From c7610f2aee2291584d92cad2184a34f4402ea000 Mon Sep 17 00:00:00 2001 From: Pat Erley Date: Wed, 13 Jan 2016 11:37:39 -0800 Subject: recovery: Fix recursive rm wipe of data Android 6 re-introduced MCS/MLS SELinux contexts. Unforunately, this broke our previous SELinux model for walking /data and unlinking everything but media. Fix this by mounting /data with a temporary SELinux context that works with the previous model. Ticket: CYNGNOS-1747 Change-Id: Id87ad3bb357102c3a8bd7c1417183d788ef858a0 --- roots.cpp | 28 ++++++++++++++++++++++++++++ roots.h | 2 ++ 2 files changed, 30 insertions(+) diff --git a/roots.cpp b/roots.cpp index ceafed9..4586c42 100644 --- a/roots.cpp +++ b/roots.cpp @@ -253,6 +253,32 @@ int ensure_volume_mounted(Volume* v, bool force_rw) { return ensure_path_mounted_at(v->mount_point, nullptr, force_rw); } +int remount_for_wipe(const char* path) { + int ret; + + char *old_fs_options; + char *new_fs_options; + + char se_context[] = ",context=u:object_r:app_data_file:s0"; + Volume *v; + + // Backup original mount options + v = volume_for_path(path); + old_fs_options = v->fs_options; + + // Add SELinux mount override + asprintf(&new_fs_options, "%s%s", v->fs_options, se_context); + + ensure_path_unmounted(path); + ret = ensure_path_mounted(path); + + // Restore original mount options + v->fs_options = old_fs_options; + free(new_fs_options); + + return ret; +} + int ensure_path_mounted(const char* path, bool force_rw) { // Mount at the default mount point. return ensure_path_mounted_at(path, nullptr, force_rw); @@ -379,6 +405,7 @@ int format_volume(const char* volume, bool force) { LOGE("format_volume failed to mount /data\n"); return -1; } + remount_for_wipe("/data"); int rc = 0; rc = rmtree_except("/data/media", NULL); ensure_path_unmounted("/data"); @@ -402,6 +429,7 @@ int format_volume(const char* volume, bool force) { if (!force && strcmp(volume, "/data") == 0 && vdc->isEmulatedStorage()) { if (ensure_path_mounted("/data") == 0) { + remount_for_wipe("/data"); // Preserve .layout_version to avoid "nesting bug" LOGI("Preserving layout version\n"); unsigned char layout_buf[256]; diff --git a/roots.h b/roots.h index addb142..2140363 100644 --- a/roots.h +++ b/roots.h @@ -30,6 +30,8 @@ Volume* volume_for_path(const char* path); // success (volume is mounted). int ensure_volume_mounted(Volume* v, bool force_rw=false); int ensure_path_mounted(const char* path, bool force_rw=false); +// Above, plus override SELinux default context +int remount_for_wipe(const char* path); // Similar to ensure_path_mounted, but allows one to specify the mount_point. int ensure_path_mounted_at(const char* path, const char* mount_point, bool force_rw=false); -- cgit v1.1