Consistent creation/destruction of user data.
Preparing and destroying users currently needs to be split across installd, system_server, and vold, since no single party has all the required SELinux permissions. Bug: 27896918, 25861755 Change-Id: Ieec14ccacfc7a3a5ab00df47ace7318feb900c38
This commit is contained in:
parent
cbedcc30b3
commit
be70c9ae22
5 changed files with 105 additions and 27 deletions
|
@ -405,6 +405,11 @@ int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,
|
|||
return sendGenericOkFailOnBool(cli, e4crypt_prepare_user_storage(
|
||||
parseNull(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5])));
|
||||
|
||||
} else if (subcommand == "destroy_user_storage") {
|
||||
if (!check_argc(cli, subcommand, argc, 5, "<uuid> <user> <flags>")) return 0;
|
||||
return sendGenericOkFailOnBool(cli,
|
||||
e4crypt_destroy_user_storage(parseNull(argv[2]), atoi(argv[3]), atoi(argv[4])));
|
||||
|
||||
} else {
|
||||
dumpArgs(argc, argv, -1);
|
||||
cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown cryptfs subcommand", false);
|
||||
|
|
106
Ext4Crypt.cpp
106
Ext4Crypt.cpp
|
@ -43,6 +43,7 @@
|
|||
#include "key_control.h"
|
||||
|
||||
#define EMULATED_USES_SELINUX 0
|
||||
#define MANAGE_MISC_DIRS 0
|
||||
|
||||
#include <cutils/fs.h>
|
||||
|
||||
|
@ -209,6 +210,15 @@ static bool prepare_dir(const std::string& dir, mode_t mode, uid_t uid, gid_t gi
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool destroy_dir(const std::string& dir) {
|
||||
LOG(DEBUG) << "Destroying: " << dir;
|
||||
if (rmdir(dir.c_str()) != 0 && errno != ENOENT) {
|
||||
PLOG(ERROR) << "Failed to destroy " << dir;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool random_key(std::string* key) {
|
||||
if (android::vold::ReadRandomBytes(EXT4_AES_256_XTS_KEY_SIZE, *key) != 0) {
|
||||
// TODO status_t plays badly with PLOG, fix it.
|
||||
|
@ -558,8 +568,8 @@ bool e4crypt_unlock_user_key(userid_t user_id, int serial, const char* token_hex
|
|||
// back into a known-good state.
|
||||
if (!emulated_unlock(android::vold::BuildDataSystemCePath(user_id), 0771) ||
|
||||
!emulated_unlock(android::vold::BuildDataMiscCePath(user_id), 01771) ||
|
||||
!emulated_unlock(android::vold::BuildDataMediaPath(nullptr, user_id), 0770) ||
|
||||
!emulated_unlock(android::vold::BuildDataUserPath(nullptr, user_id), 0771)) {
|
||||
!emulated_unlock(android::vold::BuildDataMediaCePath(nullptr, user_id), 0770) ||
|
||||
!emulated_unlock(android::vold::BuildDataUserCePath(nullptr, user_id), 0771)) {
|
||||
LOG(ERROR) << "Failed to unlock user " << user_id;
|
||||
return false;
|
||||
}
|
||||
|
@ -575,8 +585,8 @@ bool e4crypt_lock_user_key(userid_t user_id) {
|
|||
// When in emulation mode, we just use chmod
|
||||
if (!emulated_lock(android::vold::BuildDataSystemCePath(user_id)) ||
|
||||
!emulated_lock(android::vold::BuildDataMiscCePath(user_id)) ||
|
||||
!emulated_lock(android::vold::BuildDataMediaPath(nullptr, user_id)) ||
|
||||
!emulated_lock(android::vold::BuildDataUserPath(nullptr, user_id))) {
|
||||
!emulated_lock(android::vold::BuildDataMediaCePath(nullptr, user_id)) ||
|
||||
!emulated_lock(android::vold::BuildDataUserCePath(nullptr, user_id))) {
|
||||
LOG(ERROR) << "Failed to lock user " << user_id;
|
||||
return false;
|
||||
}
|
||||
|
@ -591,49 +601,53 @@ bool e4crypt_prepare_user_storage(const char* volume_uuid, userid_t user_id, int
|
|||
<< ", user " << user_id << ", serial " << serial << ", flags " << flags;
|
||||
|
||||
if (flags & FLAG_STORAGE_DE) {
|
||||
// DE_sys key
|
||||
auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id);
|
||||
auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id);
|
||||
auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
|
||||
auto foreign_de_path = android::vold::BuildDataProfilesForeignDexDePath(user_id);
|
||||
|
||||
// DE_n key
|
||||
auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
|
||||
auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
|
||||
auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
|
||||
|
||||
if (!prepare_dir(system_legacy_path, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
|
||||
#if MANAGE_MISC_DIRS
|
||||
if (!prepare_dir(misc_legacy_path, 0750, multiuser_get_uid(user_id, AID_SYSTEM),
|
||||
multiuser_get_uid(user_id, AID_EVERYBODY))) return false;
|
||||
#endif
|
||||
if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
|
||||
if (!prepare_dir(foreign_de_path, 0773, AID_SYSTEM, AID_SYSTEM)) return false;
|
||||
|
||||
if (!prepare_dir(system_de_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
|
||||
if (!prepare_dir(misc_de_path, 01771, AID_SYSTEM, AID_MISC)) return false;
|
||||
if (!prepare_dir(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
|
||||
|
||||
if (volume_uuid == nullptr) {
|
||||
// Prepare profile directories only for the internal storage.
|
||||
// For now, we do not store profiles on the adopted storage.
|
||||
auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
|
||||
auto foreign_dex_profiles_de_path =
|
||||
android::vold::BuildDataProfilesForeignDexDePath(user_id);
|
||||
if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
|
||||
if (!prepare_dir(foreign_dex_profiles_de_path, 0773, AID_SYSTEM, AID_SYSTEM)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (e4crypt_is_native()) {
|
||||
// For now, FBE is only supported on internal storage
|
||||
if (e4crypt_is_native() && volume_uuid == nullptr) {
|
||||
std::string de_raw_ref;
|
||||
if (!lookup_key_ref(s_de_key_raw_refs, user_id, &de_raw_ref)) return false;
|
||||
if (!ensure_policy(de_raw_ref, system_de_path)) return false;
|
||||
if (!ensure_policy(de_raw_ref, misc_de_path)) return false;
|
||||
if (!ensure_policy(de_raw_ref, user_de_path)) return false;
|
||||
// No need to set the policy for profiles_de_path. The parent directory (/data/misc)
|
||||
// already has a DE_sys policy set.
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FLAG_STORAGE_CE) {
|
||||
// CE_n key
|
||||
auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
|
||||
auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
|
||||
auto media_ce_path = android::vold::BuildDataMediaPath(volume_uuid, user_id);
|
||||
auto user_ce_path = android::vold::BuildDataUserPath(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);
|
||||
|
||||
if (!prepare_dir(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
|
||||
if (!prepare_dir(misc_ce_path, 01771, AID_SYSTEM, AID_MISC)) return false;
|
||||
if (!prepare_dir(media_ce_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
|
||||
if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
|
||||
|
||||
if (e4crypt_is_native()) {
|
||||
// For now, FBE is only supported on internal storage
|
||||
if (e4crypt_is_native() && volume_uuid == nullptr) {
|
||||
std::string ce_raw_ref;
|
||||
if (!lookup_key_ref(s_ce_key_raw_refs, user_id, &ce_raw_ref)) return false;
|
||||
if (!ensure_policy(ce_raw_ref, system_ce_path)) return false;
|
||||
|
@ -645,3 +659,51 @@ bool e4crypt_prepare_user_storage(const char* volume_uuid, userid_t user_id, int
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool e4crypt_destroy_user_storage(const char* volume_uuid, userid_t user_id, int flags) {
|
||||
LOG(DEBUG) << "e4crypt_destroy_user_storage for volume " << escape_null(volume_uuid)
|
||||
<< ", user " << user_id << ", flags " << flags;
|
||||
bool res = true;
|
||||
|
||||
if (flags & FLAG_STORAGE_DE) {
|
||||
// DE_sys key
|
||||
auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id);
|
||||
auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id);
|
||||
auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
|
||||
auto foreign_de_path = android::vold::BuildDataProfilesForeignDexDePath(user_id);
|
||||
|
||||
// DE_n key
|
||||
auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
|
||||
auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
|
||||
auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
|
||||
|
||||
if (volume_uuid == nullptr) {
|
||||
res &= destroy_dir(system_legacy_path);
|
||||
#if MANAGE_MISC_DIRS
|
||||
res &= destroy_dir(misc_legacy_path);
|
||||
#endif
|
||||
res &= destroy_dir(profiles_de_path);
|
||||
res &= destroy_dir(foreign_de_path);
|
||||
res &= destroy_dir(system_de_path);
|
||||
res &= destroy_dir(misc_de_path);
|
||||
}
|
||||
res &= destroy_dir(user_de_path);
|
||||
}
|
||||
|
||||
if (flags & FLAG_STORAGE_CE) {
|
||||
// CE_n key
|
||||
auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
|
||||
auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
|
||||
auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
|
||||
auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
|
||||
|
||||
if (volume_uuid == nullptr) {
|
||||
res &= destroy_dir(system_ce_path);
|
||||
res &= destroy_dir(misc_ce_path);
|
||||
}
|
||||
res &= destroy_dir(media_ce_path);
|
||||
res &= destroy_dir(user_ce_path);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -35,5 +35,6 @@ bool e4crypt_unlock_user_key(userid_t user_id, int serial, const char* token, co
|
|||
bool e4crypt_lock_user_key(userid_t user_id);
|
||||
|
||||
bool e4crypt_prepare_user_storage(const char* volume_uuid, userid_t user_id, int serial, int flags);
|
||||
bool e4crypt_destroy_user_storage(const char* volume_uuid, userid_t user_id, int flags);
|
||||
|
||||
__END_DECLS
|
||||
|
|
12
Utils.cpp
12
Utils.cpp
|
@ -560,6 +560,10 @@ std::string BuildKeyPath(const std::string& partGuid) {
|
|||
return StringPrintf("%s/expand_%s.key", kKeyPath, partGuid.c_str());
|
||||
}
|
||||
|
||||
std::string BuildDataSystemLegacyPath(userid_t userId) {
|
||||
return StringPrintf("%s/system/users/%u", BuildDataPath(nullptr).c_str(), userId);
|
||||
}
|
||||
|
||||
std::string BuildDataSystemCePath(userid_t userId) {
|
||||
return StringPrintf("%s/system_ce/%u", BuildDataPath(nullptr).c_str(), userId);
|
||||
}
|
||||
|
@ -568,6 +572,10 @@ std::string BuildDataSystemDePath(userid_t userId) {
|
|||
return StringPrintf("%s/system_de/%u", BuildDataPath(nullptr).c_str(), userId);
|
||||
}
|
||||
|
||||
std::string BuildDataMiscLegacyPath(userid_t userId) {
|
||||
return StringPrintf("%s/misc/user/%u", BuildDataPath(nullptr).c_str(), userId);
|
||||
}
|
||||
|
||||
std::string BuildDataMiscCePath(userid_t userId) {
|
||||
return StringPrintf("%s/misc_ce/%u", BuildDataPath(nullptr).c_str(), userId);
|
||||
}
|
||||
|
@ -596,13 +604,13 @@ std::string BuildDataPath(const char* volumeUuid) {
|
|||
}
|
||||
}
|
||||
|
||||
std::string BuildDataMediaPath(const char* volumeUuid, userid_t userId) {
|
||||
std::string BuildDataMediaCePath(const char* volumeUuid, userid_t userId) {
|
||||
// TODO: unify with installd path generation logic
|
||||
std::string data(BuildDataPath(volumeUuid));
|
||||
return StringPrintf("%s/media/%u", data.c_str(), userId);
|
||||
}
|
||||
|
||||
std::string BuildDataUserPath(const char* volumeUuid, userid_t userId) {
|
||||
std::string BuildDataUserCePath(const char* volumeUuid, userid_t userId) {
|
||||
// TODO: unify with installd path generation logic
|
||||
std::string data(BuildDataPath(volumeUuid));
|
||||
if (volumeUuid == nullptr) {
|
||||
|
|
6
Utils.h
6
Utils.h
|
@ -96,16 +96,18 @@ status_t WipeBlockDevice(const std::string& path);
|
|||
|
||||
std::string BuildKeyPath(const std::string& partGuid);
|
||||
|
||||
std::string BuildDataSystemLegacyPath(userid_t userid);
|
||||
std::string BuildDataSystemCePath(userid_t userid);
|
||||
std::string BuildDataSystemDePath(userid_t userid);
|
||||
std::string BuildDataMiscLegacyPath(userid_t userid);
|
||||
std::string BuildDataMiscCePath(userid_t userid);
|
||||
std::string BuildDataMiscDePath(userid_t userid);
|
||||
std::string BuildDataProfilesDePath(userid_t userid);
|
||||
std::string BuildDataProfilesForeignDexDePath(userid_t userid);
|
||||
|
||||
std::string BuildDataPath(const char* volumeUuid);
|
||||
std::string BuildDataMediaPath(const char* volumeUuid, userid_t userid);
|
||||
std::string BuildDataUserPath(const char* volumeUuid, userid_t userid);
|
||||
std::string BuildDataMediaCePath(const char* volumeUuid, userid_t userid);
|
||||
std::string BuildDataUserCePath(const char* volumeUuid, userid_t userid);
|
||||
std::string BuildDataUserDePath(const char* volumeUuid, userid_t userid);
|
||||
|
||||
dev_t GetDevice(const std::string& path);
|
||||
|
|
Loading…
Reference in a new issue