Home | History | Annotate | Download | only in vold
      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