summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPat Erley <perley@cyngn.com>2016-01-13 11:37:39 -0800
committerGerrit Code Review <gerrit@cyanogenmod.org>2016-01-28 15:20:24 -0800
commitc7610f2aee2291584d92cad2184a34f4402ea000 (patch)
treecbdb27a06e1a0ec5f5533d379d9d12d9f88e60ab
parentacfc03463b7fca50f6b176fb1d10aa735aeb2c9d (diff)
downloadbootable_recovery-c7610f2aee2291584d92cad2184a34f4402ea000.zip
bootable_recovery-c7610f2aee2291584d92cad2184a34f4402ea000.tar.gz
bootable_recovery-c7610f2aee2291584d92cad2184a34f4402ea000.tar.bz2
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
-rw-r--r--roots.cpp28
-rw-r--r--roots.h2
2 files changed, 30 insertions, 0 deletions
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);