• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "FsCrypt.h"
18 
19 #include "Checkpoint.h"
20 #include "KeyStorage.h"
21 #include "KeyUtil.h"
22 #include "Utils.h"
23 #include "VoldUtil.h"
24 
25 #include <algorithm>
26 #include <map>
27 #include <optional>
28 #include <set>
29 #include <sstream>
30 #include <string>
31 #include <vector>
32 
33 #include <dirent.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <limits.h>
37 #include <sys/mount.h>
38 #include <sys/stat.h>
39 #include <sys/types.h>
40 #include <unistd.h>
41 
42 #include <private/android_filesystem_config.h>
43 #include <private/android_projectid_config.h>
44 
45 #include "android/os/IVold.h"
46 
47 #define MANAGE_MISC_DIRS 0
48 
49 #include <cutils/fs.h>
50 #include <cutils/properties.h>
51 
52 #include <fscrypt/fscrypt.h>
53 #include <keyutils.h>
54 #include <libdm/dm.h>
55 
56 #include <android-base/file.h>
57 #include <android-base/logging.h>
58 #include <android-base/properties.h>
59 #include <android-base/stringprintf.h>
60 #include <android-base/strings.h>
61 #include <android-base/unique_fd.h>
62 
63 using android::base::Basename;
64 using android::base::Realpath;
65 using android::base::StartsWith;
66 using android::base::StringPrintf;
67 using android::fs_mgr::GetEntryForMountPoint;
68 using android::vold::BuildDataPath;
69 using android::vold::IsDotOrDotDot;
70 using android::vold::IsFilesystemSupported;
71 using android::vold::kEmptyAuthentication;
72 using android::vold::KeyBuffer;
73 using android::vold::KeyGeneration;
74 using android::vold::retrieveKey;
75 using android::vold::retrieveOrGenerateKey;
76 using android::vold::SetDefaultAcl;
77 using android::vold::SetQuotaInherit;
78 using android::vold::SetQuotaProjectId;
79 using android::vold::writeStringToFile;
80 using namespace android::fscrypt;
81 using namespace android::dm;
82 
83 namespace {
84 
85 const std::string device_key_dir = std::string() + DATA_MNT_POINT + fscrypt_unencrypted_folder;
86 const std::string device_key_path = device_key_dir + "/key";
87 const std::string device_key_temp = device_key_dir + "/temp";
88 
89 const std::string user_key_dir = std::string() + DATA_MNT_POINT + "/misc/vold/user_keys";
90 const std::string user_key_temp = user_key_dir + "/temp";
91 const std::string prepare_subdirs_path = "/system/bin/vold_prepare_subdirs";
92 
93 const std::string systemwide_volume_key_dir =
94     std::string() + DATA_MNT_POINT + "/misc/vold/volume_keys";
95 
96 const std::string data_data_dir = std::string() + DATA_MNT_POINT + "/data";
97 const std::string data_user_0_dir = std::string() + DATA_MNT_POINT + "/user/0";
98 const std::string media_obb_dir = std::string() + DATA_MNT_POINT + "/media/obb";
99 
100 // The file encryption options to use on the /data filesystem
101 EncryptionOptions s_data_options;
102 
103 // Some users are ephemeral; don't try to store or wipe their keys on disk.
104 std::set<userid_t> s_ephemeral_users;
105 
106 // New CE keys that haven't been committed to disk yet
107 std::map<userid_t, KeyBuffer> s_new_ce_keys;
108 
109 // The system DE encryption policy
110 EncryptionPolicy s_device_policy;
111 
112 // Map user ids to encryption policies
113 std::map<userid_t, EncryptionPolicy> s_de_policies;
114 std::map<userid_t, EncryptionPolicy> s_ce_policies;
115 
116 // CE key fixation operations that have been deferred to checkpoint commit
117 std::map<std::string, std::string> s_deferred_fixations;
118 
119 }  // namespace
120 
121 // Returns KeyGeneration suitable for key as described in EncryptionOptions
makeGen(const EncryptionOptions & options)122 static KeyGeneration makeGen(const EncryptionOptions& options) {
123     if (options.version == 0) {
124         LOG(ERROR) << "EncryptionOptions not initialized";
125         return android::vold::neverGen();
126     }
127     return KeyGeneration{FSCRYPT_MAX_KEY_SIZE, true, options.use_hw_wrapped_key};
128 }
129 
escape_empty(const std::string & value)130 static const char* escape_empty(const std::string& value) {
131     return value.empty() ? "null" : value.c_str();
132 }
133 
get_de_key_path(userid_t user_id)134 static std::string get_de_key_path(userid_t user_id) {
135     return StringPrintf("%s/de/%d", user_key_dir.c_str(), user_id);
136 }
137 
get_ce_key_directory_path(userid_t user_id)138 static std::string get_ce_key_directory_path(userid_t user_id) {
139     return StringPrintf("%s/ce/%d", user_key_dir.c_str(), user_id);
140 }
141 
142 // Returns the keys newest first
get_ce_key_paths(const std::string & directory_path)143 static std::vector<std::string> get_ce_key_paths(const std::string& directory_path) {
144     auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(directory_path.c_str()), closedir);
145     if (!dirp) {
146         PLOG(ERROR) << "Unable to open ce key directory: " + directory_path;
147         return std::vector<std::string>();
148     }
149     std::vector<std::string> result;
150     for (;;) {
151         errno = 0;
152         auto const entry = readdir(dirp.get());
153         if (!entry) {
154             if (errno) {
155                 PLOG(ERROR) << "Unable to read ce key directory: " + directory_path;
156                 return std::vector<std::string>();
157             }
158             break;
159         }
160         if (IsDotOrDotDot(*entry)) continue;
161         if (entry->d_type != DT_DIR || entry->d_name[0] != 'c') {
162             LOG(DEBUG) << "Skipping non-key " << entry->d_name;
163             continue;
164         }
165         result.emplace_back(directory_path + "/" + entry->d_name);
166     }
167     std::sort(result.begin(), result.end());
168     std::reverse(result.begin(), result.end());
169     return result;
170 }
171 
get_ce_key_current_path(const std::string & directory_path)172 static std::string get_ce_key_current_path(const std::string& directory_path) {
173     return directory_path + "/current";
174 }
175 
get_ce_key_new_path(const std::string & directory_path,const std::vector<std::string> & paths,std::string * ce_key_path)176 static bool get_ce_key_new_path(const std::string& directory_path,
177                                 const std::vector<std::string>& paths, std::string* ce_key_path) {
178     if (paths.empty()) {
179         *ce_key_path = get_ce_key_current_path(directory_path);
180         return true;
181     }
182     for (unsigned int i = 0; i < UINT_MAX; i++) {
183         auto const candidate = StringPrintf("%s/cx%010u", directory_path.c_str(), i);
184         if (paths[0] < candidate) {
185             *ce_key_path = candidate;
186             return true;
187         }
188     }
189     return false;
190 }
191 
192 // Discard all keys but the named one; rename it to canonical name.
fixate_user_ce_key(const std::string & directory_path,const std::string & to_fix,const std::vector<std::string> & paths)193 static bool fixate_user_ce_key(const std::string& directory_path, const std::string& to_fix,
194                                const std::vector<std::string>& paths) {
195     bool need_sync = false;
196     for (auto const other_path : paths) {
197         if (other_path != to_fix) {
198             android::vold::destroyKey(other_path);
199             need_sync = true;
200         }
201     }
202     auto const current_path = get_ce_key_current_path(directory_path);
203     if (to_fix != current_path) {
204         LOG(DEBUG) << "Renaming " << to_fix << " to " << current_path;
205         if (!android::vold::RenameKeyDir(to_fix, current_path)) return false;
206         need_sync = true;
207     }
208     if (need_sync && !android::vold::FsyncDirectory(directory_path)) return false;
209     return true;
210 }
211 
read_and_fixate_user_ce_key(userid_t user_id,const android::vold::KeyAuthentication & auth,KeyBuffer * ce_key)212 static bool read_and_fixate_user_ce_key(userid_t user_id,
213                                         const android::vold::KeyAuthentication& auth,
214                                         KeyBuffer* ce_key) {
215     auto const directory_path = get_ce_key_directory_path(user_id);
216     auto const paths = get_ce_key_paths(directory_path);
217     for (auto const ce_key_path : paths) {
218         LOG(DEBUG) << "Trying user CE key " << ce_key_path;
219         if (retrieveKey(ce_key_path, auth, ce_key)) {
220             LOG(DEBUG) << "Successfully retrieved key";
221             s_deferred_fixations.erase(directory_path);
222             fixate_user_ce_key(directory_path, ce_key_path, paths);
223             return true;
224         }
225     }
226     LOG(ERROR) << "Failed to find working ce key for user " << user_id;
227     return false;
228 }
229 
MightBeEmmcStorage(const std::string & blk_device)230 static bool MightBeEmmcStorage(const std::string& blk_device) {
231     // Handle symlinks.
232     std::string real_path;
233     if (!Realpath(blk_device, &real_path)) {
234         real_path = blk_device;
235     }
236 
237     // Handle logical volumes.
238     auto& dm = DeviceMapper::Instance();
239     for (;;) {
240         auto parent = dm.GetParentBlockDeviceByPath(real_path);
241         if (!parent.has_value()) break;
242         real_path = *parent;
243     }
244 
245     // Now we should have the "real" block device.
246     LOG(DEBUG) << "MightBeEmmcStorage(): blk_device = " << blk_device
247                << ", real_path=" << real_path;
248     std::string name = Basename(real_path);
249     return StartsWith(name, "mmcblk") ||
250            // virtio devices may provide inline encryption support that is
251            // backed by eMMC inline encryption on the host, thus inheriting the
252            // DUN size limitation.  So virtio devices must be allowed here too.
253            // TODO(b/207390665): check the maximum DUN size directly instead.
254            StartsWith(name, "vd");
255 }
256 
257 // Sets s_data_options to the file encryption options for the /data filesystem.
init_data_file_encryption_options()258 static bool init_data_file_encryption_options() {
259     auto entry = GetEntryForMountPoint(&fstab_default, DATA_MNT_POINT);
260     if (entry == nullptr) {
261         LOG(ERROR) << "No mount point entry for " << DATA_MNT_POINT;
262         return false;
263     }
264     if (!ParseOptions(entry->encryption_options, &s_data_options)) {
265         LOG(ERROR) << "Unable to parse encryption options for " << DATA_MNT_POINT ": "
266                    << entry->encryption_options;
267         return false;
268     }
269     if ((s_data_options.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) &&
270         !MightBeEmmcStorage(entry->blk_device)) {
271         LOG(ERROR) << "The emmc_optimized encryption flag is only allowed on eMMC storage.  Remove "
272                       "this flag from the device's fstab";
273         return false;
274     }
275     return true;
276 }
277 
install_storage_key(const std::string & mountpoint,const EncryptionOptions & options,const KeyBuffer & key,EncryptionPolicy * policy)278 static bool install_storage_key(const std::string& mountpoint, const EncryptionOptions& options,
279                                 const KeyBuffer& key, EncryptionPolicy* policy) {
280     if (options.version == 0) {
281         LOG(ERROR) << "EncryptionOptions not initialized";
282         return false;
283     }
284     KeyBuffer ephemeral_wrapped_key;
285     if (options.use_hw_wrapped_key) {
286         if (!exportWrappedStorageKey(key, &ephemeral_wrapped_key)) {
287             LOG(ERROR) << "Failed to get ephemeral wrapped key";
288             return false;
289         }
290     }
291     return installKey(mountpoint, options, options.use_hw_wrapped_key ? ephemeral_wrapped_key : key,
292                       policy);
293 }
294 
295 // Retrieve the options to use for encryption policies on adoptable storage.
get_volume_file_encryption_options(EncryptionOptions * options)296 static bool get_volume_file_encryption_options(EncryptionOptions* options) {
297     // If we give the empty string, libfscrypt will use the default (currently XTS)
298     auto contents_mode = android::base::GetProperty("ro.crypto.volume.contents_mode", "");
299     // HEH as default was always a mistake. Use the libfscrypt default (CTS)
300     // for devices launching on versions above Android 10.
301     auto first_api_level = GetFirstApiLevel();
302     auto filenames_mode =
303             android::base::GetProperty("ro.crypto.volume.filenames_mode",
304                                        first_api_level > __ANDROID_API_Q__ ? "" : "aes-256-heh");
305     auto options_string = android::base::GetProperty("ro.crypto.volume.options",
306                                                      contents_mode + ":" + filenames_mode);
307     if (!ParseOptionsForApiLevel(first_api_level, options_string, options)) {
308         LOG(ERROR) << "Unable to parse volume encryption options: " << options_string;
309         return false;
310     }
311     if (options->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) {
312         LOG(ERROR) << "The emmc_optimized encryption flag is only allowed on eMMC storage.  Remove "
313                       "this flag from ro.crypto.volume.options";
314         return false;
315     }
316     return true;
317 }
318 
read_and_install_user_ce_key(userid_t user_id,const android::vold::KeyAuthentication & auth)319 static bool read_and_install_user_ce_key(userid_t user_id,
320                                          const android::vold::KeyAuthentication& auth) {
321     if (s_ce_policies.count(user_id) != 0) return true;
322     KeyBuffer ce_key;
323     if (!read_and_fixate_user_ce_key(user_id, auth, &ce_key)) return false;
324     EncryptionPolicy ce_policy;
325     if (!install_storage_key(DATA_MNT_POINT, s_data_options, ce_key, &ce_policy)) return false;
326     s_ce_policies[user_id] = ce_policy;
327     LOG(DEBUG) << "Installed ce key for user " << user_id;
328     return true;
329 }
330 
331 // Prepare a directory without assigning it an encryption policy.  The directory
332 // will inherit the encryption policy of its parent directory, or will be
333 // unencrypted if the parent directory is unencrypted.
prepare_dir(const std::string & dir,mode_t mode,uid_t uid,gid_t gid)334 static bool prepare_dir(const std::string& dir, mode_t mode, uid_t uid, gid_t gid) {
335     LOG(DEBUG) << "Preparing: " << dir;
336     if (android::vold::PrepareDir(dir, mode, uid, gid, 0) != 0) {
337         PLOG(ERROR) << "Failed to prepare " << dir;
338         return false;
339     }
340     return true;
341 }
342 
343 // Prepare a directory and assign it the given encryption policy.
prepare_dir_with_policy(const std::string & dir,mode_t mode,uid_t uid,gid_t gid,const EncryptionPolicy & policy)344 static bool prepare_dir_with_policy(const std::string& dir, mode_t mode, uid_t uid, gid_t gid,
345                                     const EncryptionPolicy& policy) {
346     if (!prepare_dir(dir, mode, uid, gid)) return false;
347     if (IsFbeEnabled() && !EnsurePolicy(policy, dir)) return false;
348     return true;
349 }
350 
destroy_dir(const std::string & dir)351 static bool destroy_dir(const std::string& dir) {
352     LOG(DEBUG) << "Destroying: " << dir;
353     if (rmdir(dir.c_str()) != 0 && errno != ENOENT) {
354         PLOG(ERROR) << "Failed to destroy " << dir;
355         return false;
356     }
357     return true;
358 }
359 
360 // Checks whether the DE key directory exists for the given user.
de_key_exists(userid_t user_id)361 static bool de_key_exists(userid_t user_id) {
362     return android::vold::pathExists(get_de_key_path(user_id));
363 }
364 
365 // Checks whether at least one CE key subdirectory exists for the given user.
ce_key_exists(userid_t user_id)366 static bool ce_key_exists(userid_t user_id) {
367     auto directory_path = get_ce_key_directory_path(user_id);
368     // The common case is that "$dir/current" exists, so check for that first.
369     if (android::vold::pathExists(get_ce_key_current_path(directory_path))) return true;
370 
371     // Else, there could still be another subdirectory of $dir (if a crash
372     // occurred during fixate_user_ce_key()), so check for one.
373     return android::vold::pathExists(directory_path) && !get_ce_key_paths(directory_path).empty();
374 }
375 
create_de_key(userid_t user_id,bool ephemeral)376 static bool create_de_key(userid_t user_id, bool ephemeral) {
377     KeyBuffer de_key;
378     if (!generateStorageKey(makeGen(s_data_options), &de_key)) return false;
379     if (!ephemeral && !android::vold::storeKeyAtomically(get_de_key_path(user_id), user_key_temp,
380                                                          kEmptyAuthentication, de_key))
381         return false;
382     EncryptionPolicy de_policy;
383     if (!install_storage_key(DATA_MNT_POINT, s_data_options, de_key, &de_policy)) return false;
384     s_de_policies[user_id] = de_policy;
385     LOG(INFO) << "Created DE key for user " << user_id;
386     return true;
387 }
388 
create_ce_key(userid_t user_id,bool ephemeral)389 static bool create_ce_key(userid_t user_id, bool ephemeral) {
390     KeyBuffer ce_key;
391     if (!generateStorageKey(makeGen(s_data_options), &ce_key)) return false;
392     if (!ephemeral) {
393         if (!prepare_dir(get_ce_key_directory_path(user_id), 0700, AID_ROOT, AID_ROOT))
394             return false;
395         // We don't store the CE key on disk here, since here we don't have the
396         // secret needed to do so securely.  Instead, we cache it in memory for
397         // now, and we store it later in fscrypt_set_user_key_protection().
398         s_new_ce_keys.insert({user_id, ce_key});
399     }
400     EncryptionPolicy ce_policy;
401     if (!install_storage_key(DATA_MNT_POINT, s_data_options, ce_key, &ce_policy)) return false;
402     s_ce_policies[user_id] = ce_policy;
403     LOG(INFO) << "Created CE key for user " << user_id;
404     return true;
405 }
406 
lookup_policy(const std::map<userid_t,EncryptionPolicy> & key_map,userid_t user_id,EncryptionPolicy * policy)407 static bool lookup_policy(const std::map<userid_t, EncryptionPolicy>& key_map, userid_t user_id,
408                           EncryptionPolicy* policy) {
409     auto refi = key_map.find(user_id);
410     if (refi == key_map.end()) {
411         return false;
412     }
413     *policy = refi->second;
414     return true;
415 }
416 
is_numeric(const char * name)417 static bool is_numeric(const char* name) {
418     for (const char* p = name; *p != '\0'; p++) {
419         if (!isdigit(*p)) return false;
420     }
421     return true;
422 }
423 
load_all_de_keys()424 static bool load_all_de_keys() {
425     auto de_dir = user_key_dir + "/de";
426     auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(de_dir.c_str()), closedir);
427     if (!dirp) {
428         PLOG(ERROR) << "Unable to read de key directory";
429         return false;
430     }
431     for (;;) {
432         errno = 0;
433         auto entry = readdir(dirp.get());
434         if (!entry) {
435             if (errno) {
436                 PLOG(ERROR) << "Unable to read de key directory";
437                 return false;
438             }
439             break;
440         }
441         if (IsDotOrDotDot(*entry)) continue;
442         if (entry->d_type != DT_DIR || !is_numeric(entry->d_name)) {
443             LOG(DEBUG) << "Skipping non-de-key " << entry->d_name;
444             continue;
445         }
446         userid_t user_id = std::stoi(entry->d_name);
447         auto key_path = de_dir + "/" + entry->d_name;
448         KeyBuffer de_key;
449         if (!retrieveKey(key_path, kEmptyAuthentication, &de_key)) {
450             // This is probably a partially removed user, so ignore
451             if (user_id != 0) continue;
452             return false;
453         }
454         EncryptionPolicy de_policy;
455         if (!install_storage_key(DATA_MNT_POINT, s_data_options, de_key, &de_policy)) return false;
456         auto ret = s_de_policies.insert({user_id, de_policy});
457         if (!ret.second && ret.first->second != de_policy) {
458             LOG(ERROR) << "DE policy for user" << user_id << " changed";
459             return false;
460         }
461         LOG(DEBUG) << "Installed de key for user " << user_id;
462     }
463     // fscrypt:TODO: go through all DE directories, ensure that all user dirs have the
464     // correct policy set on them, and that no rogue ones exist.
465     return true;
466 }
467 
468 // Attempt to reinstall CE keys for users that we think are unlocked.
try_reload_ce_keys()469 static bool try_reload_ce_keys() {
470     for (const auto& it : s_ce_policies) {
471         if (!android::vold::reloadKeyFromSessionKeyring(DATA_MNT_POINT, it.second)) {
472             LOG(ERROR) << "Failed to load CE key from session keyring for user " << it.first;
473             return false;
474         }
475     }
476     return true;
477 }
478 
fscrypt_initialize_systemwide_keys()479 bool fscrypt_initialize_systemwide_keys() {
480     LOG(INFO) << "fscrypt_initialize_systemwide_keys";
481 
482     if (!init_data_file_encryption_options()) return false;
483 
484     KeyBuffer device_key;
485     if (!retrieveOrGenerateKey(device_key_path, device_key_temp, kEmptyAuthentication,
486                                makeGen(s_data_options), &device_key))
487         return false;
488 
489     // This initializes s_device_policy, which is a global variable so that
490     // fscrypt_init_user0() can access it later.
491     if (!install_storage_key(DATA_MNT_POINT, s_data_options, device_key, &s_device_policy))
492         return false;
493 
494     std::string options_string;
495     if (!OptionsToString(s_device_policy.options, &options_string)) {
496         LOG(ERROR) << "Unable to serialize options";
497         return false;
498     }
499     std::string options_filename = std::string(DATA_MNT_POINT) + fscrypt_key_mode;
500     if (!android::vold::writeStringToFile(options_string, options_filename)) return false;
501 
502     std::string ref_filename = std::string(DATA_MNT_POINT) + fscrypt_key_ref;
503     if (!android::vold::writeStringToFile(s_device_policy.key_raw_ref, ref_filename)) return false;
504     LOG(INFO) << "Wrote system DE key reference to:" << ref_filename;
505 
506     KeyBuffer per_boot_key;
507     if (!generateStorageKey(makeGen(s_data_options), &per_boot_key)) return false;
508     EncryptionPolicy per_boot_policy;
509     if (!install_storage_key(DATA_MNT_POINT, s_data_options, per_boot_key, &per_boot_policy))
510         return false;
511     std::string per_boot_ref_filename = std::string("/data") + fscrypt_key_per_boot_ref;
512     if (!android::vold::writeStringToFile(per_boot_policy.key_raw_ref, per_boot_ref_filename))
513         return false;
514     LOG(INFO) << "Wrote per boot key reference to:" << per_boot_ref_filename;
515 
516     return true;
517 }
518 
prepare_special_dirs()519 static bool prepare_special_dirs() {
520     // Ensure that /data/data and its "alias" /data/user/0 exist, and create the
521     // bind mount of /data/data onto /data/user/0.  This *should* happen in
522     // fscrypt_prepare_user_storage().  However, it actually must be done early,
523     // before the rest of user 0's CE storage is prepared.  This is because
524     // zygote may need to set up app data isolation before then, which requires
525     // mounting a tmpfs over /data/data to ensure it remains hidden.  This issue
526     // arises due to /data/data being in the top-level directory.
527 
528     // /data/user/0 used to be a symlink to /data/data, so we must first delete
529     // the old symlink if present.
530     if (android::vold::IsSymlink(data_user_0_dir) && android::vold::Unlink(data_user_0_dir) != 0)
531         return false;
532     // On first boot, we'll be creating /data/data for the first time, and user
533     // 0's CE key will be installed already since it was just created.  Take the
534     // opportunity to also set the encryption policy of /data/data right away.
535     EncryptionPolicy ce_policy;
536     if (lookup_policy(s_ce_policies, 0, &ce_policy)) {
537         if (!prepare_dir_with_policy(data_data_dir, 0771, AID_SYSTEM, AID_SYSTEM, ce_policy)) {
538             // Preparing /data/data failed, yet we had just generated a new CE
539             // key because one wasn't stored.  Before erroring out, try deleting
540             // the directory and retrying, as it's possible that the directory
541             // exists with different CE policy from an interrupted first boot.
542             if (rmdir(data_data_dir.c_str()) != 0) {
543                 PLOG(ERROR) << "rmdir " << data_data_dir << " failed";
544             }
545             if (!prepare_dir_with_policy(data_data_dir, 0771, AID_SYSTEM, AID_SYSTEM, ce_policy))
546                 return false;
547         }
548     } else {
549         if (!prepare_dir(data_data_dir, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
550         // EnsurePolicy() will have to happen later, in fscrypt_prepare_user_storage().
551     }
552     if (!prepare_dir(data_user_0_dir, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
553     if (android::vold::BindMount(data_data_dir, data_user_0_dir) != 0) return false;
554 
555     // If /data/media/obb doesn't exist, create it and encrypt it with the
556     // device policy.  Normally, device-policy-encrypted directories are created
557     // and encrypted by init; /data/media/obb is special because it is located
558     // in /data/media.  Since /data/media also contains per-user encrypted
559     // directories, by design only vold can write to it.  As a side effect of
560     // that, vold must create /data/media/obb.
561     //
562     // We must tolerate /data/media/obb being unencrypted if it already exists
563     // on-disk, since it used to be unencrypted (b/64566063).
564     if (android::vold::pathExists(media_obb_dir)) {
565         if (!prepare_dir(media_obb_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
566     } else {
567         if (!prepare_dir_with_policy(media_obb_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW,
568                                      s_device_policy))
569             return false;
570     }
571     return true;
572 }
573 
574 bool fscrypt_init_user0_done;
575 
fscrypt_init_user0()576 bool fscrypt_init_user0() {
577     LOG(DEBUG) << "fscrypt_init_user0";
578 
579     if (IsFbeEnabled()) {
580         if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return false;
581         if (!prepare_dir(user_key_dir + "/ce", 0700, AID_ROOT, AID_ROOT)) return false;
582         if (!prepare_dir(user_key_dir + "/de", 0700, AID_ROOT, AID_ROOT)) return false;
583 
584         // Create user 0's DE and CE keys if they don't already exist.  Check
585         // each key independently, since if the first boot was interrupted it is
586         // possible that the DE key exists but the CE key does not.
587         if (!de_key_exists(0) && !create_de_key(0, false)) return false;
588         if (!ce_key_exists(0) && !create_ce_key(0, false)) return false;
589 
590         // TODO: switch to loading only DE_0 here once framework makes
591         // explicit calls to install DE keys for secondary users
592         if (!load_all_de_keys()) return false;
593     }
594 
595     // Now that user 0's CE key has been created, we can prepare /data/data.
596     if (!prepare_special_dirs()) return false;
597 
598     // With the exception of what is done by prepare_special_dirs() above, we
599     // only prepare DE storage here, since user 0's CE key won't be installed
600     // yet unless it was just created.  The framework will prepare the user's CE
601     // storage later, once their CE key is installed.
602     if (!fscrypt_prepare_user_storage("", 0, 0, android::os::IVold::STORAGE_FLAG_DE)) {
603         LOG(ERROR) << "Failed to prepare user 0 storage";
604         return false;
605     }
606 
607     // In some scenarios (e.g. userspace reboot) we might unmount userdata
608     // without doing a hard reboot. If CE keys were stored in fs keyring then
609     // they will be lost after unmount. Attempt to re-install them.
610     if (IsFbeEnabled() && android::vold::isFsKeyringSupported()) {
611         if (!try_reload_ce_keys()) return false;
612     }
613 
614     fscrypt_init_user0_done = true;
615     return true;
616 }
617 
fscrypt_vold_create_user_key(userid_t user_id,int serial,bool ephemeral)618 bool fscrypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral) {
619     LOG(DEBUG) << "fscrypt_vold_create_user_key for " << user_id << " serial " << serial;
620     if (!IsFbeEnabled()) {
621         return true;
622     }
623     // FIXME test for existence of key that is not loaded yet
624     if (s_ce_policies.count(user_id) != 0) {
625         LOG(ERROR) << "Already exists, can't fscrypt_vold_create_user_key for " << user_id
626                    << " serial " << serial;
627         // FIXME should we fail the command?
628         return true;
629     }
630     if (!create_de_key(user_id, ephemeral)) return false;
631     if (!create_ce_key(user_id, ephemeral)) return false;
632     if (ephemeral) s_ephemeral_users.insert(user_id);
633     return true;
634 }
635 
636 // "Lock" all encrypted directories whose key has been removed.  This is needed
637 // in the case where the keys are being put in the session keyring (rather in
638 // the newer filesystem-level keyrings), because removing a key from the session
639 // keyring doesn't affect inodes in the kernel's inode cache whose per-file key
640 // was already set up.  So to remove the per-file keys and make the files
641 // "appear encrypted", these inodes must be evicted.
642 //
643 // To do this, sync() to clean all dirty inodes, then drop all reclaimable slab
644 // objects systemwide.  This is overkill, but it's the best available method
645 // currently.  Don't use drop_caches mode "3" because that also evicts pagecache
646 // for in-use files; all files relevant here are already closed and sync'ed.
drop_caches_if_needed()647 static void drop_caches_if_needed() {
648     if (android::vold::isFsKeyringSupported()) {
649         return;
650     }
651     sync();
652     if (!writeStringToFile("2", "/proc/sys/vm/drop_caches")) {
653         PLOG(ERROR) << "Failed to drop caches during key eviction";
654     }
655 }
656 
evict_ce_key(userid_t user_id)657 static bool evict_ce_key(userid_t user_id) {
658     bool success = true;
659     EncryptionPolicy policy;
660     // If we haven't loaded the CE key, no need to evict it.
661     if (lookup_policy(s_ce_policies, user_id, &policy)) {
662         success &= android::vold::evictKey(DATA_MNT_POINT, policy);
663         drop_caches_if_needed();
664     }
665     s_ce_policies.erase(user_id);
666     s_new_ce_keys.erase(user_id);
667     return success;
668 }
669 
fscrypt_destroy_user_key(userid_t user_id)670 bool fscrypt_destroy_user_key(userid_t user_id) {
671     LOG(DEBUG) << "fscrypt_destroy_user_key(" << user_id << ")";
672     if (!IsFbeEnabled()) {
673         return true;
674     }
675     bool success = true;
676     success &= evict_ce_key(user_id);
677     EncryptionPolicy de_policy;
678     success &= lookup_policy(s_de_policies, user_id, &de_policy) &&
679                android::vold::evictKey(DATA_MNT_POINT, de_policy);
680     s_de_policies.erase(user_id);
681     if (!s_ephemeral_users.erase(user_id)) {
682         auto ce_path = get_ce_key_directory_path(user_id);
683         if (!s_new_ce_keys.erase(user_id)) {
684             for (auto const path : get_ce_key_paths(ce_path)) {
685                 success &= android::vold::destroyKey(path);
686             }
687         }
688         s_deferred_fixations.erase(ce_path);
689         success &= destroy_dir(ce_path);
690 
691         auto de_key_path = get_de_key_path(user_id);
692         if (android::vold::pathExists(de_key_path)) {
693             success &= android::vold::destroyKey(de_key_path);
694         } else {
695             LOG(INFO) << "Not present so not erasing: " << de_key_path;
696         }
697     }
698     return success;
699 }
700 
parse_hex(const std::string & hex,std::string * result)701 static bool parse_hex(const std::string& hex, std::string* result) {
702     if (hex == "!") {
703         *result = "";
704         return true;
705     }
706     if (android::vold::HexToStr(hex, *result) != 0) {
707         LOG(ERROR) << "Invalid FBE hex string";  // Don't log the string for security reasons
708         return false;
709     }
710     return true;
711 }
712 
authentication_from_hex(const std::string & secret_hex)713 static std::optional<android::vold::KeyAuthentication> authentication_from_hex(
714         const std::string& secret_hex) {
715     std::string secret;
716     if (!parse_hex(secret_hex, &secret)) return std::optional<android::vold::KeyAuthentication>();
717     if (secret.empty()) {
718         return kEmptyAuthentication;
719     } else {
720         return android::vold::KeyAuthentication(secret);
721     }
722 }
723 
volkey_path(const std::string & misc_path,const std::string & volume_uuid)724 static std::string volkey_path(const std::string& misc_path, const std::string& volume_uuid) {
725     return misc_path + "/vold/volume_keys/" + volume_uuid + "/default";
726 }
727 
volume_secdiscardable_path(const std::string & volume_uuid)728 static std::string volume_secdiscardable_path(const std::string& volume_uuid) {
729     return systemwide_volume_key_dir + "/" + volume_uuid + "/secdiscardable";
730 }
731 
read_or_create_volkey(const std::string & misc_path,const std::string & volume_uuid,EncryptionPolicy * policy)732 static bool read_or_create_volkey(const std::string& misc_path, const std::string& volume_uuid,
733                                   EncryptionPolicy* policy) {
734     auto secdiscardable_path = volume_secdiscardable_path(volume_uuid);
735     std::string secdiscardable_hash;
736     if (android::vold::pathExists(secdiscardable_path)) {
737         if (!android::vold::readSecdiscardable(secdiscardable_path, &secdiscardable_hash))
738             return false;
739     } else {
740         if (!android::vold::MkdirsSync(secdiscardable_path, 0700)) return false;
741         if (!android::vold::createSecdiscardable(secdiscardable_path, &secdiscardable_hash))
742             return false;
743     }
744     auto key_path = volkey_path(misc_path, volume_uuid);
745     if (!android::vold::MkdirsSync(key_path, 0700)) return false;
746     android::vold::KeyAuthentication auth(secdiscardable_hash);
747 
748     EncryptionOptions options;
749     if (!get_volume_file_encryption_options(&options)) return false;
750     KeyBuffer key;
751     if (!retrieveOrGenerateKey(key_path, key_path + "_tmp", auth, makeGen(options), &key))
752         return false;
753     if (!install_storage_key(BuildDataPath(volume_uuid), options, key, policy)) return false;
754     return true;
755 }
756 
destroy_volkey(const std::string & misc_path,const std::string & volume_uuid)757 static bool destroy_volkey(const std::string& misc_path, const std::string& volume_uuid) {
758     auto path = volkey_path(misc_path, volume_uuid);
759     if (!android::vold::pathExists(path)) return true;
760     return android::vold::destroyKey(path);
761 }
762 
763 // (Re-)encrypts the user's CE key with the given secret.  This function handles
764 // storing the CE key for a new user for the first time.  It also handles
765 // re-encrypting the CE key upon upgrade from an Android version where the CE
766 // key was stored with kEmptyAuthentication when the user didn't have an LSKF.
767 // See the comments below for the different cases handled.
fscrypt_set_user_key_protection(userid_t user_id,const std::string & secret_hex)768 bool fscrypt_set_user_key_protection(userid_t user_id, const std::string& secret_hex) {
769     LOG(DEBUG) << "fscrypt_set_user_key_protection " << user_id;
770     if (!IsFbeEnabled()) return true;
771     auto auth = authentication_from_hex(secret_hex);
772     if (!auth) return false;
773     if (auth->secret.empty()) {
774         LOG(ERROR) << "fscrypt_set_user_key_protection: secret must be nonempty";
775         return false;
776     }
777     // We shouldn't store any keys for ephemeral users.
778     if (s_ephemeral_users.count(user_id) != 0) {
779         LOG(DEBUG) << "Not storing key because user is ephemeral";
780         return true;
781     }
782     KeyBuffer ce_key;
783     auto it = s_new_ce_keys.find(user_id);
784     if (it != s_new_ce_keys.end()) {
785         // If the key exists in s_new_ce_keys, then the key is a
786         // not-yet-committed key for a new user, and we are committing it here.
787         // This happens when the user's synthetic password is created.
788         ce_key = it->second;
789     } else if (ce_key_exists(user_id)) {
790         // If the key doesn't exist in s_new_ce_keys but does exist on-disk,
791         // then we are setting the protection on an existing key.  This happens
792         // at upgrade time, when CE keys that were previously protected by
793         // kEmptyAuthentication are encrypted by the user's synthetic password.
794         LOG(DEBUG) << "CE key already exists on-disk; re-protecting it with the given secret";
795         if (!read_and_fixate_user_ce_key(user_id, kEmptyAuthentication, &ce_key)) {
796             LOG(ERROR) << "Failed to retrieve CE key for user " << user_id << " using empty auth";
797             // Before failing, also check whether the key is already protected
798             // with the given secret.  This isn't expected, but in theory it
799             // could happen if an upgrade is requested for a user more than once
800             // due to a power-off or other interruption.
801             if (read_and_fixate_user_ce_key(user_id, *auth, &ce_key)) {
802                 LOG(WARNING) << "CE key is already protected by given secret";
803                 return true;
804             }
805             // The key isn't protected by either kEmptyAuthentication or by
806             // |auth|.  This should never happen, and there's nothing we can do
807             // besides return an error.
808             return false;
809         }
810     } else {
811         // If the key doesn't exist in memory or on-disk, then we need to
812         // generate it here, then commit it to disk.  This is needed after the
813         // unusual case where a non-system user was created during early boot,
814         // and then the device was force-rebooted before the boot completed.  In
815         // that case, the Android user record was committed but the CE key was
816         // not.  So the CE key was lost, and we need to regenerate it.  This
817         // should be fine, since the key should not have been used yet.
818         LOG(WARNING) << "CE key not found!  Regenerating it";
819         if (!create_ce_key(user_id, false)) return false;
820         ce_key = s_new_ce_keys.find(user_id)->second;
821     }
822 
823     auto const directory_path = get_ce_key_directory_path(user_id);
824     auto const paths = get_ce_key_paths(directory_path);
825     std::string ce_key_path;
826     if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
827     if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, *auth, ce_key)) return false;
828 
829     // Fixate the key, i.e. delete all other bindings of it.  (In practice this
830     // just means the kEmptyAuthentication binding, if there is one.)  However,
831     // if a userdata filesystem checkpoint is pending, then we need to delay the
832     // fixation until the checkpoint has been committed, since deleting keys
833     // from Keystore cannot be rolled back.
834     if (android::vold::cp_needsCheckpoint()) {
835         LOG(INFO) << "Deferring fixation of " << directory_path << " until checkpoint is committed";
836         s_deferred_fixations[directory_path] = ce_key_path;
837     } else {
838         s_deferred_fixations.erase(directory_path);
839         if (!fixate_user_ce_key(directory_path, ce_key_path, paths)) return false;
840     }
841 
842     if (s_new_ce_keys.erase(user_id)) {
843         LOG(INFO) << "Stored CE key for new user " << user_id;
844     }
845     return true;
846 }
847 
fscrypt_deferred_fixate_ce_keys()848 void fscrypt_deferred_fixate_ce_keys() {
849     for (const auto& it : s_deferred_fixations) {
850         const auto& directory_path = it.first;
851         const auto& to_fix = it.second;
852         LOG(INFO) << "Doing deferred fixation of " << directory_path;
853         fixate_user_ce_key(directory_path, to_fix, get_ce_key_paths(directory_path));
854         // Continue on error.
855     }
856     s_deferred_fixations.clear();
857 }
858 
fscrypt_get_unlocked_users()859 std::vector<int> fscrypt_get_unlocked_users() {
860     std::vector<int> user_ids;
861     for (const auto& it : s_ce_policies) {
862         user_ids.push_back(it.first);
863     }
864     return user_ids;
865 }
866 
867 // TODO: rename to 'install' for consistency, and take flags to know which keys to install
fscrypt_unlock_user_key(userid_t user_id,int serial,const std::string & secret_hex)868 bool fscrypt_unlock_user_key(userid_t user_id, int serial, const std::string& secret_hex) {
869     LOG(DEBUG) << "fscrypt_unlock_user_key " << user_id << " serial=" << serial;
870     if (IsFbeEnabled()) {
871         if (s_ce_policies.count(user_id) != 0) {
872             LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id;
873             return true;
874         }
875         auto auth = authentication_from_hex(secret_hex);
876         if (!auth) return false;
877         if (!read_and_install_user_ce_key(user_id, *auth)) {
878             LOG(ERROR) << "Couldn't read key for " << user_id;
879             return false;
880         }
881     }
882     return true;
883 }
884 
885 // TODO: rename to 'evict' for consistency
fscrypt_lock_user_key(userid_t user_id)886 bool fscrypt_lock_user_key(userid_t user_id) {
887     LOG(DEBUG) << "fscrypt_lock_user_key " << user_id;
888     if (IsFbeEnabled()) {
889         return evict_ce_key(user_id);
890     }
891     return true;
892 }
893 
prepare_subdirs(const std::string & action,const std::string & volume_uuid,userid_t user_id,int flags)894 static bool prepare_subdirs(const std::string& action, const std::string& volume_uuid,
895                             userid_t user_id, int flags) {
896     if (0 != android::vold::ForkExecvp(
897                  std::vector<std::string>{prepare_subdirs_path, action, volume_uuid,
898                                           std::to_string(user_id), std::to_string(flags)})) {
899         LOG(ERROR) << "vold_prepare_subdirs failed";
900         return false;
901     }
902     return true;
903 }
904 
fscrypt_prepare_user_storage(const std::string & volume_uuid,userid_t user_id,int serial,int flags)905 bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial,
906                                   int flags) {
907     LOG(DEBUG) << "fscrypt_prepare_user_storage for volume " << escape_empty(volume_uuid)
908                << ", user " << user_id << ", serial " << serial << ", flags " << flags;
909 
910     // Internal storage must be prepared before adoptable storage, since the
911     // user's volume keys are stored in their internal storage.
912     if (!volume_uuid.empty()) {
913         if ((flags & android::os::IVold::STORAGE_FLAG_DE) &&
914             !android::vold::pathExists(android::vold::BuildDataMiscDePath("", user_id))) {
915             LOG(ERROR) << "Cannot prepare DE storage for user " << user_id << " on volume "
916                        << volume_uuid << " before internal storage";
917             return false;
918         }
919         if ((flags & android::os::IVold::STORAGE_FLAG_CE) &&
920             !android::vold::pathExists(android::vold::BuildDataMiscCePath("", user_id))) {
921             LOG(ERROR) << "Cannot prepare CE storage for user " << user_id << " on volume "
922                        << volume_uuid << " before internal storage";
923             return false;
924         }
925     }
926 
927     if (flags & android::os::IVold::STORAGE_FLAG_DE) {
928         // DE_sys key
929         auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id);
930         auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id);
931         auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
932 
933         // DE_n key
934         EncryptionPolicy de_policy;
935         auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
936         auto misc_de_path = android::vold::BuildDataMiscDePath(volume_uuid, user_id);
937         auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
938         auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
939 
940         if (IsFbeEnabled()) {
941             if (volume_uuid.empty()) {
942                 if (!lookup_policy(s_de_policies, user_id, &de_policy)) {
943                     LOG(ERROR) << "Cannot find DE policy for user " << user_id;
944                     return false;
945                 }
946             } else {
947                 auto misc_de_empty_volume_path = android::vold::BuildDataMiscDePath("", user_id);
948                 if (!read_or_create_volkey(misc_de_empty_volume_path, volume_uuid, &de_policy)) {
949                     return false;
950                 }
951             }
952         }
953 
954         if (volume_uuid.empty()) {
955             if (!prepare_dir(system_legacy_path, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
956 #if MANAGE_MISC_DIRS
957             if (!prepare_dir(misc_legacy_path, 0750, multiuser_get_uid(user_id, AID_SYSTEM),
958                              multiuser_get_uid(user_id, AID_EVERYBODY)))
959                 return false;
960 #endif
961             if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
962 
963             if (!prepare_dir_with_policy(system_de_path, 0770, AID_SYSTEM, AID_SYSTEM, de_policy))
964                 return false;
965             if (!prepare_dir_with_policy(vendor_de_path, 0771, AID_ROOT, AID_ROOT, de_policy))
966                 return false;
967         }
968 
969         if (!prepare_dir_with_policy(misc_de_path, 01771, AID_SYSTEM, AID_MISC, de_policy))
970             return false;
971         if (!prepare_dir_with_policy(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM, de_policy))
972             return false;
973     }
974 
975     if (flags & android::os::IVold::STORAGE_FLAG_CE) {
976         // CE_n key
977         EncryptionPolicy ce_policy;
978         auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
979         auto misc_ce_path = android::vold::BuildDataMiscCePath(volume_uuid, user_id);
980         auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
981         auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
982         auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
983 
984         if (IsFbeEnabled()) {
985             if (volume_uuid.empty()) {
986                 if (!lookup_policy(s_ce_policies, user_id, &ce_policy)) {
987                     LOG(ERROR) << "Cannot find CE policy for user " << user_id;
988                     return false;
989                 }
990             } else {
991                 auto misc_ce_empty_volume_path = android::vold::BuildDataMiscCePath("", user_id);
992                 if (!read_or_create_volkey(misc_ce_empty_volume_path, volume_uuid, &ce_policy)) {
993                     return false;
994                 }
995             }
996         }
997 
998         if (volume_uuid.empty()) {
999             if (!prepare_dir_with_policy(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM, ce_policy))
1000                 return false;
1001             if (!prepare_dir_with_policy(vendor_ce_path, 0771, AID_ROOT, AID_ROOT, ce_policy))
1002                 return false;
1003         }
1004         if (!prepare_dir_with_policy(media_ce_path, 02770, AID_MEDIA_RW, AID_MEDIA_RW, ce_policy))
1005             return false;
1006         // On devices without sdcardfs (kernel 5.4+), the path permissions aren't fixed
1007         // up automatically; therefore, use a default ACL, to ensure apps with MEDIA_RW
1008         // can keep reading external storage; in particular, this allows app cloning
1009         // scenarios to work correctly on such devices.
1010         int ret = SetDefaultAcl(media_ce_path, 02770, AID_MEDIA_RW, AID_MEDIA_RW, {AID_MEDIA_RW});
1011         if (ret != android::OK) {
1012             return false;
1013         }
1014         if (!prepare_dir_with_policy(misc_ce_path, 01771, AID_SYSTEM, AID_MISC, ce_policy))
1015             return false;
1016         if (!prepare_dir_with_policy(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM, ce_policy))
1017             return false;
1018 
1019         if (volume_uuid.empty()) {
1020             // Now that credentials have been installed, we can run restorecon
1021             // over these paths
1022             // NOTE: these paths need to be kept in sync with libselinux
1023             android::vold::RestoreconRecursive(system_ce_path);
1024             android::vold::RestoreconRecursive(vendor_ce_path);
1025             android::vold::RestoreconRecursive(misc_ce_path);
1026         }
1027     }
1028     if (!prepare_subdirs("prepare", volume_uuid, user_id, flags)) return false;
1029 
1030     return true;
1031 }
1032 
fscrypt_destroy_user_storage(const std::string & volume_uuid,userid_t user_id,int flags)1033 bool fscrypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags) {
1034     LOG(DEBUG) << "fscrypt_destroy_user_storage for volume " << escape_empty(volume_uuid)
1035                << ", user " << user_id << ", flags " << flags;
1036     bool res = true;
1037 
1038     res &= prepare_subdirs("destroy", volume_uuid, user_id, flags);
1039 
1040     if (flags & android::os::IVold::STORAGE_FLAG_CE) {
1041         // CE_n key
1042         auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
1043         auto misc_ce_path = android::vold::BuildDataMiscCePath(volume_uuid, user_id);
1044         auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
1045         auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
1046         auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
1047 
1048         res &= destroy_dir(media_ce_path);
1049         res &= destroy_dir(misc_ce_path);
1050         res &= destroy_dir(user_ce_path);
1051         if (volume_uuid.empty()) {
1052             res &= destroy_dir(system_ce_path);
1053             res &= destroy_dir(vendor_ce_path);
1054         } else {
1055             if (IsFbeEnabled()) {
1056                 auto misc_ce_empty_volume_path = android::vold::BuildDataMiscCePath("", user_id);
1057                 res &= destroy_volkey(misc_ce_empty_volume_path, volume_uuid);
1058             }
1059         }
1060     }
1061 
1062     if (flags & android::os::IVold::STORAGE_FLAG_DE) {
1063         // DE_sys key
1064         auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id);
1065         auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id);
1066         auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
1067 
1068         // DE_n key
1069         auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
1070         auto misc_de_path = android::vold::BuildDataMiscDePath(volume_uuid, user_id);
1071         auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
1072         auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
1073 
1074         res &= destroy_dir(user_de_path);
1075         res &= destroy_dir(misc_de_path);
1076         if (volume_uuid.empty()) {
1077             res &= destroy_dir(system_legacy_path);
1078 #if MANAGE_MISC_DIRS
1079             res &= destroy_dir(misc_legacy_path);
1080 #endif
1081             res &= destroy_dir(profiles_de_path);
1082             res &= destroy_dir(system_de_path);
1083             res &= destroy_dir(vendor_de_path);
1084         } else {
1085             if (IsFbeEnabled()) {
1086                 auto misc_de_empty_volume_path = android::vold::BuildDataMiscDePath("", user_id);
1087                 res &= destroy_volkey(misc_de_empty_volume_path, volume_uuid);
1088             }
1089         }
1090     }
1091 
1092     return res;
1093 }
1094 
destroy_volume_keys(const std::string & directory_path,const std::string & volume_uuid)1095 static bool destroy_volume_keys(const std::string& directory_path, const std::string& volume_uuid) {
1096     auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(directory_path.c_str()), closedir);
1097     if (!dirp) {
1098         PLOG(ERROR) << "Unable to open directory: " + directory_path;
1099         return false;
1100     }
1101     bool res = true;
1102     for (;;) {
1103         errno = 0;
1104         auto const entry = readdir(dirp.get());
1105         if (!entry) {
1106             if (errno) {
1107                 PLOG(ERROR) << "Unable to read directory: " + directory_path;
1108                 return false;
1109             }
1110             break;
1111         }
1112         if (IsDotOrDotDot(*entry)) continue;
1113         if (entry->d_type != DT_DIR || entry->d_name[0] == '.') {
1114             LOG(DEBUG) << "Skipping non-user " << entry->d_name;
1115             continue;
1116         }
1117         res &= destroy_volkey(directory_path + "/" + entry->d_name, volume_uuid);
1118     }
1119     return res;
1120 }
1121 
fscrypt_destroy_volume_keys(const std::string & volume_uuid)1122 bool fscrypt_destroy_volume_keys(const std::string& volume_uuid) {
1123     bool res = true;
1124     LOG(DEBUG) << "fscrypt_destroy_volume_keys for volume " << escape_empty(volume_uuid);
1125     auto secdiscardable_path = volume_secdiscardable_path(volume_uuid);
1126     res &= android::vold::runSecdiscardSingle(secdiscardable_path);
1127     res &= destroy_volume_keys("/data/misc_ce", volume_uuid);
1128     res &= destroy_volume_keys("/data/misc_de", volume_uuid);
1129     return res;
1130 }
1131