From 6b600f964471cef977821689185db687f67d2c19 Mon Sep 17 00:00:00 2001 From: bigbiff bigbiff Date: Sun, 5 Jan 2014 18:13:43 -0500 Subject: Restore contexts when doing mkdierhier in libtar Do a restore of loaded file contexts to /data/media directory. This will help denials to be prevented when internal storage is wiped. Change-Id: Ie49bbfa48d2f3ee4f08376d9c1877b92c051017c --- fixPermissions.cpp | 33 ++++++++++++++++++++++++++++++++- fixPermissions.hpp | 5 +++-- libtar/extract.c | 5 ++++- libtar/wrapper.c | 6 ------ partition.cpp | 15 +++++++++++++++ 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/fixPermissions.cpp b/fixPermissions.cpp index 40ac516b0..12ce0b528 100644 --- a/fixPermissions.cpp +++ b/fixPermissions.cpp @@ -74,18 +74,48 @@ int fixPermissions::fixDataDataContexts(void) { struct selinux_opt selinux_options[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; + selinux_handle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1); + if (!selinux_handle) printf("No file contexts for SELinux\n"); else printf("SELinux contexts loaded from /file_contexts\n"); + d = opendir("/data/data"); + while (( de = readdir(d)) != NULL) { stat(de->d_name, &sb); string f = "/data/data/"; f = f + de->d_name; restorecon(f, &sb); } + closedir(d); + return 0; +} + +int fixPermissions::fixDataInternalContexts(void) { + DIR *d; + struct dirent *de; + struct stat sb; + string dir; + + if (TWFunc::Path_Exists("/data/media")) { + dir = "/data/media"; + } + else { + dir = "/data/media/0"; + } + LOGINFO("Fixing %s contexts\n", dir.c_str()); + d = opendir(dir.c_str()); + + while (( de = readdir(d)) != NULL) { + stat(de->d_name, &sb); + string f; + f = dir + de->d_name; + restorecon(f, &sb); + } + closedir(d); return 0; } #endif @@ -173,8 +203,9 @@ int fixPermissions::fixPerms(bool enable_debug, bool remove_data_for_missing_app } } #ifdef HAVE_SELINUX - gui_print("Fixing /data/data contexts.\n"); + gui_print("Fixing /data/data/ contexts.\n"); fixDataDataContexts(); + fixDataInternalContexts(); #endif gui_print("Done fixing permissions.\n"); return 0; diff --git a/fixPermissions.hpp b/fixPermissions.hpp index 6439dac60..48a52074e 100644 --- a/fixPermissions.hpp +++ b/fixPermissions.hpp @@ -17,6 +17,7 @@ using namespace std; class fixPermissions { public: int fixPerms(bool enable_debug, bool remove_data_for_missing_apps); + int fixDataInternalContexts(void); private: int pchown(std::string fn, int puid, int pgid); @@ -28,8 +29,8 @@ class fixPermissions { int fixDataApps(); int fixAllFiles(string directory, int gid, int uid, string file_perms); int fixDataData(string dataDir); - int fixDataDataContexts(void); int restorecon(std::string entry, struct stat *sb); + int fixDataDataContexts(void); struct package { string pkgName; @@ -45,6 +46,6 @@ class fixPermissions { bool remove_data; bool multi_user; package* head; - package* temp; + package* temp; string packageFile; }; diff --git a/libtar/extract.c b/libtar/extract.c index 8081aa2b9..d9ab7882f 100644 --- a/libtar/extract.c +++ b/libtar/extract.c @@ -159,11 +159,14 @@ tar_extract_file(TAR *t, char *realname, char *prefix) if((t->options & TAR_STORE_SELINUX) && t->th_buf.selinux_context != NULL) { #ifdef DEBUG - printf(" Restoring SELinux context %s to file %s\n", t->th_buf.selinux_context, realname); + printf(" Restoring SELinux context %s to file %s\n", t->th_buf.selinux_context, realname); #endif if (lsetfilecon(realname, t->th_buf.selinux_context) < 0) { fprintf(stderr, "Failed to restore SELinux context %s!\n", strerror(errno)); } + if (lsetfilecon(dirname(realname), t->th_buf.selinux_context) < 0) { + fprintf(stderr, "Failed to restore SELinux context %s!\n", strerror(errno)); + } } #endif diff --git a/libtar/wrapper.c b/libtar/wrapper.c index dab7e0076..708c845b9 100644 --- a/libtar/wrapper.c +++ b/libtar/wrapper.c @@ -80,12 +80,6 @@ tar_extract_all(TAR *t, char *prefix) "\"%s\")\n", buf); #endif printf("item name: '%s'\n", filename); - /* - if (strcmp(filename, "/") == 0) { - printf("skipping /\n"); - continue; - } - */ if (tar_extract_file(t, buf, prefix) != 0) return -1; } diff --git a/partition.cpp b/partition.cpp index 95f6bcac4..974f7e4a5 100644 --- a/partition.cpp +++ b/partition.cpp @@ -40,6 +40,7 @@ #include "twrpDigest.hpp" #include "twrpTar.hpp" #include "twrpDU.hpp" +#include "fixPermissions.hpp" extern "C" { #include "mtdutils/mtdutils.h" #include "mtdutils/mounts.h" @@ -1511,6 +1512,9 @@ bool TWPartition::Wipe_F2FS() { bool TWPartition::Wipe_Data_Without_Wiping_Media() { string dir; + #ifdef HAVE_SELINUX + fixPermissions perms; + #endif // This handles wiping data on devices with "sdcard" in /data/media if (!Mount(true)) @@ -1541,6 +1545,10 @@ bool TWPartition::Wipe_Data_Without_Wiping_Media() { } closedir(d); + #ifdef HAVE_SELINUX + perms.fixDataInternalContexts(); + #endif + gui_print("Done.\n"); return true; } @@ -1811,12 +1819,19 @@ void TWPartition::Find_Actual_Block_Device(void) { void TWPartition::Recreate_Media_Folder(void) { string Command; + #ifdef HAVE_SELINUX + fixPermissions perms; + #endif + if (!Mount(true)) { LOGERR("Unable to recreate /data/media folder.\n"); } else if (!TWFunc::Path_Exists("/data/media")) { PartitionManager.Mount_By_Path(Symlink_Mount_Point, true); LOGINFO("Recreating /data/media folder.\n"); mkdir("/data/media", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + #ifdef HAVE_SELINUX + perms.fixDataInternalContexts(); + #endif PartitionManager.UnMount_By_Path(Symlink_Mount_Point, true); } } -- cgit v1.2.3