Merge "Add and use prepare_dir_with_policy() helper function" am: 14ac67efab
am: b0aec67fab
Original change: https://android-review.googlesource.com/c/platform/system/vold/+/2097184 Change-Id: I090927709e10f6eb6ade3192ab76ce73e29ec10e Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
814dbfb77c
1 changed files with 92 additions and 64 deletions
156
FsCrypt.cpp
156
FsCrypt.cpp
|
@ -314,6 +314,9 @@ static bool read_and_install_user_ce_key(userid_t user_id,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare a directory without assigning it an encryption policy. The directory
|
||||||
|
// will inherit the encryption policy of its parent directory, or will be
|
||||||
|
// unencrypted if the parent directory is unencrypted.
|
||||||
static bool prepare_dir(const std::string& dir, mode_t mode, uid_t uid, gid_t gid) {
|
static bool prepare_dir(const std::string& dir, mode_t mode, uid_t uid, gid_t gid) {
|
||||||
LOG(DEBUG) << "Preparing: " << dir;
|
LOG(DEBUG) << "Preparing: " << dir;
|
||||||
if (android::vold::PrepareDir(dir, mode, uid, gid, 0) != 0) {
|
if (android::vold::PrepareDir(dir, mode, uid, gid, 0) != 0) {
|
||||||
|
@ -323,6 +326,14 @@ static bool prepare_dir(const std::string& dir, mode_t mode, uid_t uid, gid_t gi
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare a directory and assign it the given encryption policy.
|
||||||
|
static bool prepare_dir_with_policy(const std::string& dir, mode_t mode, uid_t uid, gid_t gid,
|
||||||
|
const EncryptionPolicy& policy) {
|
||||||
|
if (!prepare_dir(dir, mode, uid, gid)) return false;
|
||||||
|
if (fscrypt_is_native() && !EnsurePolicy(policy, dir)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool destroy_dir(const std::string& dir) {
|
static bool destroy_dir(const std::string& dir) {
|
||||||
LOG(DEBUG) << "Destroying: " << dir;
|
LOG(DEBUG) << "Destroying: " << dir;
|
||||||
if (rmdir(dir.c_str()) != 0 && errno != ENOENT) {
|
if (rmdir(dir.c_str()) != 0 && errno != ENOENT) {
|
||||||
|
@ -372,7 +383,6 @@ static bool lookup_policy(const std::map<userid_t, EncryptionPolicy>& key_map, u
|
||||||
EncryptionPolicy* policy) {
|
EncryptionPolicy* policy) {
|
||||||
auto refi = key_map.find(user_id);
|
auto refi = key_map.find(user_id);
|
||||||
if (refi == key_map.end()) {
|
if (refi == key_map.end()) {
|
||||||
LOG(DEBUG) << "Cannot find key for " << user_id;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*policy = refi->second;
|
*policy = refi->second;
|
||||||
|
@ -479,18 +489,29 @@ bool fscrypt_initialize_systemwide_keys() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool prepare_special_dirs() {
|
static bool prepare_special_dirs() {
|
||||||
// Create /data/user/0 and its bind-mount alias /data/data. This *should*
|
// Ensure that /data/data and its "alias" /data/user/0 exist, and create the
|
||||||
// happen in fscrypt_prepare_user_storage(). However, it actually must be
|
// bind mount of /data/data onto /data/user/0. This *should* happen in
|
||||||
// done early, before the rest of user 0's CE storage is prepared. This is
|
// fscrypt_prepare_user_storage(). However, it actually must be done early,
|
||||||
// because zygote may need to set up app data isolation before then, which
|
// before the rest of user 0's CE storage is prepared. This is because
|
||||||
// requires mounting a tmpfs over /data/data to ensure it remains hidden.
|
// zygote may need to set up app data isolation before then, which requires
|
||||||
// This issue arises due to /data/data being in the top-level directory.
|
// mounting a tmpfs over /data/data to ensure it remains hidden. This issue
|
||||||
//
|
// arises due to /data/data being in the top-level directory.
|
||||||
|
|
||||||
// /data/user/0 used to be a symlink to /data/data, so we must first delete
|
// /data/user/0 used to be a symlink to /data/data, so we must first delete
|
||||||
// the old symlink if present.
|
// the old symlink if present.
|
||||||
if (android::vold::IsSymlink(data_user_0_dir) && android::vold::Unlink(data_user_0_dir) != 0)
|
if (android::vold::IsSymlink(data_user_0_dir) && android::vold::Unlink(data_user_0_dir) != 0)
|
||||||
return false;
|
return false;
|
||||||
if (!prepare_dir(data_data_dir, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
|
// On first boot, we'll be creating /data/data for the first time, and user
|
||||||
|
// 0's CE key will be installed already since it was just created. Take the
|
||||||
|
// opportunity to also set the encryption policy of /data/data right away.
|
||||||
|
EncryptionPolicy ce_policy;
|
||||||
|
if (lookup_policy(s_ce_policies, 0, &ce_policy)) {
|
||||||
|
if (!prepare_dir_with_policy(data_data_dir, 0771, AID_SYSTEM, AID_SYSTEM, ce_policy))
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (!prepare_dir(data_data_dir, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
|
||||||
|
// EnsurePolicy() will have to happen later, in fscrypt_prepare_user_storage().
|
||||||
|
}
|
||||||
if (!prepare_dir(data_user_0_dir, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
|
if (!prepare_dir(data_user_0_dir, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
|
||||||
if (android::vold::BindMount(data_data_dir, data_user_0_dir) != 0) return false;
|
if (android::vold::BindMount(data_data_dir, data_user_0_dir) != 0) return false;
|
||||||
|
|
||||||
|
@ -503,9 +524,13 @@ static bool prepare_special_dirs() {
|
||||||
//
|
//
|
||||||
// We must tolerate /data/media/obb being unencrypted if it already exists
|
// We must tolerate /data/media/obb being unencrypted if it already exists
|
||||||
// on-disk, since it used to be unencrypted (b/64566063).
|
// on-disk, since it used to be unencrypted (b/64566063).
|
||||||
bool encrypt_obb = !android::vold::pathExists(media_obb_dir) && fscrypt_is_native();
|
if (android::vold::pathExists(media_obb_dir)) {
|
||||||
if (!prepare_dir(media_obb_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
|
if (!prepare_dir(media_obb_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
|
||||||
if (encrypt_obb && !EnsurePolicy(s_device_policy, media_obb_dir)) return false;
|
} else {
|
||||||
|
if (!prepare_dir_with_policy(media_obb_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW,
|
||||||
|
s_device_policy))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,25 +539,23 @@ bool fscrypt_init_user0_done;
|
||||||
bool fscrypt_init_user0() {
|
bool fscrypt_init_user0() {
|
||||||
LOG(DEBUG) << "fscrypt_init_user0";
|
LOG(DEBUG) << "fscrypt_init_user0";
|
||||||
|
|
||||||
if (!prepare_special_dirs()) return false;
|
|
||||||
|
|
||||||
if (fscrypt_is_native()) {
|
if (fscrypt_is_native()) {
|
||||||
if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return false;
|
if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return false;
|
||||||
if (!prepare_dir(user_key_dir + "/ce", 0700, AID_ROOT, AID_ROOT)) return false;
|
if (!prepare_dir(user_key_dir + "/ce", 0700, AID_ROOT, AID_ROOT)) return false;
|
||||||
if (!prepare_dir(user_key_dir + "/de", 0700, AID_ROOT, AID_ROOT)) return false;
|
if (!prepare_dir(user_key_dir + "/de", 0700, AID_ROOT, AID_ROOT)) return false;
|
||||||
if (!android::vold::pathExists(get_de_key_path(0))) {
|
if (!android::vold::pathExists(get_de_key_path(0))) {
|
||||||
if (!create_and_install_user_keys(0, false)) return false;
|
if (!create_and_install_user_keys(0, false)) return false;
|
||||||
// Since /data/user/0 was created already, and directory creation
|
|
||||||
// and encryption should always happen together, encrypt
|
|
||||||
// /data/user/0 right away without waiting for the request to
|
|
||||||
// prepare user 0's CE storage.
|
|
||||||
if (!EnsurePolicy(s_ce_policies[0], data_user_0_dir)) return false;
|
|
||||||
}
|
}
|
||||||
// TODO: switch to loading only DE_0 here once framework makes
|
// TODO: switch to loading only DE_0 here once framework makes
|
||||||
// explicit calls to install DE keys for secondary users
|
// explicit calls to install DE keys for secondary users
|
||||||
if (!load_all_de_keys()) return false;
|
if (!load_all_de_keys()) return false;
|
||||||
}
|
}
|
||||||
// We only prepare DE storage here, since user 0's CE key won't be installed
|
|
||||||
|
// Now that user 0's CE key has been created, we can prepare /data/data.
|
||||||
|
if (!prepare_special_dirs()) return false;
|
||||||
|
|
||||||
|
// With the exception of what is done by prepare_special_dirs() above, we
|
||||||
|
// only prepare DE storage here, since user 0's CE key won't be installed
|
||||||
// yet unless it was just created. The framework will prepare the user's CE
|
// yet unless it was just created. The framework will prepare the user's CE
|
||||||
// storage later, once their CE key is installed.
|
// storage later, once their CE key is installed.
|
||||||
if (!fscrypt_prepare_user_storage("", 0, 0, android::os::IVold::STORAGE_FLAG_DE)) {
|
if (!fscrypt_prepare_user_storage("", 0, 0, android::os::IVold::STORAGE_FLAG_DE)) {
|
||||||
|
@ -883,11 +906,26 @@ bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_
|
||||||
auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
|
auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
|
||||||
|
|
||||||
// DE_n key
|
// DE_n key
|
||||||
|
EncryptionPolicy de_policy;
|
||||||
auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
|
auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
|
||||||
auto misc_de_path = android::vold::BuildDataMiscDePath(volume_uuid, user_id);
|
auto misc_de_path = android::vold::BuildDataMiscDePath(volume_uuid, user_id);
|
||||||
auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
|
auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
|
||||||
auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
|
auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
|
||||||
|
|
||||||
|
if (fscrypt_is_native()) {
|
||||||
|
if (volume_uuid.empty()) {
|
||||||
|
if (!lookup_policy(s_de_policies, user_id, &de_policy)) {
|
||||||
|
LOG(ERROR) << "Cannot find DE policy for user " << user_id;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto misc_de_empty_volume_path = android::vold::BuildDataMiscDePath("", user_id);
|
||||||
|
if (!read_or_create_volkey(misc_de_empty_volume_path, volume_uuid, &de_policy)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (volume_uuid.empty()) {
|
if (volume_uuid.empty()) {
|
||||||
if (!prepare_dir(system_legacy_path, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
|
if (!prepare_dir(system_legacy_path, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
|
||||||
#if MANAGE_MISC_DIRS
|
#if MANAGE_MISC_DIRS
|
||||||
|
@ -897,43 +935,49 @@ bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_
|
||||||
#endif
|
#endif
|
||||||
if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
|
if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
|
||||||
|
|
||||||
if (!prepare_dir(system_de_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
|
if (!prepare_dir_with_policy(system_de_path, 0770, AID_SYSTEM, AID_SYSTEM, de_policy))
|
||||||
if (!prepare_dir(vendor_de_path, 0771, AID_ROOT, AID_ROOT)) return false;
|
return false;
|
||||||
|
if (!prepare_dir_with_policy(vendor_de_path, 0771, AID_ROOT, AID_ROOT, de_policy))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!prepare_dir(misc_de_path, 01771, AID_SYSTEM, AID_MISC)) return false;
|
if (!prepare_dir_with_policy(misc_de_path, 01771, AID_SYSTEM, AID_MISC, de_policy))
|
||||||
if (!prepare_dir(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
|
return false;
|
||||||
|
if (!prepare_dir_with_policy(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM, de_policy))
|
||||||
if (fscrypt_is_native()) {
|
return false;
|
||||||
EncryptionPolicy de_policy;
|
|
||||||
if (volume_uuid.empty()) {
|
|
||||||
if (!lookup_policy(s_de_policies, user_id, &de_policy)) return false;
|
|
||||||
if (!EnsurePolicy(de_policy, system_de_path)) return false;
|
|
||||||
if (!EnsurePolicy(de_policy, vendor_de_path)) return false;
|
|
||||||
} else {
|
|
||||||
auto misc_de_empty_volume_path = android::vold::BuildDataMiscDePath("", user_id);
|
|
||||||
if (!read_or_create_volkey(misc_de_empty_volume_path, volume_uuid, &de_policy)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!EnsurePolicy(de_policy, misc_de_path)) return false;
|
|
||||||
if (!EnsurePolicy(de_policy, user_de_path)) return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & android::os::IVold::STORAGE_FLAG_CE) {
|
if (flags & android::os::IVold::STORAGE_FLAG_CE) {
|
||||||
// CE_n key
|
// CE_n key
|
||||||
|
EncryptionPolicy ce_policy;
|
||||||
auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
|
auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
|
||||||
auto misc_ce_path = android::vold::BuildDataMiscCePath(volume_uuid, user_id);
|
auto misc_ce_path = android::vold::BuildDataMiscCePath(volume_uuid, user_id);
|
||||||
auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
|
auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
|
||||||
auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
|
auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
|
||||||
auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
|
auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
|
||||||
|
|
||||||
if (volume_uuid.empty()) {
|
if (fscrypt_is_native()) {
|
||||||
if (!prepare_dir(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
|
if (volume_uuid.empty()) {
|
||||||
if (!prepare_dir(vendor_ce_path, 0771, AID_ROOT, AID_ROOT)) return false;
|
if (!lookup_policy(s_ce_policies, user_id, &ce_policy)) {
|
||||||
|
LOG(ERROR) << "Cannot find CE policy for user " << user_id;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto misc_ce_empty_volume_path = android::vold::BuildDataMiscCePath("", user_id);
|
||||||
|
if (!read_or_create_volkey(misc_ce_empty_volume_path, volume_uuid, &ce_policy)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!prepare_dir(media_ce_path, 02770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
|
|
||||||
|
if (volume_uuid.empty()) {
|
||||||
|
if (!prepare_dir_with_policy(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM, ce_policy))
|
||||||
|
return false;
|
||||||
|
if (!prepare_dir_with_policy(vendor_ce_path, 0771, AID_ROOT, AID_ROOT, ce_policy))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!prepare_dir_with_policy(media_ce_path, 02770, AID_MEDIA_RW, AID_MEDIA_RW, ce_policy))
|
||||||
|
return false;
|
||||||
// On devices without sdcardfs (kernel 5.4+), the path permissions aren't fixed
|
// On devices without sdcardfs (kernel 5.4+), the path permissions aren't fixed
|
||||||
// up automatically; therefore, use a default ACL, to ensure apps with MEDIA_RW
|
// up automatically; therefore, use a default ACL, to ensure apps with MEDIA_RW
|
||||||
// can keep reading external storage; in particular, this allows app cloning
|
// can keep reading external storage; in particular, this allows app cloning
|
||||||
|
@ -942,26 +986,10 @@ bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_
|
||||||
if (ret != android::OK) {
|
if (ret != android::OK) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!prepare_dir_with_policy(misc_ce_path, 01771, AID_SYSTEM, AID_MISC, ce_policy))
|
||||||
if (!prepare_dir(misc_ce_path, 01771, AID_SYSTEM, AID_MISC)) return false;
|
return false;
|
||||||
if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
|
if (!prepare_dir_with_policy(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM, ce_policy))
|
||||||
|
return false;
|
||||||
if (fscrypt_is_native()) {
|
|
||||||
EncryptionPolicy ce_policy;
|
|
||||||
if (volume_uuid.empty()) {
|
|
||||||
if (!lookup_policy(s_ce_policies, user_id, &ce_policy)) return false;
|
|
||||||
if (!EnsurePolicy(ce_policy, system_ce_path)) return false;
|
|
||||||
if (!EnsurePolicy(ce_policy, vendor_ce_path)) return false;
|
|
||||||
} else {
|
|
||||||
auto misc_ce_empty_volume_path = android::vold::BuildDataMiscCePath("", user_id);
|
|
||||||
if (!read_or_create_volkey(misc_ce_empty_volume_path, volume_uuid, &ce_policy)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!EnsurePolicy(ce_policy, media_ce_path)) return false;
|
|
||||||
if (!EnsurePolicy(ce_policy, misc_ce_path)) return false;
|
|
||||||
if (!EnsurePolicy(ce_policy, user_ce_path)) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (volume_uuid.empty()) {
|
if (volume_uuid.empty()) {
|
||||||
// Now that credentials have been installed, we can run restorecon
|
// Now that credentials have been installed, we can run restorecon
|
||||||
|
|
Loading…
Reference in a new issue