Merge "Move vold (and sdcard childs) to foreground cpuset." into nyc-dev
diff --git a/CryptCommandListener.cpp b/CryptCommandListener.cpp
index 798a912..f4ced43 100644
--- a/CryptCommandListener.cpp
+++ b/CryptCommandListener.cpp
@@ -405,6 +405,11 @@
         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);
diff --git a/Ext4Crypt.cpp b/Ext4Crypt.cpp
index 11f104a..309a1f2 100644
--- a/Ext4Crypt.cpp
+++ b/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 @@
     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 @@
         // 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 @@
         // 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;
         }
@@ -586,54 +596,58 @@
 }
 
 bool e4crypt_prepare_user_storage(const char* volume_uuid, userid_t user_id, int serial,
-                                  int flags) {
+        int flags) {
     LOG(DEBUG) << "e4crypt_prepare_user_storage for volume " << escape_null(volume_uuid)
                << ", 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 @@
 
     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;
+}
diff --git a/Ext4Crypt.h b/Ext4Crypt.h
index dff2953..89cfbab 100644
--- a/Ext4Crypt.h
+++ b/Ext4Crypt.h
@@ -35,5 +35,6 @@
 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
diff --git a/Utils.cpp b/Utils.cpp
index 9d5f168..7ae22c5 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -560,6 +560,10 @@
     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 @@
     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 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) {
diff --git a/Utils.h b/Utils.h
index d2970e7..9abd322 100644
--- a/Utils.h
+++ b/Utils.h
@@ -96,16 +96,18 @@
 
 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);
diff --git a/cryptfs.c b/cryptfs.c
index f217fa5..eb9a8ed 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -3705,26 +3705,20 @@
  */
 int cryptfs_mount_default_encrypted(void)
 {
-    char decrypt_state[PROPERTY_VALUE_MAX];
-    property_get("vold.decrypt", decrypt_state, "0");
-    if (!strcmp(decrypt_state, "0")) {
-        SLOGE("Not encrypted - should not call here");
+    int crypt_type = cryptfs_get_password_type();
+    if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) {
+        SLOGE("Bad crypt type - error");
+    } else if (crypt_type != CRYPT_TYPE_DEFAULT) {
+        SLOGD("Password is not default - "
+              "starting min framework to prompt");
+        property_set("vold.decrypt", "trigger_restart_min_framework");
+        return 0;
+    } else if (cryptfs_check_passwd(DEFAULT_PASSWORD) == 0) {
+        SLOGD("Password is default - restarting filesystem");
+        cryptfs_restart_internal(0);
+        return 0;
     } else {
-        int crypt_type = cryptfs_get_password_type();
-        if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) {
-            SLOGE("Bad crypt type - error");
-        } else if (crypt_type != CRYPT_TYPE_DEFAULT) {
-            SLOGD("Password is not default - "
-                  "starting min framework to prompt");
-            property_set("vold.decrypt", "trigger_restart_min_framework");
-            return 0;
-        } else if (cryptfs_check_passwd(DEFAULT_PASSWORD) == 0) {
-            SLOGD("Password is default - restarting filesystem");
-            cryptfs_restart_internal(0);
-            return 0;
-        } else {
-            SLOGE("Encrypted, default crypt type but can't decrypt");
-        }
+        SLOGE("Encrypted, default crypt type but can't decrypt");
     }
 
     /** Corrupt. Allow us to boot into framework, which will detect bad
diff --git a/vdc.rc b/vdc.rc
index d5483d0..4d51ced 100644
--- a/vdc.rc
+++ b/vdc.rc
@@ -1,13 +1,12 @@
 # One shot invocation to deal with encrypted volume.
-service defaultcrypto /system/bin/vdc --wait cryptfs mountdefaultencrypted
-    disabled
-    oneshot
+on defaultcrypto
+    exec - root -- /system/bin/vdc --wait cryptfs mountdefaultencrypted
     # vold will set vold.decrypt to trigger_restart_framework (default
     # encryption) or trigger_restart_min_framework (other encryption)
 
 # One shot invocation to encrypt unencrypted volumes
-service encrypt /system/bin/vdc --wait cryptfs enablecrypto inplace default noui
-    disabled
-    oneshot
+on encrypt
+    start surfaceflinger
+    exec - root -- /system/bin/vdc --wait cryptfs enablecrypto inplace default noui
     # vold will set vold.decrypt to trigger_restart_framework (default
     # encryption)