Add init_user0 command.
Change-Id: Icf746ec1968a073fde707ecc788b648f5803fd38
diff --git a/CryptCommandListener.cpp b/CryptCommandListener.cpp
index c265fb0..2eac60e 100644
--- a/CryptCommandListener.cpp
+++ b/CryptCommandListener.cpp
@@ -354,6 +354,10 @@
dumpArgs(argc, argv, -1);
rc = cryptfs_isConvertibleToFBE();
+ } else if (subcommand == "init_user0") {
+ if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
+ return sendGenericOkFail(cli, e4crypt_init_user0());
+
} else if (subcommand == "create_user_key") {
if (!check_argc(cli, subcommand, argc, 5, "<user> <serial> <ephemeral>")) return 0;
return sendGenericOkFail(cli,
diff --git a/Ext4Crypt.cpp b/Ext4Crypt.cpp
index fb66a6b..04d7a12 100644
--- a/Ext4Crypt.cpp
+++ b/Ext4Crypt.cpp
@@ -593,7 +593,6 @@
// If the key should be created as ephemeral, store it in memory only.
s_ephemeral_user_keys[key_path] = key;
} else {
- if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return false;
if (!prepare_dir(user_key_dir + "/user_" + std::to_string(user_id),
0700, AID_ROOT, AID_ROOT)) return false;
if (!android::vold::storeKey(key_path, key)) return false;
@@ -613,6 +612,32 @@
return do_policy_set(path.c_str(), raw_ref.data(), raw_ref.size());
}
+int e4crypt_init_user0() {
+ LOG(DEBUG) << "e4crypt_init_user0";
+ if (e4crypt_is_native()) {
+ if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return -1;
+ std::string user_key;
+ if (!read_user_key(0, user_key)) {
+ // FIXME if the key exists and we just failed to read it, this destroys it.
+ if (!create_user_key(0, false)) {
+ return -1;
+ }
+ if (!read_user_key(0, user_key)) {
+ LOG(ERROR) << "Couldn't read just-created key for user 0";
+ return -1;
+ }
+ }
+ auto raw_ref = e4crypt_install_key(user_key);
+ if (raw_ref.empty()) {
+ return -1;
+ }
+ s_key_raw_refs[0] = raw_ref;
+ }
+ // Ignore failures. FIXME this is horrid
+ e4crypt_prepare_user_storage(nullptr, 0, 0, false);
+ return 0;
+}
+
int e4crypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral) {
LOG(DEBUG) << "e4crypt_vold_create_user_key for " << user_id << " serial " << serial;
if (!e4crypt_is_native()) {
@@ -703,31 +728,14 @@
if (e4crypt_is_native()) {
std::string user_key;
if (!read_user_key(user_id, user_key)) {
- // FIXME special case for user 0
- if (user_id != 0) {
- LOG(ERROR) << "Couldn't read key for " << user_id;
- return -1;
- }
- // FIXME if the key exists and we just failed to read it, this destroys it.
- if (!create_user_key(user_id, false)) {
- return -1;
- }
- if (!read_user_key(user_id, user_key)) {
- LOG(ERROR) << "Couldn't read just-created key for " << user_id;
- return -1;
- }
+ LOG(ERROR) << "Couldn't read key for " << user_id;
+ return -1;
}
auto raw_ref = e4crypt_install_key(user_key);
if (raw_ref.empty()) {
return -1;
}
s_key_raw_refs[serial] = raw_ref;
- if (user_id == 0) {
- // FIXME special case for user 0
- // prepare their storage here
- e4crypt_prepare_user_storage(nullptr, 0, 0, false);
- }
- return 0;
} else {
// When in emulation mode, we just use chmod. However, we also
// unlock directories when not in emulation mode, to bring devices
@@ -739,7 +747,6 @@
return -1;
}
}
-
return 0;
}
@@ -773,7 +780,8 @@
auto user_ce_path = android::vold::BuildDataUserPath(volume_uuid, user_id);
auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
- if (!prepare_dir(system_ce_path, 0700, AID_SYSTEM, AID_SYSTEM)) return -1;
+ // FIXME: should this be 0770 or 0700?
+ if (!prepare_dir(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM)) return -1;
if (!prepare_dir(media_ce_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return -1;
if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return -1;
if (!prepare_dir(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return -1;
diff --git a/Ext4Crypt.h b/Ext4Crypt.h
index 3fb6f16..9005f4a 100644
--- a/Ext4Crypt.h
+++ b/Ext4Crypt.h
@@ -36,6 +36,7 @@
int e4crypt_set_field(const char* path, const char* fieldname,
const char* value);
+int e4crypt_init_user0();
int e4crypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral);
int e4crypt_destroy_user_key(userid_t user_id);