Add IVold::destroyDsuMetadataKey()
destroyDsuMetadataKey() / destroy_dsu_metadata_key() calls
android::gsi::GetDsuMetadataKeyDir() to query the DSU metadata
encryption key dir and destroy the key.
This releases the resource and allows consecutive DSU installations to
use the same key *directory*, but not the same key *blob*.
Bug: 168571434
Test: 1. Install a DSU system.
2. Boot the DSU system and reboot back to the host system.
3. Wipe the DSU installation.
4. DSU metadata key dir /metadata/vold/metadata_encryption/dsu/dsu is
destroyed.
Change-Id: Ib851177315a5a266807f46ccfd446de1848232cf
diff --git a/MetadataCrypt.cpp b/MetadataCrypt.cpp
index c61132c..52add4a 100644
--- a/MetadataCrypt.cpp
+++ b/MetadataCrypt.cpp
@@ -35,6 +35,7 @@
#include <cutils/fs.h>
#include <fs_mgr.h>
#include <libdm/dm.h>
+#include <libgsi/libgsi.h>
#include "Checkpoint.h"
#include "CryptoType.h"
@@ -366,5 +367,44 @@
return create_crypto_blk_dev(label, blk_device, key, options, out_crypto_blkdev, &nr_sec);
}
+bool destroy_dsu_metadata_key(const std::string& dsu_slot) {
+ LOG(DEBUG) << "destroy_dsu_metadata_key: " << dsu_slot;
+
+ const auto dsu_metadata_key_dir = android::gsi::GetDsuMetadataKeyDir(dsu_slot);
+ if (!pathExists(dsu_metadata_key_dir)) {
+ LOG(DEBUG) << "DSU metadata_key_dir doesn't exist, nothing to remove: "
+ << dsu_metadata_key_dir;
+ return true;
+ }
+
+ // Ensure that the DSU key directory is different from the host OS'.
+ // Under normal circumstances, this should never happen, but handle it just in case.
+ if (auto data_rec = GetEntryForMountPoint(&fstab_default, "/data")) {
+ if (dsu_metadata_key_dir == data_rec->metadata_key_dir) {
+ LOG(ERROR) << "DSU metadata_key_dir is same as host OS: " << dsu_metadata_key_dir;
+ return false;
+ }
+ }
+
+ bool ok = true;
+ for (auto suffix : {"/key", "/tmp"}) {
+ const auto key_path = dsu_metadata_key_dir + suffix;
+ if (pathExists(key_path)) {
+ LOG(DEBUG) << "Destroy key: " << key_path;
+ if (!android::vold::destroyKey(key_path)) {
+ LOG(ERROR) << "Failed to destroyKey(): " << key_path;
+ ok = false;
+ }
+ }
+ }
+ if (!ok) {
+ return false;
+ }
+
+ LOG(DEBUG) << "Remove DSU metadata_key_dir: " << dsu_metadata_key_dir;
+ // DeleteDirContentsAndDir() already logged any error, so don't log repeatedly.
+ return android::vold::DeleteDirContentsAndDir(dsu_metadata_key_dir) == android::OK;
+}
+
} // namespace vold
} // namespace android