1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "Ext4Crypt.h" 18 19 #include "KeyStorage.h" 20 #include "KeyUtil.h" 21 #include "Utils.h" 22 23 #include <algorithm> 24 #include <map> 25 #include <set> 26 #include <sstream> 27 #include <string> 28 #include <vector> 29 30 #include <dirent.h> 31 #include <errno.h> 32 #include <fcntl.h> 33 #include <unistd.h> 34 #include <limits.h> 35 #include <selinux/android.h> 36 #include <sys/mount.h> 37 #include <sys/stat.h> 38 #include <sys/types.h> 39 40 #include <private/android_filesystem_config.h> 41 42 #include "cryptfs.h" 43 44 #define EMULATED_USES_SELINUX 0 45 #define MANAGE_MISC_DIRS 0 46 47 #include <cutils/fs.h> 48 #include <cutils/properties.h> 49 50 #include <ext4_utils/ext4_crypt.h> 51 #include <keyutils.h> 52 53 #include <android-base/file.h> 54 #include <android-base/logging.h> 55 #include <android-base/stringprintf.h> 56 57 using android::base::StringPrintf; 58 using android::base::WriteStringToFile; 59 using android::vold::kEmptyAuthentication; 60 using android::vold::KeyBuffer; 61 62 // NOTE: keep in sync with StorageManager 63 static constexpr int FLAG_STORAGE_DE = 1 << 0; 64 static constexpr int FLAG_STORAGE_CE = 1 << 1; 65 66 namespace { 67 68 const std::string device_key_dir = std::string() + DATA_MNT_POINT + e4crypt_unencrypted_folder; 69 const std::string device_key_path = device_key_dir + "/key"; 70 const std::string device_key_temp = device_key_dir + "/temp"; 71 72 const std::string user_key_dir = std::string() + DATA_MNT_POINT + "/misc/vold/user_keys"; 73 const std::string user_key_temp = user_key_dir + "/temp"; 74 75 bool s_global_de_initialized = false; 76 77 // Some users are ephemeral, don't try to wipe their keys from disk 78 std::set<userid_t> s_ephemeral_users; 79 80 // Map user ids to key references 81 std::map<userid_t, std::string> s_de_key_raw_refs; 82 std::map<userid_t, std::string> s_ce_key_raw_refs; 83 // TODO abolish this map, per b/26948053 84 std::map<userid_t, KeyBuffer> s_ce_keys; 85 86 } 87 88 static bool e4crypt_is_emulated() { 89 return property_get_bool("persist.sys.emulate_fbe", false); 90 } 91 92 static const char* escape_null(const char* value) { 93 return (value == nullptr) ? "null" : value; 94 } 95 96 static std::string get_de_key_path(userid_t user_id) { 97 return StringPrintf("%s/de/%d", user_key_dir.c_str(), user_id); 98 } 99 100 static std::string get_ce_key_directory_path(userid_t user_id) { 101 return StringPrintf("%s/ce/%d", user_key_dir.c_str(), user_id); 102 } 103 104 // Returns the keys newest first 105 static std::vector<std::string> get_ce_key_paths(const std::string& directory_path) { 106 auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(directory_path.c_str()), closedir); 107 if (!dirp) { 108 PLOG(ERROR) << "Unable to open ce key directory: " + directory_path; 109 return std::vector<std::string>(); 110 } 111 std::vector<std::string> result; 112 for (;;) { 113 errno = 0; 114 auto const entry = readdir(dirp.get()); 115 if (!entry) { 116 if (errno) { 117 PLOG(ERROR) << "Unable to read ce key directory: " + directory_path; 118 return std::vector<std::string>(); 119 } 120 break; 121 } 122 if (entry->d_type != DT_DIR || entry->d_name[0] != 'c') { 123 LOG(DEBUG) << "Skipping non-key " << entry->d_name; 124 continue; 125 } 126 result.emplace_back(directory_path + "/" + entry->d_name); 127 } 128 std::sort(result.begin(), result.end()); 129 std::reverse(result.begin(), result.end()); 130 return result; 131 } 132 133 static std::string get_ce_key_current_path(const std::string& directory_path) { 134 return directory_path + "/current"; 135 } 136 137 static bool get_ce_key_new_path(const std::string& directory_path, 138 const std::vector<std::string>& paths, 139 std::string *ce_key_path) { 140 if (paths.empty()) { 141 *ce_key_path = get_ce_key_current_path(directory_path); 142 return true; 143 } 144 for (unsigned int i = 0; i < UINT_MAX; i++) { 145 auto const candidate = StringPrintf("%s/cx%010u", directory_path.c_str(), i); 146 if (paths[0] < candidate) { 147 *ce_key_path = candidate; 148 return true; 149 } 150 } 151 return false; 152 } 153 154 // Discard all keys but the named one; rename it to canonical name. 155 // No point in acting on errors in this; ignore them. 156 static void fixate_user_ce_key(const std::string& directory_path, const std::string &to_fix, 157 const std::vector<std::string>& paths) { 158 for (auto const other_path: paths) { 159 if (other_path != to_fix) { 160 android::vold::destroyKey(other_path); 161 } 162 } 163 auto const current_path = get_ce_key_current_path(directory_path); 164 if (to_fix != current_path) { 165 LOG(DEBUG) << "Renaming " << to_fix << " to " << current_path; 166 if (rename(to_fix.c_str(), current_path.c_str()) != 0) { 167 PLOG(WARNING) << "Unable to rename " << to_fix << " to " << current_path; 168 } 169 } 170 } 171 172 static bool read_and_fixate_user_ce_key(userid_t user_id, 173 const android::vold::KeyAuthentication& auth, 174 KeyBuffer *ce_key) { 175 auto const directory_path = get_ce_key_directory_path(user_id); 176 auto const paths = get_ce_key_paths(directory_path); 177 for (auto const ce_key_path: paths) { 178 LOG(DEBUG) << "Trying user CE key " << ce_key_path; 179 if (android::vold::retrieveKey(ce_key_path, auth, ce_key)) { 180 LOG(DEBUG) << "Successfully retrieved key"; 181 fixate_user_ce_key(directory_path, ce_key_path, paths); 182 return true; 183 } 184 } 185 LOG(ERROR) << "Failed to find working ce key for user " << user_id; 186 return false; 187 } 188 189 static bool read_and_install_user_ce_key(userid_t user_id, 190 const android::vold::KeyAuthentication& auth) { 191 if (s_ce_key_raw_refs.count(user_id) != 0) return true; 192 KeyBuffer ce_key; 193 if (!read_and_fixate_user_ce_key(user_id, auth, &ce_key)) return false; 194 std::string ce_raw_ref; 195 if (!android::vold::installKey(ce_key, &ce_raw_ref)) return false; 196 s_ce_keys[user_id] = std::move(ce_key); 197 s_ce_key_raw_refs[user_id] = ce_raw_ref; 198 LOG(DEBUG) << "Installed ce key for user " << user_id; 199 return true; 200 } 201 202 static bool prepare_dir(const std::string& dir, mode_t mode, uid_t uid, gid_t gid) { 203 LOG(DEBUG) << "Preparing: " << dir; 204 if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) { 205 PLOG(ERROR) << "Failed to prepare " << dir; 206 return false; 207 } 208 return true; 209 } 210 211 static bool destroy_dir(const std::string& dir) { 212 LOG(DEBUG) << "Destroying: " << dir; 213 if (rmdir(dir.c_str()) != 0 && errno != ENOENT) { 214 PLOG(ERROR) << "Failed to destroy " << dir; 215 return false; 216 } 217 return true; 218 } 219 220 // NB this assumes that there is only one thread listening for crypt commands, because 221 // it creates keys in a fixed location. 222 static bool create_and_install_user_keys(userid_t user_id, bool create_ephemeral) { 223 KeyBuffer de_key, ce_key; 224 if (!android::vold::randomKey(&de_key)) return false; 225 if (!android::vold::randomKey(&ce_key)) return false; 226 if (create_ephemeral) { 227 // If the key should be created as ephemeral, don't store it. 228 s_ephemeral_users.insert(user_id); 229 } else { 230 auto const directory_path = get_ce_key_directory_path(user_id); 231 if (!prepare_dir(directory_path, 0700, AID_ROOT, AID_ROOT)) return false; 232 auto const paths = get_ce_key_paths(directory_path); 233 std::string ce_key_path; 234 if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false; 235 if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, 236 kEmptyAuthentication, ce_key)) return false; 237 fixate_user_ce_key(directory_path, ce_key_path, paths); 238 // Write DE key second; once this is written, all is good. 239 if (!android::vold::storeKeyAtomically(get_de_key_path(user_id), user_key_temp, 240 kEmptyAuthentication, de_key)) return false; 241 } 242 std::string de_raw_ref; 243 if (!android::vold::installKey(de_key, &de_raw_ref)) return false; 244 s_de_key_raw_refs[user_id] = de_raw_ref; 245 std::string ce_raw_ref; 246 if (!android::vold::installKey(ce_key, &ce_raw_ref)) return false; 247 s_ce_keys[user_id] = ce_key; 248 s_ce_key_raw_refs[user_id] = ce_raw_ref; 249 LOG(DEBUG) << "Created keys for user " << user_id; 250 return true; 251 } 252 253 static bool lookup_key_ref(const std::map<userid_t, std::string>& key_map, userid_t user_id, 254 std::string* raw_ref) { 255 auto refi = key_map.find(user_id); 256 if (refi == key_map.end()) { 257 LOG(ERROR) << "Cannot find key for " << user_id; 258 return false; 259 } 260 *raw_ref = refi->second; 261 return true; 262 } 263 264 static bool ensure_policy(const std::string& raw_ref, const std::string& path) { 265 const char *contents_mode; 266 const char *filenames_mode; 267 268 cryptfs_get_file_encryption_modes(&contents_mode, &filenames_mode); 269 270 if (e4crypt_policy_ensure(path.c_str(), 271 raw_ref.data(), raw_ref.size(), 272 contents_mode, filenames_mode) != 0) { 273 LOG(ERROR) << "Failed to set policy on: " << path; 274 return false; 275 } 276 return true; 277 } 278 279 static bool is_numeric(const char* name) { 280 for (const char* p = name; *p != '\0'; p++) { 281 if (!isdigit(*p)) return false; 282 } 283 return true; 284 } 285 286 static bool load_all_de_keys() { 287 auto de_dir = user_key_dir + "/de"; 288 auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(de_dir.c_str()), closedir); 289 if (!dirp) { 290 PLOG(ERROR) << "Unable to read de key directory"; 291 return false; 292 } 293 for (;;) { 294 errno = 0; 295 auto entry = readdir(dirp.get()); 296 if (!entry) { 297 if (errno) { 298 PLOG(ERROR) << "Unable to read de key directory"; 299 return false; 300 } 301 break; 302 } 303 if (entry->d_type != DT_DIR || !is_numeric(entry->d_name)) { 304 LOG(DEBUG) << "Skipping non-de-key " << entry->d_name; 305 continue; 306 } 307 userid_t user_id = atoi(entry->d_name); 308 if (s_de_key_raw_refs.count(user_id) == 0) { 309 auto key_path = de_dir + "/" + entry->d_name; 310 KeyBuffer key; 311 if (!android::vold::retrieveKey(key_path, kEmptyAuthentication, &key)) return false; 312 std::string raw_ref; 313 if (!android::vold::installKey(key, &raw_ref)) return false; 314 s_de_key_raw_refs[user_id] = raw_ref; 315 LOG(DEBUG) << "Installed de key for user " << user_id; 316 } 317 } 318 // ext4enc:TODO: go through all DE directories, ensure that all user dirs have the 319 // correct policy set on them, and that no rogue ones exist. 320 return true; 321 } 322 323 bool e4crypt_initialize_global_de() { 324 LOG(INFO) << "e4crypt_initialize_global_de"; 325 326 if (s_global_de_initialized) { 327 LOG(INFO) << "Already initialized"; 328 return true; 329 } 330 331 const char *contents_mode; 332 const char *filenames_mode; 333 cryptfs_get_file_encryption_modes(&contents_mode, &filenames_mode); 334 std::string modestring = std::string(contents_mode) + ":" + filenames_mode; 335 336 std::string mode_filename = std::string("/data") + e4crypt_key_mode; 337 if (!android::base::WriteStringToFile(modestring, mode_filename)) { 338 PLOG(ERROR) << "Cannot save type"; 339 return false; 340 } 341 342 std::string device_key_ref; 343 if (!android::vold::retrieveAndInstallKey(true, 344 device_key_path, device_key_temp, &device_key_ref)) return false; 345 346 std::string ref_filename = std::string("/data") + e4crypt_key_ref; 347 if (!android::base::WriteStringToFile(device_key_ref, ref_filename)) { 348 PLOG(ERROR) << "Cannot save key reference to:" << ref_filename; 349 return false; 350 } 351 LOG(INFO) << "Wrote system DE key reference to:" << ref_filename; 352 353 s_global_de_initialized = true; 354 return true; 355 } 356 357 bool e4crypt_init_user0() { 358 LOG(DEBUG) << "e4crypt_init_user0"; 359 if (e4crypt_is_native()) { 360 if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return false; 361 if (!prepare_dir(user_key_dir + "/ce", 0700, AID_ROOT, AID_ROOT)) return false; 362 if (!prepare_dir(user_key_dir + "/de", 0700, AID_ROOT, AID_ROOT)) return false; 363 if (!android::vold::pathExists(get_de_key_path(0))) { 364 if (!create_and_install_user_keys(0, false)) return false; 365 } 366 // TODO: switch to loading only DE_0 here once framework makes 367 // explicit calls to install DE keys for secondary users 368 if (!load_all_de_keys()) return false; 369 } 370 // We can only safely prepare DE storage here, since CE keys are probably 371 // entangled with user credentials. The framework will always prepare CE 372 // storage once CE keys are installed. 373 if (!e4crypt_prepare_user_storage(nullptr, 0, 0, FLAG_STORAGE_DE)) { 374 LOG(ERROR) << "Failed to prepare user 0 storage"; 375 return false; 376 } 377 378 // If this is a non-FBE device that recently left an emulated mode, 379 // restore user data directories to known-good state. 380 if (!e4crypt_is_native() && !e4crypt_is_emulated()) { 381 e4crypt_unlock_user_key(0, 0, "!", "!"); 382 } 383 384 return true; 385 } 386 387 bool e4crypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral) { 388 LOG(DEBUG) << "e4crypt_vold_create_user_key for " << user_id << " serial " << serial; 389 if (!e4crypt_is_native()) { 390 return true; 391 } 392 // FIXME test for existence of key that is not loaded yet 393 if (s_ce_key_raw_refs.count(user_id) != 0) { 394 LOG(ERROR) << "Already exists, can't e4crypt_vold_create_user_key for " << user_id 395 << " serial " << serial; 396 // FIXME should we fail the command? 397 return true; 398 } 399 if (!create_and_install_user_keys(user_id, ephemeral)) { 400 return false; 401 } 402 return true; 403 } 404 405 static void drop_caches() { 406 // Clean any dirty pages (otherwise they won't be dropped). 407 sync(); 408 // Drop inode and page caches. 409 if (!WriteStringToFile("3", "/proc/sys/vm/drop_caches")) { 410 PLOG(ERROR) << "Failed to drop caches during key eviction"; 411 } 412 } 413 414 static bool evict_ce_key(userid_t user_id) { 415 s_ce_keys.erase(user_id); 416 bool success = true; 417 std::string raw_ref; 418 // If we haven't loaded the CE key, no need to evict it. 419 if (lookup_key_ref(s_ce_key_raw_refs, user_id, &raw_ref)) { 420 success &= android::vold::evictKey(raw_ref); 421 drop_caches(); 422 } 423 s_ce_key_raw_refs.erase(user_id); 424 return success; 425 } 426 427 bool e4crypt_destroy_user_key(userid_t user_id) { 428 LOG(DEBUG) << "e4crypt_destroy_user_key(" << user_id << ")"; 429 if (!e4crypt_is_native()) { 430 return true; 431 } 432 bool success = true; 433 std::string raw_ref; 434 success &= evict_ce_key(user_id); 435 success &= lookup_key_ref(s_de_key_raw_refs, user_id, &raw_ref) 436 && android::vold::evictKey(raw_ref); 437 s_de_key_raw_refs.erase(user_id); 438 auto it = s_ephemeral_users.find(user_id); 439 if (it != s_ephemeral_users.end()) { 440 s_ephemeral_users.erase(it); 441 } else { 442 for (auto const path: get_ce_key_paths(get_ce_key_directory_path(user_id))) { 443 success &= android::vold::destroyKey(path); 444 } 445 auto de_key_path = get_de_key_path(user_id); 446 if (android::vold::pathExists(de_key_path)) { 447 success &= android::vold::destroyKey(de_key_path); 448 } else { 449 LOG(INFO) << "Not present so not erasing: " << de_key_path; 450 } 451 } 452 return success; 453 } 454 455 static bool emulated_lock(const std::string& path) { 456 if (chmod(path.c_str(), 0000) != 0) { 457 PLOG(ERROR) << "Failed to chmod " << path; 458 return false; 459 } 460 #if EMULATED_USES_SELINUX 461 if (setfilecon(path.c_str(), "u:object_r:storage_stub_file:s0") != 0) { 462 PLOG(WARNING) << "Failed to setfilecon " << path; 463 return false; 464 } 465 #endif 466 return true; 467 } 468 469 static bool emulated_unlock(const std::string& path, mode_t mode) { 470 if (chmod(path.c_str(), mode) != 0) { 471 PLOG(ERROR) << "Failed to chmod " << path; 472 // FIXME temporary workaround for b/26713622 473 if (e4crypt_is_emulated()) return false; 474 } 475 #if EMULATED_USES_SELINUX 476 if (selinux_android_restorecon(path.c_str(), SELINUX_ANDROID_RESTORECON_FORCE) != 0) { 477 PLOG(WARNING) << "Failed to restorecon " << path; 478 // FIXME temporary workaround for b/26713622 479 if (e4crypt_is_emulated()) return false; 480 } 481 #endif 482 return true; 483 } 484 485 static bool parse_hex(const char* hex, std::string* result) { 486 if (strcmp("!", hex) == 0) { 487 *result = ""; 488 return true; 489 } 490 if (android::vold::HexToStr(hex, *result) != 0) { 491 LOG(ERROR) << "Invalid FBE hex string"; // Don't log the string for security reasons 492 return false; 493 } 494 return true; 495 } 496 497 bool e4crypt_add_user_key_auth(userid_t user_id, int serial, const char* token_hex, 498 const char* secret_hex) { 499 LOG(DEBUG) << "e4crypt_add_user_key_auth " << user_id << " serial=" << serial 500 << " token_present=" << (strcmp(token_hex, "!") != 0); 501 if (!e4crypt_is_native()) return true; 502 if (s_ephemeral_users.count(user_id) != 0) return true; 503 std::string token, secret; 504 if (!parse_hex(token_hex, &token)) return false; 505 if (!parse_hex(secret_hex, &secret)) return false; 506 auto auth = secret.empty() ? kEmptyAuthentication 507 : android::vold::KeyAuthentication(token, secret); 508 auto it = s_ce_keys.find(user_id); 509 if (it == s_ce_keys.end()) { 510 LOG(ERROR) << "Key not loaded into memory, can't change for user " << user_id; 511 return false; 512 } 513 const auto &ce_key = it->second; 514 auto const directory_path = get_ce_key_directory_path(user_id); 515 auto const paths = get_ce_key_paths(directory_path); 516 std::string ce_key_path; 517 if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false; 518 if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, auth, ce_key)) return false; 519 return true; 520 } 521 522 bool e4crypt_fixate_newest_user_key_auth(userid_t user_id) { 523 LOG(DEBUG) << "e4crypt_fixate_newest_user_key_auth " << user_id; 524 if (!e4crypt_is_native()) return true; 525 if (s_ephemeral_users.count(user_id) != 0) return true; 526 auto const directory_path = get_ce_key_directory_path(user_id); 527 auto const paths = get_ce_key_paths(directory_path); 528 if (paths.empty()) { 529 LOG(ERROR) << "No ce keys present, cannot fixate for user " << user_id; 530 return false; 531 } 532 fixate_user_ce_key(directory_path, paths[0], paths); 533 return true; 534 } 535 536 // TODO: rename to 'install' for consistency, and take flags to know which keys to install 537 bool e4crypt_unlock_user_key(userid_t user_id, int serial, const char* token_hex, 538 const char* secret_hex) { 539 LOG(DEBUG) << "e4crypt_unlock_user_key " << user_id << " serial=" << serial 540 << " token_present=" << (strcmp(token_hex, "!") != 0); 541 if (e4crypt_is_native()) { 542 if (s_ce_key_raw_refs.count(user_id) != 0) { 543 LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id; 544 return true; 545 } 546 std::string token, secret; 547 if (!parse_hex(token_hex, &token)) return false; 548 if (!parse_hex(secret_hex, &secret)) return false; 549 android::vold::KeyAuthentication auth(token, secret); 550 if (!read_and_install_user_ce_key(user_id, auth)) { 551 LOG(ERROR) << "Couldn't read key for " << user_id; 552 return false; 553 } 554 } else { 555 // When in emulation mode, we just use chmod. However, we also 556 // unlock directories when not in emulation mode, to bring devices 557 // back into a known-good state. 558 if (!emulated_unlock(android::vold::BuildDataSystemCePath(user_id), 0771) || 559 !emulated_unlock(android::vold::BuildDataMiscCePath(user_id), 01771) || 560 !emulated_unlock(android::vold::BuildDataMediaCePath(nullptr, user_id), 0770) || 561 !emulated_unlock(android::vold::BuildDataUserCePath(nullptr, user_id), 0771)) { 562 LOG(ERROR) << "Failed to unlock user " << user_id; 563 return false; 564 } 565 } 566 return true; 567 } 568 569 // TODO: rename to 'evict' for consistency 570 bool e4crypt_lock_user_key(userid_t user_id) { 571 LOG(DEBUG) << "e4crypt_lock_user_key " << user_id; 572 if (e4crypt_is_native()) { 573 return evict_ce_key(user_id); 574 } else if (e4crypt_is_emulated()) { 575 // When in emulation mode, we just use chmod 576 if (!emulated_lock(android::vold::BuildDataSystemCePath(user_id)) || 577 !emulated_lock(android::vold::BuildDataMiscCePath(user_id)) || 578 !emulated_lock(android::vold::BuildDataMediaCePath(nullptr, user_id)) || 579 !emulated_lock(android::vold::BuildDataUserCePath(nullptr, user_id))) { 580 LOG(ERROR) << "Failed to lock user " << user_id; 581 return false; 582 } 583 } 584 585 return true; 586 } 587 588 bool e4crypt_prepare_user_storage(const char* volume_uuid, userid_t user_id, int serial, 589 int flags) { 590 LOG(DEBUG) << "e4crypt_prepare_user_storage for volume " << escape_null(volume_uuid) 591 << ", user " << user_id << ", serial " << serial << ", flags " << flags; 592 593 if (flags & FLAG_STORAGE_DE) { 594 // DE_sys key 595 auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id); 596 auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id); 597 auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id); 598 599 // DE_n key 600 auto system_de_path = android::vold::BuildDataSystemDePath(user_id); 601 auto misc_de_path = android::vold::BuildDataMiscDePath(user_id); 602 auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id); 603 604 if (!prepare_dir(system_legacy_path, 0700, AID_SYSTEM, AID_SYSTEM)) return false; 605 #if MANAGE_MISC_DIRS 606 if (!prepare_dir(misc_legacy_path, 0750, multiuser_get_uid(user_id, AID_SYSTEM), 607 multiuser_get_uid(user_id, AID_EVERYBODY))) return false; 608 #endif 609 if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false; 610 611 if (!prepare_dir(system_de_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false; 612 if (!prepare_dir(misc_de_path, 01771, AID_SYSTEM, AID_MISC)) return false; 613 if (!prepare_dir(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false; 614 615 if (e4crypt_is_native()) { 616 std::string de_raw_ref; 617 if (!lookup_key_ref(s_de_key_raw_refs, user_id, &de_raw_ref)) return false; 618 if (!ensure_policy(de_raw_ref, system_de_path)) return false; 619 if (!ensure_policy(de_raw_ref, misc_de_path)) return false; 620 if (!ensure_policy(de_raw_ref, user_de_path)) return false; 621 } 622 } 623 624 if (flags & FLAG_STORAGE_CE) { 625 // CE_n key 626 auto system_ce_path = android::vold::BuildDataSystemCePath(user_id); 627 auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id); 628 auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id); 629 auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id); 630 631 if (!prepare_dir(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false; 632 if (!prepare_dir(misc_ce_path, 01771, AID_SYSTEM, AID_MISC)) return false; 633 if (!prepare_dir(media_ce_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false; 634 if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false; 635 636 if (e4crypt_is_native()) { 637 std::string ce_raw_ref; 638 if (!lookup_key_ref(s_ce_key_raw_refs, user_id, &ce_raw_ref)) return false; 639 if (!ensure_policy(ce_raw_ref, system_ce_path)) return false; 640 if (!ensure_policy(ce_raw_ref, misc_ce_path)) return false; 641 if (!ensure_policy(ce_raw_ref, media_ce_path)) return false; 642 if (!ensure_policy(ce_raw_ref, user_ce_path)) return false; 643 644 // Now that credentials have been installed, we can run restorecon 645 // over these paths 646 // NOTE: these paths need to be kept in sync with libselinux 647 android::vold::RestoreconRecursive(system_ce_path); 648 android::vold::RestoreconRecursive(misc_ce_path); 649 } 650 } 651 652 return true; 653 } 654 655 bool e4crypt_destroy_user_storage(const char* volume_uuid, userid_t user_id, int flags) { 656 LOG(DEBUG) << "e4crypt_destroy_user_storage for volume " << escape_null(volume_uuid) 657 << ", user " << user_id << ", flags " << flags; 658 bool res = true; 659 660 if (flags & FLAG_STORAGE_DE) { 661 // DE_sys key 662 auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id); 663 auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id); 664 auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id); 665 666 // DE_n key 667 auto system_de_path = android::vold::BuildDataSystemDePath(user_id); 668 auto misc_de_path = android::vold::BuildDataMiscDePath(user_id); 669 auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id); 670 671 if (volume_uuid == nullptr) { 672 res &= destroy_dir(system_legacy_path); 673 #if MANAGE_MISC_DIRS 674 res &= destroy_dir(misc_legacy_path); 675 #endif 676 res &= destroy_dir(profiles_de_path); 677 res &= destroy_dir(system_de_path); 678 res &= destroy_dir(misc_de_path); 679 } 680 res &= destroy_dir(user_de_path); 681 } 682 683 if (flags & FLAG_STORAGE_CE) { 684 // CE_n key 685 auto system_ce_path = android::vold::BuildDataSystemCePath(user_id); 686 auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id); 687 auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id); 688 auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id); 689 690 if (volume_uuid == nullptr) { 691 res &= destroy_dir(system_ce_path); 692 res &= destroy_dir(misc_ce_path); 693 } 694 res &= destroy_dir(media_ce_path); 695 res &= destroy_dir(user_ce_path); 696 } 697 698 return res; 699 } 700 701 bool e4crypt_secdiscard(const char* path) { 702 return android::vold::runSecdiscardSingle(std::string(path)); 703 } 704