Massive sepolicy refactor

This commit is contained in:
topjohnwu 2018-04-15 03:18:18 +08:00
parent 9194c50590
commit 87f6018468
13 changed files with 71 additions and 112 deletions

2
app

@ -1 +1 @@
Subproject commit e79d764148a493aeb82fa590301a4301f662ff76 Subproject commit 6764a98409fac8da30218ec87b7f7e6fcfcef4c9

View File

@ -31,6 +31,7 @@ LOCAL_SHARED_LIBRARIES := libsqlite libselinux
LOCAL_C_INCLUDES := \ LOCAL_C_INCLUDES := \
jni/include \ jni/include \
jni/magiskpolicy \
$(EXT_PATH)/include \ $(EXT_PATH)/include \
$(LIBSELINUX) $(LIBSELINUX)
@ -74,7 +75,6 @@ LOCAL_C_INCLUDES := \
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
core/magiskinit.c \ core/magiskinit.c \
core/socket.c \
magiskpolicy/api.c \ magiskpolicy/api.c \
magiskpolicy/magiskpolicy.c \ magiskpolicy/magiskpolicy.c \
magiskpolicy/rules.c \ magiskpolicy/rules.c \

View File

@ -19,6 +19,7 @@
#include "utils.h" #include "utils.h"
#include "daemon.h" #include "daemon.h"
#include "resetprop.h" #include "resetprop.h"
#include "magiskpolicy.h"
static char *buf, *buf2; static char *buf, *buf2;
static struct vector module_list; static struct vector module_list;
@ -451,7 +452,7 @@ static int prepare_img() {
void fix_filecon() { void fix_filecon() {
int dirfd = xopen(MOUNTPOINT, O_RDONLY | O_CLOEXEC); int dirfd = xopen(MOUNTPOINT, O_RDONLY | O_CLOEXEC);
restorecon(dirfd, 0); restorecon(dirfd);
close(dirfd); close(dirfd);
} }
@ -621,8 +622,7 @@ void late_start(int client) {
if (buf2 == NULL) buf2 = xmalloc(PATH_MAX); if (buf2 == NULL) buf2 = xmalloc(PATH_MAX);
// Wait till the full patch is done // Wait till the full patch is done
wait_till_exists(PATCHDONE); waitpid(full_patch_pid, NULL, 0);
unlink(PATCHDONE);
// Run scripts after full patch, most reliable way to run scripts // Run scripts after full patch, most reliable way to run scripts
LOGI("* Running service.d scripts\n"); LOGI("* Running service.d scripts\n");
@ -639,7 +639,7 @@ core_only:
// Install Magisk Manager if exists // Install Magisk Manager if exists
if (access(MANAGERAPK, F_OK) == 0) { if (access(MANAGERAPK, F_OK) == 0) {
rename(MANAGERAPK, "/data/magisk.apk"); rename(MANAGERAPK, "/data/magisk.apk");
setfilecon("/data/magisk.apk", "u:object_r:su_file:s0"); setfilecon("/data/magisk.apk", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
while (1) { while (1) {
sleep(5); sleep(5);
LOGD("apk_install: attempting to install APK"); LOGD("apk_install: attempting to install APK");

View File

@ -19,8 +19,11 @@
#include "utils.h" #include "utils.h"
#include "daemon.h" #include "daemon.h"
#include "resetprop.h" #include "resetprop.h"
#include "magiskpolicy.h"
int is_daemon_init = 0, seperate_vendor = 0; int is_daemon_init = 0;
int seperate_vendor = 0;
int full_patch_pid;
static void *request_handler(void *args) { static void *request_handler(void *args) {
int client = *((int *) args); int client = *((int *) args);
@ -133,23 +136,50 @@ void daemon_init() {
LOGI("* Creating /sbin overlay"); LOGI("* Creating /sbin overlay");
DIR *dir; DIR *dir;
struct dirent *entry; struct dirent *entry;
int root, sbin; int root, sbin, fd;
char buf[PATH_MAX], buf2[PATH_MAX]; char buf[PATH_MAX], buf2[PATH_MAX];
char magisk_name[10], init_name[10]; void *data;
size_t size;
// Setup links under /sbin // Create hardlink mirror of /sbin to /root
xmount(NULL, "/", NULL, MS_REMOUNT, NULL); xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
xmkdir("/root", 0755); full_read("/sbin/magisk", &data, &size);
chmod("/root", 0755);
root = xopen("/root", O_RDONLY | O_CLOEXEC); root = xopen("/root", O_RDONLY | O_CLOEXEC);
sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC); sbin = xopen("/sbin", O_RDONLY | O_CLOEXEC);
link_dir(sbin, root); link_dir(sbin, root);
unlink("/sbin/magisk"); unlink("/sbin/magisk");
close(sbin); close(sbin);
// Mount the /sbin tmpfs overlay
xmount("tmpfs", "/sbin", "tmpfs", 0, NULL); xmount("tmpfs", "/sbin", "tmpfs", 0, NULL);
chmod("/sbin", 0755); chmod("/sbin", 0755);
setfilecon("/sbin", "u:object_r:rootfs:s0"); setfilecon("/sbin", "u:object_r:rootfs:s0");
// Setup magisk
fd = creat("/sbin/magisk", 0755);
xwrite(fd, data, size);
close(fd);
free(data);
setfilecon("/sbin/magisk", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
for (int i = 0; applet[i]; ++i) {
snprintf(buf, PATH_MAX, "/sbin/%s", applet[i]);
xsymlink("/sbin/magisk", buf);
}
// Setup magiskinit
full_read("/root/magiskinit", &data, &size);
unlink("/root/magiskinit");
fd = creat("/sbin/magiskinit", 0755);
xwrite(fd, data, size);
close(fd);
free(data);
setfilecon("/sbin/magiskinit", "u:object_r:"SEPOL_FILE_DOMAIN":s0");
for (int i = 0; init_applet[i]; ++i) {
snprintf(buf, PATH_MAX, "/sbin/%s", init_applet[i]);
xsymlink("/sbin/magiskinit", buf);
}
// Create symlinks pointing back to /root
dir = xfdopendir(root); dir = xfdopendir(root);
while((entry = xreaddir(dir))) { while((entry = xreaddir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
@ -158,29 +188,11 @@ void daemon_init() {
xsymlink(buf, buf2); xsymlink(buf, buf2);
} }
gen_rand_str(magisk_name, sizeof(magisk_name));
snprintf(buf, PATH_MAX, "/root/%s", magisk_name);
unlink("/sbin/magisk");
rename("/root/magisk", buf);
xsymlink(buf, "/sbin/magisk");
for (int i = 0; applet[i]; ++i) {
snprintf(buf2, PATH_MAX, "/sbin/%s", applet[i]);
xsymlink(buf, buf2);
}
gen_rand_str(init_name, sizeof(init_name));
snprintf(buf, PATH_MAX, "/root/%s", init_name);
unlink("/sbin/magiskinit");
rename("/root/magiskinit", buf);
for (int i = 0; init_applet[i]; ++i) {
snprintf(buf2, PATH_MAX, "/sbin/%s", init_applet[i]);
xsymlink(buf, buf2);
}
close(root); close(root);
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL); xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
full_patch_pid = exec_command(0, NULL, NULL, "/sbin/magiskpolicy", "--live", "allow "SEPOL_PROC_DOMAIN" * * *", NULL);
LOGI("* Mounting mirrors"); LOGI("* Mounting mirrors");
struct vector mounts; struct vector mounts;
vec_init(&mounts); vec_init(&mounts);
@ -239,7 +251,7 @@ void daemon_init() {
void start_daemon() { void start_daemon() {
setsid(); setsid();
setcon("u:r:su:s0"); setcon("u:r:"SEPOL_PROC_DOMAIN":s0");
umask(0); umask(0);
int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC); int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC);
xdup2(fd, STDIN_FILENO); xdup2(fd, STDIN_FILENO);

View File

@ -339,7 +339,7 @@ static void patch_socket_name(const char *path) {
mmap_rw(path, &buf, &size); mmap_rw(path, &buf, &size);
if (SOCKET_OFF < 0) { if (SOCKET_OFF < 0) {
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
if (memcmp(buf + i, socket_name, sizeof(SOCKET_NAME)) == 0) { if (memcmp(buf + i, SOCKET_NAME, sizeof(SOCKET_NAME)) == 0) {
SOCKET_OFF = i; SOCKET_OFF = i;
break; break;
} }
@ -350,55 +350,6 @@ static void patch_socket_name(const char *path) {
munmap(buf, size); munmap(buf, size);
} }
static void magisk_init_daemon() {
setsid();
// Full patch
sepol_allow("su", ALL, ALL, ALL);
// Wait till init cold boot done
while (access("/dev/.coldboot_done", F_OK))
usleep(1);
int null = open("/dev/null", O_RDWR | O_CLOEXEC);
dup3(null, STDIN_FILENO, O_CLOEXEC);
dup3(null, STDOUT_FILENO, O_CLOEXEC);
dup3(null, STDERR_FILENO, O_CLOEXEC);
if (null > STDERR_FILENO)
close(null);
// Transit our context to su (mimic setcon)
int fd, crap;
fd = open("/proc/self/attr/current", O_WRONLY);
write(fd, "u:r:su:s0", 9);
close(fd);
// Dump full patch to kernel
dump_policydb(SELINUX_LOAD);
close(creat(PATCHDONE, 0));
destroy_policydb();
// Keep Magisk daemon always alive
while (1) {
struct sockaddr_un sun;
fd = setup_socket(&sun);
memcpy(sun.sun_path + 1, RAND_SOCKET_NAME, sizeof(SOCKET_NAME));
while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)))
usleep(10000); /* Wait 10 ms after each try */
/* Should hold forever */
read(fd, &crap, sizeof(crap));
/* If things went here, it means the other side of the socket is closed
* We restart the daemon again */
close(fd);
if (fork_dont_care() == 0) {
execv("/sbin/magisk", (char *[]) { "magisk", "--daemon", NULL } );
exit(1);
}
}
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
umask(0); umask(0);
@ -430,7 +381,7 @@ int main(int argc, char *argv[]) {
mkdir("/overlay/sbin", 0755); mkdir("/overlay/sbin", 0755);
dump_magisk("/overlay/sbin/magisk", 0755); dump_magisk("/overlay/sbin/magisk", 0755);
patch_socket_name("/overlay/sbin/magisk"); patch_socket_name("/overlay/sbin/magisk");
mkdir("/overlay/root", 0755); mkdir("/overlay/root", 0750);
link("/init", "/overlay/root/magiskinit"); link("/init", "/overlay/root/magiskinit");
struct cmdline cmd; struct cmdline cmd;
@ -520,20 +471,13 @@ int main(int argc, char *argv[]) {
patch_ramdisk(); patch_ramdisk();
patch_sepolicy(); patch_sepolicy();
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
if (fork_dont_care() == 0) {
strcpy(argv[0], "magiskinit");
close(root);
magisk_init_daemon();
}
} }
// Clean up // Clean up
close(root); close(root);
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
if (!cmd.skip_initramfs) if (!cmd.skip_initramfs)
umount("/system"); umount("/system");
umount("/vendor"); umount("/vendor");

View File

@ -8,7 +8,7 @@
#include "utils.h" #include "utils.h"
#include "magisk.h" #include "magisk.h"
char socket_name[] = SOCKET_NAME; static char socket_name[] = SOCKET_NAME; /* Workaround compiler bug pre NDK r13 */
/* Setup the address and return socket fd */ /* Setup the address and return socket fd */
int setup_socket(struct sockaddr_un *sun) { int setup_socket(struct sockaddr_un *sun) {

View File

@ -8,7 +8,9 @@
#include <sys/un.h> #include <sys/un.h>
#include <sys/socket.h> #include <sys/socket.h>
extern int is_daemon_init, seperate_vendor; extern int is_daemon_init;
extern int seperate_vendor;
extern int full_patch_pid;
// Commands require connecting to daemon // Commands require connecting to daemon
enum { enum {

View File

@ -55,7 +55,6 @@ extern char *argv0; /* For changing process name */
#define init_applet ((char *[]) { "magiskpolicy", "supolicy", NULL }) #define init_applet ((char *[]) { "magiskpolicy", "supolicy", NULL })
extern int (*applet_main[]) (int, char *[]), (*init_applet_main[]) (int, char *[]); extern int (*applet_main[]) (int, char *[]), (*init_applet_main[]) (int, char *[]);
extern char socket_name[]; /* Workaround compiler bug pre NDK r13 */
int create_links(const char *bin, const char *path); int create_links(const char *bin, const char *path);

View File

@ -1,3 +1,5 @@
#include "magiskpolicy.h"
const char magiskrc[] = const char magiskrc[] =
// Triggers // Triggers
@ -20,25 +22,25 @@ const char magiskrc[] =
"service magisk_daemon /sbin/magisk --daemon\n" "service magisk_daemon /sbin/magisk --daemon\n"
" user root\n" " user root\n"
" seclabel u:r:su:s0\n" " seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
" oneshot\n" " oneshot\n"
"\n" "\n"
"service magisk_pfs /sbin/magisk --post-fs\n" "service magisk_pfs /sbin/magisk --post-fs\n"
" user root\n" " user root\n"
" seclabel u:r:su:s0\n" " seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
" oneshot\n" " oneshot\n"
"\n" "\n"
"service magisk_pfsd /sbin/magisk --post-fs-data\n" "service magisk_pfsd /sbin/magisk --post-fs-data\n"
" user root\n" " user root\n"
" seclabel u:r:su:s0\n" " seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
" oneshot\n" " oneshot\n"
"\n" "\n"
"service magisk_service /sbin/magisk --service\n" "service magisk_service /sbin/magisk --service\n"
" class late_start\n" " class late_start\n"
" user root\n" " user root\n"
" seclabel u:r:su:s0\n" " seclabel u:r:"SEPOL_PROC_DOMAIN":s0\n"
" oneshot\n" " oneshot\n"
; ;

View File

@ -122,7 +122,7 @@ int setattrat(int dirfd, const char *pathname, struct file_attr *a);
int fsetattr(int fd, struct file_attr *a); int fsetattr(int fd, struct file_attr *a);
void fclone_attr(const int sourcefd, const int targetfd); void fclone_attr(const int sourcefd, const int targetfd);
void clone_attr(const char *source, const char *target); void clone_attr(const char *source, const char *target);
void restorecon(int dirfd, int force); void restorecon(int dirfd);
int mmap_ro(const char *filename, void **buf, size_t *size); int mmap_ro(const char *filename, void **buf, size_t *size);
int mmap_rw(const char *filename, void **buf, size_t *size); int mmap_rw(const char *filename, void **buf, size_t *size);
void fd_full_read(int fd, void **buf, size_t *size); void fd_full_read(int fd, void **buf, size_t *size);

@ -1 +1 @@
Subproject commit 21a557a1840392e1b802480814cbb86607534814 Subproject commit 31110b192721f9c721efb154333d1110cd9800b8

@ -1 +1 @@
Subproject commit ed5dd827e9092bc87a6f89e211a50092485d4e91 Subproject commit 248f8a2a39acf51bf4cb603a32e70430b851edf4

View File

@ -344,7 +344,7 @@ void fclone_attr(const int sourcefd, const int targetfd) {
#define UNLABEL_CON "u:object_r:unlabeled:s0" #define UNLABEL_CON "u:object_r:unlabeled:s0"
#define SYSTEM_CON "u:object_r:system_file:s0" #define SYSTEM_CON "u:object_r:system_file:s0"
void restorecon(int dirfd, int force) { void restorecon(int dirfd) {
struct dirent *entry; struct dirent *entry;
DIR *dir; DIR *dir;
int fd; int fd;
@ -352,7 +352,7 @@ void restorecon(int dirfd, int force) {
fd_getpath(dirfd, path, sizeof(path)); fd_getpath(dirfd, path, sizeof(path));
lgetfilecon(path, &con); lgetfilecon(path, &con);
if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) if (strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
lsetfilecon(path, SYSTEM_CON); lsetfilecon(path, SYSTEM_CON);
freecon(con); freecon(con);
@ -362,12 +362,12 @@ void restorecon(int dirfd, int force) {
continue; continue;
if (entry->d_type == DT_DIR) { if (entry->d_type == DT_DIR) {
fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC); fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
restorecon(fd, force); restorecon(fd);
} else { } else {
fd = xopenat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC); fd = xopenat(dirfd, entry->d_name, O_PATH | O_NOFOLLOW | O_CLOEXEC);
fd_getpath(fd, path, sizeof(path)); fd_getpath(fd, path, sizeof(path));
lgetfilecon(path, &con); lgetfilecon(path, &con);
if (force || strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0) if (strlen(con) == 0 || strcmp(con, UNLABEL_CON) == 0)
lsetfilecon(path, SYSTEM_CON); lsetfilecon(path, SYSTEM_CON);
freecon(con); freecon(con);
} }
@ -379,7 +379,7 @@ void restorecon(int dirfd, int force) {
static int _mmap(int rw, const char *filename, void **buf, size_t *size) { static int _mmap(int rw, const char *filename, void **buf, size_t *size) {
struct stat st; struct stat st;
int fd = xopen(filename, rw ? O_RDWR : O_RDONLY); int fd = xopen(filename, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC);
fstat(fd, &st); fstat(fd, &st);
if (S_ISBLK(st.st_mode)) if (S_ISBLK(st.st_mode))
ioctl(fd, BLKGETSIZE64, size); ioctl(fd, BLKGETSIZE64, size);
@ -407,7 +407,7 @@ void fd_full_read(int fd, void **buf, size_t *size) {
} }
void full_read(const char *filename, void **buf, size_t *size) { void full_read(const char *filename, void **buf, size_t *size) {
int fd = xopen(filename, O_RDONLY); int fd = xopen(filename, O_RDONLY | O_CLOEXEC);
if (fd < 0) { if (fd < 0) {
*buf = NULL; *buf = NULL;
*size = 0; *size = 0;
@ -418,7 +418,7 @@ void full_read(const char *filename, void **buf, size_t *size) {
} }
void full_read_at(int dirfd, const char *filename, void **buf, size_t *size) { void full_read_at(int dirfd, const char *filename, void **buf, size_t *size) {
int fd = xopenat(dirfd, filename, O_RDONLY); int fd = xopenat(dirfd, filename, O_RDONLY | O_CLOEXEC);
if (fd < 0) { if (fd < 0) {
*buf = NULL; *buf = NULL;
*size = 0; *size = 0;