From c6433a299df633c45d714a20fe3672b9b86d9312 Mon Sep 17 00:00:00 2001 From: Paul Crowley Date: Tue, 24 Oct 2017 14:54:43 -0700 Subject: [PATCH] Forget keys when we forget the volume. Bug: 25861755 Test: create a volume, forget it, check logs and filesystem. Change-Id: I0ab662969c51703cb046d57b72330e0f14447ef3 --- Ext4Crypt.cpp | 38 +++++++++++++++++++++++++++++++++++++- Ext4Crypt.h | 6 ++---- VolumeManager.cpp | 32 ++++++++++++++++++++------------ 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/Ext4Crypt.cpp b/Ext4Crypt.cpp index dc0f191..495a0fa 100644 --- a/Ext4Crypt.cpp +++ b/Ext4Crypt.cpp @@ -521,7 +521,9 @@ static bool read_or_create_volkey(const std::string& misc_path, const std::strin } static bool destroy_volkey(const std::string& misc_path, const std::string& volume_uuid) { - return android::vold::destroyKey(volkey_path(misc_path, volume_uuid)); + auto path = volkey_path(misc_path, volume_uuid); + if (!android::vold::pathExists(path)) return true; + return android::vold::destroyKey(path); } bool e4crypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token_hex, @@ -767,6 +769,40 @@ bool e4crypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_ return res; } +static bool destroy_volume_keys(const std::string& directory_path, const std::string& volume_uuid) { + auto dirp = std::unique_ptr(opendir(directory_path.c_str()), closedir); + if (!dirp) { + PLOG(ERROR) << "Unable to open directory: " + directory_path; + return false; + } + bool res = true; + for (;;) { + errno = 0; + auto const entry = readdir(dirp.get()); + if (!entry) { + if (errno) { + PLOG(ERROR) << "Unable to read directory: " + directory_path; + return false; + } + break; + } + if (entry->d_type != DT_DIR || entry->d_name[0] == '.') { + LOG(DEBUG) << "Skipping non-user " << entry->d_name; + continue; + } + res &= destroy_volkey(directory_path + "/" + entry->d_name, volume_uuid); + } + return res; +} + +bool e4crypt_destroy_volume_keys(const std::string& volume_uuid) { + bool res = true; + LOG(DEBUG) << "e4crypt_destroy_volume_keys for volume " << escape_empty(volume_uuid); + res &= destroy_volume_keys("/data/misc_ce", volume_uuid); + res &= destroy_volume_keys("/data/misc_de", volume_uuid); + return res; +} + bool e4crypt_secdiscard(const std::string& path) { return android::vold::runSecdiscardSingle(path); } diff --git a/Ext4Crypt.h b/Ext4Crypt.h index d0afd85..4226f15 100644 --- a/Ext4Crypt.h +++ b/Ext4Crypt.h @@ -16,12 +16,8 @@ #include -#include -#include - #include -// General functions bool e4crypt_initialize_global_de(); bool e4crypt_init_user0(); @@ -39,4 +35,6 @@ bool e4crypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_ int flags); bool e4crypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_id, int flags); +bool e4crypt_destroy_volume_keys(const std::string& volume_uuid); + bool e4crypt_secdiscard(const std::string& path); diff --git a/VolumeManager.cpp b/VolumeManager.cpp index 3194e59..f54fb00 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -48,18 +48,21 @@ #include -#include "model/EmulatedVolume.h" -#include "model/ObbVolume.h" -#include "VolumeManager.h" -#include "NetlinkManager.h" +#include + +#include "Devmapper.h" +#include "Ext4Crypt.h" #include "Loop.h" +#include "NetlinkManager.h" +#include "Process.h" +#include "Utils.h" +#include "VoldUtil.h" +#include "VolumeManager.h" +#include "cryptfs.h" #include "fs/Ext4.h" #include "fs/Vfat.h" -#include "Utils.h" -#include "Devmapper.h" -#include "Process.h" -#include "VoldUtil.h" -#include "cryptfs.h" +#include "model/EmulatedVolume.h" +#include "model/ObbVolume.h" using android::base::StringPrintf; using android::base::unique_fd; @@ -300,13 +303,18 @@ int VolumeManager::forgetPartition(const std::string& partGuid, const std::strin return -1; } + bool success = true; std::string keyPath = android::vold::BuildKeyPath(normalizedGuid); if (unlink(keyPath.c_str()) != 0) { LOG(ERROR) << "Failed to unlink " << keyPath; - return -1; + success = false; } - - return 0; + if (e4crypt_is_native()) { + if (!e4crypt_destroy_volume_keys(fsUuid)) { + success = false; + } + } + return success ? 0 : -1; } int VolumeManager::linkPrimary(userid_t userId) {