Sync parent directory in storeKeyAtomically()
When an FBE or metadata encryption key is created, it's important that it be persisted to disk right away; otherwise the device may fail to boot after an unclean shutdown. storeKey() has the needed fsync()s. However, storeKeyAtomically() doesn't, as it doesn't fsync() the parent directory of key_path after it renames tmp_path to it. Two callers do fsync() the parent directory themselves, but others don't. E.g., the metadata encryption key doesn't get properly synced. Therefore, add the needed fsync() to storeKeyAtomically() so that it gets done for everyone. Also remove the now-unneeded fsync()s from the two callers that did it themselves. Change-Id: I342ebd94f0a3d2bf3a7a443c35b6bda0f12e1ab2
This commit is contained in:
parent
bd138dd08a
commit
3345a2a98c
5 changed files with 9 additions and 3 deletions
|
@ -463,7 +463,6 @@ bool fscrypt_initialize_systemwide_keys() {
|
|||
return false;
|
||||
LOG(INFO) << "Wrote per boot key reference to:" << per_boot_ref_filename;
|
||||
|
||||
if (!android::vold::FsyncDirectory(device_key_dir)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -705,7 +704,6 @@ static bool fscrypt_rewrap_user_key(userid_t user_id, int serial,
|
|||
if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
|
||||
if (!android::vold::storeKeyAtomically(ce_key_path, user_key_temp, store_auth, ce_key))
|
||||
return false;
|
||||
if (!android::vold::FsyncDirectory(directory_path)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -661,6 +661,7 @@ bool storeKeyAtomically(const std::string& key_path, const std::string& tmp_path
|
|||
PLOG(ERROR) << "Unable to move new key to location: " << key_path;
|
||||
return false;
|
||||
}
|
||||
if (!FsyncParentDirectory(key_path)) return false;
|
||||
LOG(DEBUG) << "Created key: " << key_path;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,8 @@ bool storeKey(const std::string& dir, const KeyAuthentication& auth, const KeyBu
|
|||
// Create a directory at the named path, and store "key" in it as storeKey
|
||||
// This version creates the key in "tmp_path" then atomically renames "tmp_path"
|
||||
// to "key_path" thereby ensuring that the key is either stored entirely or
|
||||
// not at all.
|
||||
// not at all. All the needed files and directories are also fsync'ed to ensure
|
||||
// that the key is actually persisted to disk.
|
||||
bool storeKeyAtomically(const std::string& key_path, const std::string& tmp_path,
|
||||
const KeyAuthentication& auth, const KeyBuffer& key);
|
||||
|
||||
|
|
|
@ -1371,6 +1371,10 @@ bool FsyncDirectory(const std::string& dirname) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FsyncParentDirectory(const std::string& path) {
|
||||
return FsyncDirectory(android::base::Dirname(path));
|
||||
}
|
||||
|
||||
bool writeStringToFile(const std::string& payload, const std::string& filename) {
|
||||
android::base::unique_fd fd(TEMP_FAILURE_RETRY(
|
||||
open(filename.c_str(), O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC | O_CLOEXEC, 0666)));
|
||||
|
|
2
Utils.h
2
Utils.h
|
@ -183,6 +183,8 @@ bool pathExists(const std::string& path);
|
|||
|
||||
bool FsyncDirectory(const std::string& dirname);
|
||||
|
||||
bool FsyncParentDirectory(const std::string& path);
|
||||
|
||||
bool writeStringToFile(const std::string& payload, const std::string& filename);
|
||||
|
||||
void ConfigureMaxDirtyRatioForFuse(const std::string& fuse_mount, unsigned int max_ratio);
|
||||
|
|
Loading…
Reference in a new issue