Fix selinux context on Magisk files

This commit is contained in:
topjohnwu 2017-10-12 03:39:39 +08:00
parent 25bdbcf526
commit fe4b3df7e9
5 changed files with 57 additions and 8 deletions

View File

@ -396,7 +396,7 @@ static void simple_mount(const char *path) {
*****************/
// A one time setup
void daemon_init() {
static void daemon_init() {
LOGI("* Creating /sbin overlay");
DIR *dir;
struct dirent *entry;
@ -493,6 +493,12 @@ void daemon_init() {
}
static int prepare_img() {
// First merge images
if (merge_img("/data/magisk_merge.img", MAINIMG)) {
LOGE("Image merge %s -> %s failed!\n", "/data/magisk_merge.img", MAINIMG);
return 1;
}
if (access(MAINIMG, F_OK) == -1) {
if (create_img(MAINIMG, 64))
return 1;
@ -544,9 +550,20 @@ static int prepare_img() {
magiskloop = mount_image(MAINIMG, MOUNTPOINT);
free(magiskloop);
// Fix file seliux contexts
fix_filecon();
return 0;
}
void fix_filecon() {
int dirfd = xopen(MOUNTPOINT, O_RDONLY | O_CLOEXEC);
restorecon(dirfd, 0);
close(dirfd);
dirfd = xopen(DATABIN, O_RDONLY | O_CLOEXEC);
restorecon(dirfd, 1);
close(dirfd);
}
/****************
* Entry points *
****************/
@ -618,12 +635,6 @@ void post_fs_data(int client) {
// Initialize
daemon_init();
// Merge images
if (merge_img("/data/magisk_merge.img", MAINIMG)) {
LOGE("Image merge %s -> %s failed!\n", "/data/magisk_merge.img", MAINIMG);
goto unblock;
}
// uninstaller
if (access(UNINSTALLER, F_OK) == 0) {
close(open(UNBLOCKFILE, O_RDONLY | O_CREAT));
@ -632,7 +643,7 @@ void post_fs_data(int client) {
return;
}
// Trim, mount magisk.img, which will also travel through the modules
// Merge, trim, mount magisk.img, which will also travel through the modules
// After this, it will create the module list
if (prepare_img())
goto core_only; // Mounting fails, we can only do core only stuffs

View File

@ -56,6 +56,7 @@ static void usage() {
" --umountimg PATH LOOP unmount PATH and delete LOOP device\n"
" --[init service] start init service\n"
" --unlock-blocks set BLKROSET flag to OFF for all block devices\n"
" --restorecon fix selinux context on Magisk files and folders\n"
"\n"
"Supported init services:\n"
" daemon post-fs, post-fs-data, service\n"
@ -146,6 +147,9 @@ int main(int argc, char *argv[]) {
} else if (strcmp(argv[1], "--unlock-blocks") == 0) {
unlock_blocks();
return 0;
} else if (strcmp(argv[1], "--restorecon") == 0) {
fix_filecon();
return 0;
} else if (strcmp(argv[1], "--daemon") == 0) {
// Start daemon, this process won't return
start_daemon();

View File

@ -59,6 +59,7 @@ void write_string(int fd, const char* val);
void post_fs(int client);
void post_fs_data(int client);
void late_start(int client);
void fix_filecon();
/**************
* MagiskHide *

View File

@ -110,6 +110,7 @@ int setattrat(int dirfd, const char *pathname, struct file_attr *a);
int fsetattr(int fd, struct file_attr *a);
void fclone_attr(const int sourcefd, const int targetfd);
void clone_attr(const char *source, const char *target);
void restorecon(int dirfd, int force);
// img.c

View File

@ -270,3 +270,35 @@ void fclone_attr(const int sourcefd, const int targetfd) {
fgetattr(sourcefd, &a);
fsetattr(targetfd, &a);
}
#define UNLABEL_CON "u:object_r:unlabeled:s0"
#define SYSTEM_CON "u:object_r:system_file:s0"
void restorecon(int dirfd, int force) {
struct dirent *entry;
DIR *dir;
int fd;
char *con;
fgetfilecon(dirfd, &con);
if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
fsetfilecon(dirfd, SYSTEM_CON);
freecon(con);
dir = fdopendir(dirfd);
while ((entry = readdir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
if (entry->d_type == DT_DIR) {
fd = openat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
restorecon(fd, force);
} else {
fd = openat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC);
fgetfilecon(fd, &con);
if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
fsetfilecon(fd, SYSTEM_CON);
freecon(con);
}
close(fd);
}
}