From 8e5506684590f4656073224546543366bf382241 Mon Sep 17 00:00:00 2001 From: Paul Crowley Date: Mon, 16 Oct 2017 17:01:44 -0700 Subject: [PATCH] Recursively delete subdirs when deleting Use vold_prepare_subdirs since only it has the privilege needed. Bug: 25861755 Test: Boot device, create user, create files, remove user, observe logs Change-Id: I90fb2517ccd177c9b009001e7a2b00f537152f8c --- Ext4Crypt.cpp | 68 ++++++++++++++++++++++++-------------------- vold_prepare_subdirs | 49 ++++++++++++++++++++++--------- 2 files changed, 73 insertions(+), 44 deletions(-) diff --git a/Ext4Crypt.cpp b/Ext4Crypt.cpp index 1a84e30..646a032 100644 --- a/Ext4Crypt.cpp +++ b/Ext4Crypt.cpp @@ -594,6 +594,18 @@ bool e4crypt_lock_user_key(userid_t user_id) { return true; } +static bool prepare_subdirs(const std::string& action, const std::string& dirtype, + const std::string& volume_uuid, userid_t user_id, + const std::string& path) { + if (0 != android::vold::ForkExecvp(std::vector{"/system/bin/vold_prepare_subdirs", + action, dirtype, volume_uuid, + std::to_string(user_id), path})) { + LOG(ERROR) << "vold_prepare_subdirs failed on: " << path; + return false; + } + return true; +} + bool e4crypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial, int flags) { LOG(DEBUG) << "e4crypt_prepare_user_storage for volume " << escape_empty(volume_uuid) @@ -634,12 +646,8 @@ bool e4crypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_ } if (volume_uuid.empty()) { - if (0 != android::vold::ForkExecvp( - std::vector{"/system/bin/vold_prepare_subdirs", "misc_de", - misc_de_path, std::to_string(user_id), ""})) { - LOG(ERROR) << "vold_prepare_subdirs failed on: " << misc_de_path; + if (!prepare_subdirs("prepare", "misc_de", volume_uuid, user_id, misc_de_path)) return false; - } } } @@ -664,23 +672,19 @@ bool e4crypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_ if (!ensure_policy(ce_raw_ref, system_ce_path)) return false; if (!ensure_policy(ce_raw_ref, misc_ce_path)) return false; - // Now that credentials have been installed, we can run restorecon - // over these paths - // NOTE: these paths need to be kept in sync with libselinux - android::vold::RestoreconRecursive(system_ce_path); - android::vold::RestoreconRecursive(misc_ce_path); } if (!ensure_policy(ce_raw_ref, media_ce_path)) return false; if (!ensure_policy(ce_raw_ref, user_ce_path)) return false; } if (volume_uuid.empty()) { - if (0 != android::vold::ForkExecvp( - std::vector{"/system/bin/vold_prepare_subdirs", "misc_ce", - misc_ce_path, std::to_string(user_id), ""})) { - LOG(ERROR) << "vold_prepare_subdirs failed on: " << misc_ce_path; + if (!prepare_subdirs("prepare", "misc_ce", volume_uuid, user_id, misc_ce_path)) return false; - } + // Now that credentials have been installed, we can run restorecon + // over these paths + // NOTE: these paths need to be kept in sync with libselinux + android::vold::RestoreconRecursive(system_ce_path); + android::vold::RestoreconRecursive(misc_ce_path); } } @@ -692,6 +696,22 @@ bool e4crypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_ << ", user " << user_id << ", flags " << flags; bool res = true; + if (flags & FLAG_STORAGE_CE) { + // CE_n key + auto system_ce_path = android::vold::BuildDataSystemCePath(user_id); + auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id); + auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id); + auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id); + + res &= destroy_dir(media_ce_path); + res &= destroy_dir(user_ce_path); + if (volume_uuid.empty()) { + res &= prepare_subdirs("destroy", "misc_ce", volume_uuid, user_id, misc_ce_path); + res &= destroy_dir(system_ce_path); + res &= destroy_dir(misc_ce_path); + } + } + if (flags & FLAG_STORAGE_DE) { // DE_sys key auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id); @@ -703,7 +723,9 @@ bool e4crypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_ auto misc_de_path = android::vold::BuildDataMiscDePath(user_id); auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id); + res &= destroy_dir(user_de_path); if (volume_uuid.empty()) { + res &= prepare_subdirs("destroy", "misc_de", volume_uuid, user_id, misc_de_path); res &= destroy_dir(system_legacy_path); #if MANAGE_MISC_DIRS res &= destroy_dir(misc_legacy_path); @@ -712,22 +734,6 @@ bool e4crypt_destroy_user_storage(const std::string& volume_uuid, userid_t user_ res &= destroy_dir(system_de_path); res &= destroy_dir(misc_de_path); } - res &= destroy_dir(user_de_path); - } - - if (flags & FLAG_STORAGE_CE) { - // CE_n key - auto system_ce_path = android::vold::BuildDataSystemCePath(user_id); - auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id); - auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id); - auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id); - - if (volume_uuid.empty()) { - res &= destroy_dir(system_ce_path); - res &= destroy_dir(misc_ce_path); - } - res &= destroy_dir(media_ce_path); - res &= destroy_dir(user_ce_path); } return res; diff --git a/vold_prepare_subdirs b/vold_prepare_subdirs index f436ca2..cdea243 100644 --- a/vold_prepare_subdirs +++ b/vold_prepare_subdirs @@ -14,31 +14,54 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +# Set up or tear down subdirectories of vold-created directories. +# +# This is kept separate from vold because under the SELinux rules, it has privileges vold doesn't +# have. In particular, prepare_dir sets SELinux labels on subdirectories based on file_contexts, +# so this script has some relabelling privileges. -case "$3" in - *[!0-9]* | '') - echo "Invalid user id" - exit -1 - ;; + +set -e +action="$1" +dirtype="$2" +volume_uuid="$3" +user_id="$4" +path="$5" + +case "$user_id" in + *[!0-9]* | '') + echo "Invalid user id" + exit -1 + ;; esac -if [ x"$4" != x ] ; then +if [ x"$volume_uuid" != x ] ; then echo "Volume must be root volume" exit -1; fi -case "$1" in +case "$dirtype" in misc_de|misc_ce) - computed_path="/data/$1/$3" - if [ x"$computed_path" != x"$2" ] ; then + computed_path="/data/$dirtype/$user_id" + if [ x"$computed_path" != x"$path" ] ; then echo "Parameter path didn't match computed path: " $computed_path exit -1; fi - /system/bin/prepare_dir --mode 700 --uid 0 --gid 0 -- "$computed_path"/vold + case "$action" in + prepare) + /system/bin/prepare_dir --mode 700 --uid 0 --gid 0 -- "$computed_path"/vold + ;; + destroy) + rm -rf "$computed_path"/* + ;; + *) + echo "Unknown action: $action" + exit -1 + ;; + esac ;; *) - echo "Unknown type: $1" - exit -1; + echo "Unknown type: $dirtype" + exit -1 ;; esac