From e29b712108e75d35e3c123e5a5a2dbdf0d68f710 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Tue, 25 Jun 2019 23:31:59 -0700 Subject: [PATCH] Start Magisk in SAR --- native/jni/core/bootstages.cpp | 11 +++-- native/jni/core/daemon.cpp | 6 +++ native/jni/init/rootdir.cpp | 80 +++++++++++++++++-------------- native/jni/magiskpolicy/rules.cpp | 3 ++ native/jni/utils/selinux.cpp | 4 ++ scripts/util_functions.sh | 1 + 6 files changed, 67 insertions(+), 38 deletions(-) diff --git a/native/jni/core/bootstages.cpp b/native/jni/core/bootstages.cpp index 1b198ef9c..079c29e38 100644 --- a/native/jni/core/bootstages.cpp +++ b/native/jni/core/bootstages.cpp @@ -381,6 +381,11 @@ static bool magisk_env() { } return true; }); + if (access(MIRRMNT(system), F_OK) != 0 && access(MIRRMNT(system_root), F_OK) == 0) { + // Pre-init mirrors + xsymlink(MIRRMNT(system_root) "/system", MIRRMNT(system)); + VLOGI("link", MIRRMNT(system_root) "/system", MIRRMNT(system)); + } if (access(MIRRMNT(vendor), F_OK) != 0) { xsymlink(MIRRMNT(system) "/vendor", MIRRMNT(vendor)); VLOGI("link", MIRRMNT(system) "/vendor", MIRRMNT(vendor)); @@ -606,13 +611,13 @@ void post_fs_data(int client) { prepare_modules(); + restorecon(); + chmod(SECURE_DIR, 0700); + // Core only mode if (access(DISABLEFILE, F_OK) == 0) core_only(); - restorecon(); - chmod(SECURE_DIR, 0700); - collect_modules(); // Execute module scripts diff --git a/native/jni/core/daemon.cpp b/native/jni/core/daemon.cpp index 3e1f34b07..0c1243eac 100644 --- a/native/jni/core/daemon.cpp +++ b/native/jni/core/daemon.cpp @@ -108,6 +108,12 @@ static void main_daemon() { setcon("u:r:" SEPOL_PROC_DOMAIN ":s0"); restore_rootcon(); + // Unmount pre-init patches + umount2("/init", MNT_DETACH); + umount2("/init.rc", MNT_DETACH); + umount2("/system/lib/libselinux.so", MNT_DETACH); + umount2("/system/lib64/libselinux.so", MNT_DETACH); + int fd = xopen("/dev/null", O_RDWR | O_CLOEXEC); xdup2(fd, STDOUT_FILENO); xdup2(fd, STDERR_FILENO); diff --git a/native/jni/init/rootdir.cpp b/native/jni/init/rootdir.cpp index 0d48d04bf..074907540 100644 --- a/native/jni/init/rootdir.cpp +++ b/native/jni/init/rootdir.cpp @@ -33,11 +33,34 @@ static void patch_socket_name(const char *path) { munmap(buf, size); } -constexpr const char wrapper[] = -"#!/system/bin/sh\n" -"export LD_LIBRARY_PATH=\"$LD_LIBRARY_PATH:/apex/com.android.runtime/" LIBNAME "\"\n" -"exec /sbin/magisk.bin \"$0\" \"$@\"\n" -; +static void patch_init_rc(FILE *rc) { + file_readline("/init.rc", [&](string_view line) -> bool { + // Do not start vaultkeeper + if (str_contains(line, "start vaultkeeper")) { + LOGD("Remove vaultkeeper\n"); + return true; + } + // Do not run flash_recovery + if (str_starts(line, "service flash_recovery")) { + LOGD("Remove flash_recovery\n"); + fprintf(rc, "service flash_recovery /system/bin/xxxxx\n"); + return true; + } + // Else just write the line + fprintf(rc, "%s", line.data()); + return true; + }); + char pfd_svc[8], ls_svc[8], bc_svc[8]; + // Make sure to be unique + pfd_svc[0] = 'a'; + ls_svc[0] = '0'; + bc_svc[0] = 'A'; + gen_rand_str(pfd_svc + 1, sizeof(pfd_svc) - 1); + gen_rand_str(ls_svc + 1, sizeof(ls_svc) - 1); + gen_rand_str(bc_svc + 1, sizeof(bc_svc) - 1); + LOGD("Inject magisk services: [%s] [%s] [%s]\n", pfd_svc, ls_svc, bc_svc); + fprintf(rc, magiskrc, pfd_svc, pfd_svc, ls_svc, bc_svc, bc_svc); +} void RootFSInit::setup_rootfs() { if (patch_sepolicy()) { @@ -66,39 +89,11 @@ void RootFSInit::setup_rootfs() { // Patch init.rc FILE *rc = xfopen("/init.p.rc", "we"); - file_readline("/init.rc", [&](auto line) -> bool { - // Do not start vaultkeeper - if (str_contains(line, "start vaultkeeper")) { - LOGD("Remove vaultkeeper\n"); - return true; - } - // Do not run flash_recovery - if (str_starts(line, "service flash_recovery")) { - LOGD("Remove flash_recovery\n"); - fprintf(rc, "service flash_recovery /system/bin/xxxxx\n"); - return true; - } - // Else just write the line - fprintf(rc, "%s", line.data()); - return true; - }); - char pfd_svc[8], ls_svc[8], bc_svc[8]; - // Make sure to be unique - pfd_svc[0] = 'a'; - ls_svc[0] = '0'; - bc_svc[0] = 'A'; - gen_rand_str(pfd_svc + 1, sizeof(pfd_svc) - 1); - gen_rand_str(ls_svc + 1, sizeof(ls_svc) - 1); - gen_rand_str(bc_svc + 1, sizeof(bc_svc) - 1); - LOGD("Inject magisk services: [%s] [%s] [%s]\n", pfd_svc, ls_svc, bc_svc); - fprintf(rc, magiskrc, pfd_svc, pfd_svc, ls_svc, bc_svc, bc_svc); + patch_init_rc(rc); fclose(rc); clone_attr("/init.rc", "/init.p.rc"); rename("/init.p.rc", "/init.rc"); - // Don't let init run in init yet - lsetfilecon("/init", "u:object_r:rootfs:s0"); - // Create hardlink mirror of /sbin to /root mkdir("/root", 0750); clone_attr("/sbin", "/root"); @@ -156,6 +151,12 @@ bool MagiskInit::patch_sepolicy(const char *file) { return patch_init; } +constexpr const char wrapper[] = +"#!/system/bin/sh\n" +"export LD_LIBRARY_PATH=\"$LD_LIBRARY_PATH:/apex/com.android.runtime/" LIBNAME "\"\n" +"exec /sbin/magisk.bin \"$0\" \"$@\"\n" +; + static void sbin_overlay(const raw_data &self, const raw_data &config) { LOGD("Mount /sbin tmpfs overlay\n"); xmount("tmpfs", "/sbin", "tmpfs", 0, "mode=755"); @@ -236,7 +237,10 @@ void SARInit::patch_rootdir() { close(src); close(dest); - // Customize rootdir + /* ****************** + * Customize rootdir + * ******************/ + char *addr; size_t size; file_attr attr; @@ -288,6 +292,12 @@ void SARInit::patch_rootdir() { } patch_sepolicy(PATCHPOLICY); + + FILE *rc = xfopen(ROOTOVERLAY "/init.rc", "we"); + patch_init_rc(rc); + fclose(rc); + clone_attr("/init.rc", ROOTOVERLAY "/init.rc"); + xmount(ROOTOVERLAY "/init.rc", "/init.rc", nullptr, MS_BIND, nullptr); } #ifdef MAGISK_DEBUG diff --git a/native/jni/magiskpolicy/rules.cpp b/native/jni/magiskpolicy/rules.cpp index 4c747ef7c..5dcbd40b5 100644 --- a/native/jni/magiskpolicy/rules.cpp +++ b/native/jni/magiskpolicy/rules.cpp @@ -48,6 +48,9 @@ void sepol_magisk_rules() { sepol_attradd(SEPOL_PROC_DOMAIN, "bluetoothdomain"); sepol_attradd(SEPOL_FILE_DOMAIN, "mlstrustedobject"); + // Let everyone access tmpfs files (for SAR sbin overlay) + sepol_allow(ALL, "tmpfs", "file", ALL); + // Let init transit to SEPOL_PROC_DOMAIN sepol_allow("kernel", "kernel", "process", "setcurrent"); sepol_allow("kernel", SEPOL_PROC_DOMAIN, "process", "dyntransition"); diff --git a/native/jni/utils/selinux.cpp b/native/jni/utils/selinux.cpp index f19600e62..ed3696191 100644 --- a/native/jni/utils/selinux.cpp +++ b/native/jni/utils/selinux.cpp @@ -227,6 +227,10 @@ void restorecon() { void restore_rootcon() { setfilecon("/sbin", ROOT_CON); + setfilecon(MAGISKTMP, ROOT_CON); + setfilecon(MIRRDIR, ROOT_CON); + setfilecon(BLOCKDIR, ROOT_CON); + struct dirent *entry; DIR *dir = xopendir("/sbin"); int dfd = dirfd(dir); diff --git a/scripts/util_functions.sh b/scripts/util_functions.sh index 10780eefc..c764dec6e 100644 --- a/scripts/util_functions.sh +++ b/scripts/util_functions.sh @@ -166,6 +166,7 @@ find_block() { } mount_part() { + $BOOTMODE && return local PART=$1 local POINT=/${PART} [ -L $POINT ] && rm -f $POINT