146 lines
3.9 KiB
C++
146 lines
3.9 KiB
C++
/*
|
|
Copyright 2012-2016 bigbiff/Dees_Troy TeamWin
|
|
This file is part of TWRP/TeamWin Recovery Project.
|
|
|
|
TWRP is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
TWRP is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with TWRP. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <string>
|
|
#include <unistd.h>
|
|
#include <sys/stat.h>
|
|
#include <dirent.h>
|
|
#include <errno.h>
|
|
#include <cctype>
|
|
#include "fixContexts.hpp"
|
|
#include "twrp-functions.hpp"
|
|
#include "twcommon.h"
|
|
#include <selinux/selinux.h>
|
|
#include <selinux/label.h>
|
|
#include <selinux/android.h>
|
|
#include <selinux/label.h>
|
|
|
|
using namespace std;
|
|
|
|
struct selabel_handle *sehandle;
|
|
struct selinux_opt selinux_options[] = {
|
|
{ SELABEL_OPT_PATH, "/file_contexts" }
|
|
};
|
|
|
|
int fixContexts::restorecon(string entry, struct stat *sb) {
|
|
char *oldcontext, *newcontext;
|
|
|
|
if (lgetfilecon(entry.c_str(), &oldcontext) < 0) {
|
|
LOGINFO("Couldn't get selinux context for %s\n", entry.c_str());
|
|
return -1;
|
|
}
|
|
if (selabel_lookup(sehandle, &newcontext, entry.c_str(), sb->st_mode) < 0) {
|
|
LOGINFO("Couldn't lookup selinux context for %s\n", entry.c_str());
|
|
return -1;
|
|
}
|
|
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);
|
|
return 0;
|
|
}
|
|
|
|
int fixContexts::fixContextsRecursively(string name, int level) {
|
|
DIR *d;
|
|
struct dirent *de;
|
|
struct stat sb;
|
|
string path;
|
|
|
|
if (!(d = opendir(name.c_str())))
|
|
return -1;
|
|
if (!(de = readdir(d)))
|
|
return -1;
|
|
|
|
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;
|
|
}
|
|
|
|
int fixContexts::fixDataMediaContexts(string Mount_Point) {
|
|
DIR *d;
|
|
struct dirent *de;
|
|
struct stat sb;
|
|
|
|
LOGINFO("Fixing media contexts on '%s'\n", Mount_Point.c_str());
|
|
|
|
sehandle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1);
|
|
if (!sehandle) {
|
|
LOGINFO("Unable to open /file_contexts\n");
|
|
return 0;
|
|
}
|
|
|
|
if (TWFunc::Path_Exists(Mount_Point + "/media/0")) {
|
|
string dir = Mount_Point + "/media";
|
|
if (!(d = opendir(dir.c_str()))) {
|
|
LOGINFO("opendir failed (%s)\n", strerror(errno));
|
|
return -1;
|
|
}
|
|
if (!(de = readdir(d))) {
|
|
LOGINFO("readdir failed (%s)\n", strerror(errno));
|
|
closedir(d);
|
|
return -1;
|
|
}
|
|
|
|
do {
|
|
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0 || de->d_type != DT_DIR)
|
|
continue;
|
|
size_t len = strlen(de->d_name);
|
|
bool is_numeric = true;
|
|
char* folder_name = de->d_name;
|
|
for (size_t i = 0; i < len; i++) {
|
|
if (!isdigit(*folder_name)) {
|
|
is_numeric = false;
|
|
break;
|
|
}
|
|
folder_name++;
|
|
}
|
|
if (is_numeric) {
|
|
dir = Mount_Point + "/media/";
|
|
dir += de->d_name;
|
|
restorecon(dir, &sb);
|
|
fixContextsRecursively(dir, 0);
|
|
}
|
|
} while ((de = readdir(d)));
|
|
closedir(d);
|
|
} else if (TWFunc::Path_Exists(Mount_Point + "/media")) {
|
|
restorecon(Mount_Point + "/media", &sb);
|
|
fixContextsRecursively(Mount_Point + "/media", 0);
|
|
} else {
|
|
LOGINFO("fixDataMediaContexts: %s/media does not exist!\n", Mount_Point.c_str());
|
|
return 0;
|
|
}
|
|
selabel_close(sehandle);
|
|
return 0;
|
|
}
|