summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fixPermissions.cpp84
-rw-r--r--fixPermissions.hpp1
-rw-r--r--twrp-functions.cpp2
3 files changed, 53 insertions, 34 deletions
diff --git a/fixPermissions.cpp b/fixPermissions.cpp
index 12ce0b528..db6e90b52 100644
--- a/fixPermissions.cpp
+++ b/fixPermissions.cpp
@@ -42,13 +42,13 @@ using namespace std;
using namespace rapidxml;
#ifdef HAVE_SELINUX
+struct selabel_handle *sehandle;
+struct selinux_opt selinux_options[] = {
+ { SELABEL_OPT_PATH, "/file_contexts" }
+};
+
int fixPermissions::restorecon(string entry, struct stat *sb) {
char *oldcontext, *newcontext;
- struct selabel_handle *sehandle;
- struct selinux_opt selinux_options[] = {
- { SELABEL_OPT_PATH, "/file_contexts" }
- };
- sehandle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1);
if (lgetfilecon(entry.c_str(), &oldcontext) < 0) {
LOGINFO("Couldn't get selinux context for %s\n", entry.c_str());
return -1;
@@ -57,9 +57,11 @@ int fixPermissions::restorecon(string entry, struct stat *sb) {
LOGINFO("Couldn't lookup selinux context for %s\n", entry.c_str());
return -1;
}
- LOGINFO("Relabeling %s from %s to %s\n", entry.c_str(), oldcontext, newcontext);
- if (lsetfilecon(entry.c_str(), newcontext) < 0) {
- LOGINFO("Couldn't label %s with %s: %s\n", entry.c_str(), newcontext, strerror(errno));
+ if (strcmp(oldcontext, newcontext) != 0) {
+ LOGINFO("Relabeling %s from %s to %s\n", entry.c_str(), oldcontext, newcontext);
+ if (lsetfilecon(entry.c_str(), newcontext) < 0) {
+ LOGINFO("Couldn't label %s with %s: %s\n", entry.c_str(), newcontext, strerror(errno));
+ }
}
freecon(oldcontext);
freecon(newcontext);
@@ -67,29 +69,39 @@ int fixPermissions::restorecon(string entry, struct stat *sb) {
}
int fixPermissions::fixDataDataContexts(void) {
+ string dir = "/data/data/";
+ sehandle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1);
+ if (TWFunc::Path_Exists(dir)) {
+ fixContextsRecursively(dir, 0);
+ }
+ selabel_close(sehandle);
+ return 0;
+}
+
+int fixPermissions::fixContextsRecursively(string name, int level) {
DIR *d;
struct dirent *de;
struct stat sb;
- struct selabel_handle *selinux_handle;
- struct selinux_opt selinux_options[] = {
- { SELABEL_OPT_PATH, "/file_contexts" }
- };
+ string path;
- 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");
+ if (!(d = opendir(name.c_str())))
+ return -1;
+ if (!(de = readdir(d)))
+ return -1;
- while (( de = readdir(d)) != NULL) {
- stat(de->d_name, &sb);
- string f = "/data/data/";
- f = f + de->d_name;
- restorecon(f, &sb);
- }
+ do {
+ if (de->d_type == DT_DIR) {
+ if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
+ continue;
+ path = name + "/" + de->d_name;
+ restorecon(path, &sb);
+ fixContextsRecursively(path, level + 1);
+ }
+ else {
+ path = name + "/" + de->d_name;
+ restorecon(path, &sb);
+ }
+ } while (de = readdir(d));
closedir(d);
return 0;
}
@@ -98,24 +110,30 @@ int fixPermissions::fixDataInternalContexts(void) {
DIR *d;
struct dirent *de;
struct stat sb;
- string dir;
+ string dir, androiddir;
+ sehandle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1);
- if (TWFunc::Path_Exists("/data/media")) {
- dir = "/data/media";
- }
- else {
+ if (TWFunc::Path_Exists("/data/media/0"))
dir = "/data/media/0";
- }
+ else
+ dir = "/data/media";
LOGINFO("Fixing %s contexts\n", dir.c_str());
+ restorecon(dir, &sb);
d = opendir(dir.c_str());
while (( de = readdir(d)) != NULL) {
stat(de->d_name, &sb);
string f;
- f = dir + de->d_name;
+ f = dir + "/" + de->d_name;
restorecon(f, &sb);
}
closedir(d);
+
+ androiddir = dir + "/Android/";
+ if (TWFunc::Path_Exists(androiddir)) {
+ fixContextsRecursively(androiddir, 0);
+ }
+ selabel_close(sehandle);
return 0;
}
#endif
diff --git a/fixPermissions.hpp b/fixPermissions.hpp
index 48a52074e..e57d7bff3 100644
--- a/fixPermissions.hpp
+++ b/fixPermissions.hpp
@@ -31,6 +31,7 @@ class fixPermissions {
int fixDataData(string dataDir);
int restorecon(std::string entry, struct stat *sb);
int fixDataDataContexts(void);
+ int fixContextsRecursively(std::string path, int level);
struct package {
string pkgName;
diff --git a/twrp-functions.cpp b/twrp-functions.cpp
index 5145b2678..6c1f25f09 100644
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -79,7 +79,7 @@ int TWFunc::Exec_Cmd(const string& cmd) {
switch(pid = fork())
{
case -1:
- LOGERR("Exec_Cmd(): vfork failed!\n");
+ LOGERR("Exec_Cmd(): vfork failed: %d!\n", errno);
return -1;
case 0: // child
execl("/sbin/sh", "sh", "-c", cmd.c_str(), NULL);