diff --git a/native/jni/core/init.cpp b/native/jni/core/init.cpp index 96eb356a0..d0f1c0fa6 100644 --- a/native/jni/core/init.cpp +++ b/native/jni/core/init.cpp @@ -245,7 +245,7 @@ void MagiskInit::load_kernel_info() { if (cmd.dt_dir[0] == '\0') strcpy(cmd.dt_dir, DEFAULT_DT_DIR); - LOGD("system_as_root[%d] slot[%s] dt_dir[%s]\n", cmd.system_as_root, cmd.slot, cmd.dt_dir); + LOGD("system_as_root[%d]\nslot[%s]\ndt_dir[%s]\n", cmd.system_as_root, cmd.slot, cmd.dt_dir); } void MagiskInit::preset() { @@ -253,10 +253,7 @@ void MagiskInit::preset() { if (cmd.system_as_root) { // Clear rootfs - const char *excl[] = { "overlay", "proc", "sys", nullptr }; - excl_list = excl; - frm_rf(root); - excl_list = nullptr; + frm_rf(root, { "overlay", "proc", "sys" }); } else { decompress_ramdisk(); @@ -375,24 +372,16 @@ void MagiskInit::setup_rootfs() { bool patch_init = patch_sepolicy(); if (cmd.system_as_root) { - // Clone rootfs except /system + // Clone rootfs int system_root = open("/system_root", O_RDONLY | O_CLOEXEC); - const char *excl[] = { "system", nullptr }; - excl_list = excl; - clone_dir(system_root, root); + clone_dir(system_root, root, false); close(system_root); - excl_list = nullptr; } - // Override /sepolicy if exist - rename("/magisk_sepolicy", "/sepolicy"); - if (patch_init) { constexpr char SYSTEM_INIT[] = "/system/bin/init"; // If init is symlink, copy it to rootfs so we can patch - struct stat st; - lstat("/init", &st); - if (S_ISLNK(st.st_mode)) + if (is_lnk("/init")) cp_afc(SYSTEM_INIT, "/init"); char *addr; @@ -474,7 +463,7 @@ bool MagiskInit::patch_sepolicy() { sepol_magisk_rules(); sepol_allow(SEPOL_PROC_DOMAIN, ALL, ALL, ALL); - dump_policydb("/magisk_sepolicy"); + dump_policydb("/sepolicy"); // Load policy to kernel so we can label rootfs if (load_sepol) @@ -483,7 +472,7 @@ bool MagiskInit::patch_sepolicy() { // Remove OnePlus stupid debug sepolicy and use our own if (access("/sepolicy_debug", F_OK) == 0) { unlink("/sepolicy_debug"); - link("/magisk_sepolicy", "/sepolicy_debug"); + link("/sepolicy", "/sepolicy_debug"); } // Enable selinux functions diff --git a/native/jni/utils/file.cpp b/native/jni/utils/file.cpp index a02cf1515..6329bd89e 100644 --- a/native/jni/utils/file.cpp +++ b/native/jni/utils/file.cpp @@ -17,16 +17,6 @@ using namespace std; -const char **excl_list = nullptr; - -static int is_excl(const char *name) { - if (excl_list) - for (int i = 0; excl_list[i]; ++i) - if (strcmp(name, excl_list[i]) == 0) - return 1; - return 0; -} - ssize_t fd_path(int fd, char *path, size_t size) { snprintf(path, size, "/proc/self/fd/%d", fd); return xreadlink(path, path, size); @@ -62,7 +52,15 @@ int mkdirs(const char *pathname, mode_t mode) { return 0; } -void post_order_walk(int dirfd, void (*fn)(int, struct dirent *)) { +static bool is_excl(initializer_list excl, const char *name) { + for (auto item : excl) + if (strcmp(item, name) == 0) + return true; + return false; +} + +static void post_order_walk(int dirfd, initializer_list excl, + int (*fn)(int, struct dirent *)) { struct dirent *entry; int newfd; DIR *dir = fdopendir(dirfd); @@ -71,17 +69,21 @@ void post_order_walk(int dirfd, void (*fn)(int, struct dirent *)) { while ((entry = xreaddir(dir))) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; - if (is_excl(entry->d_name)) + if (is_excl(excl, entry->d_name)) continue; if (entry->d_type == DT_DIR) { newfd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC); - post_order_walk(newfd, fn); + post_order_walk(newfd, excl, fn); close(newfd); } fn(dirfd, entry); } } +static int remove_at(int dirfd, struct dirent *entry) { + return unlinkat(dirfd, entry->d_name, entry->d_type == DT_DIR ? AT_REMOVEDIR : 0); +} + void rm_rf(const char *path) { struct stat st; if (lstat(path, &st) < 0) @@ -94,10 +96,8 @@ void rm_rf(const char *path) { remove(path); } -void frm_rf(int dirfd) { - post_order_walk(dirfd, [](auto dirfd, auto entry) -> void { - unlinkat(dirfd, entry->d_name, entry->d_type == DT_DIR ? AT_REMOVEDIR : 0); - }); +void frm_rf(int dirfd, initializer_list excl) { + post_order_walk(dirfd, excl, remove_at); } /* This will only on the same file system */ @@ -134,8 +134,6 @@ void mv_dir(int src, int dest) { while ((entry = xreaddir(dir))) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; - if (is_excl(entry->d_name)) - continue; getattrat(src, entry->d_name, &a); switch (entry->d_type) { case DT_DIR: @@ -186,7 +184,7 @@ void cp_afc(const char *source, const char *destination) { setattr(destination, &a); } -void clone_dir(int src, int dest) { +void clone_dir(int src, int dest, bool overwrite) { struct dirent *entry; DIR *dir; int srcfd, destfd, newsrc, newdest; @@ -197,7 +195,8 @@ void clone_dir(int src, int dest) { while ((entry = xreaddir(dir))) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; - if (is_excl(entry->d_name)) + if (struct stat st; !overwrite && + fstatat(dest, entry->d_name, &st, AT_SYMLINK_NOFOLLOW) == 0) continue; getattrat(src, entry->d_name, &a); switch (entry->d_type) { @@ -206,7 +205,7 @@ void clone_dir(int src, int dest) { setattrat(dest, entry->d_name, &a); newsrc = xopenat(src, entry->d_name, O_RDONLY | O_CLOEXEC); newdest = xopenat(dest, entry->d_name, O_RDONLY | O_CLOEXEC); - clone_dir(newsrc, newdest); + clone_dir(newsrc, newdest, overwrite); close(newsrc); close(newdest); break; @@ -237,8 +236,6 @@ void link_dir(int src, int dest) { while ((entry = xreaddir(dir))) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; - if (is_excl(entry->d_name)) - continue; if (entry->d_type == DT_DIR) { getattrat(src, entry->d_name, &a); xmkdirat(dest, entry->d_name, a.st.st_mode & 0777); diff --git a/native/jni/utils/include/utils.h b/native/jni/utils/include/utils.h index 534602444..12292d37f 100644 --- a/native/jni/utils/include/utils.h +++ b/native/jni/utils/include/utils.h @@ -97,8 +97,6 @@ ssize_t __getdelim(char **lineptr, size_t *n, int delim, FILE *stream); #define do_align(p, a) (((p) + (a) - 1) / (a) * (a)) #define align_off(p, a) (do_align(p, a) - (p)) -extern const char **excl_list; - struct file_attr { struct stat st; char con[128]; @@ -107,14 +105,11 @@ struct file_attr { ssize_t fd_path(int fd, char *path, size_t size); int fd_pathat(int dirfd, const char *name, char *path, size_t size); int mkdirs(const char *pathname, mode_t mode); -void post_order_walk(int dirfd, void (*fn)(int, struct dirent *)); void rm_rf(const char *path); -void frm_rf(int dirfd); void mv_f(const char *source, const char *destination); void mv_dir(int src, int dest); void cp_afc(const char *source, const char *destination); void link_dir(int src, int dest); -void clone_dir(int src, int dest); int getattr(const char *path, struct file_attr *a); int getattrat(int dirfd, const char *name, struct file_attr *a); int fgetattr(int fd, struct file_attr *a); @@ -177,6 +172,8 @@ void file_readline(const char *file, const std::function &fn); void *__mmap(const char *filename, size_t *size, bool rw); +void frm_rf(int dirfd, std::initializer_list excl = std::initializer_list()); +void clone_dir(int src, int dest, bool overwrite = true); template void mmap_ro(const char *filename, B &buf, size_t &sz) {