diff --git a/native/jni/daemon/bootstages.cpp b/native/jni/daemon/bootstages.cpp index 8e98cb964..4b00c8be8 100644 --- a/native/jni/daemon/bootstages.cpp +++ b/native/jni/daemon/bootstages.cpp @@ -25,6 +25,7 @@ static char buf[PATH_MAX], buf2[PATH_MAX]; static Vector module_list; +static bool seperate_vendor; char *system_block, *vendor_block, *magiskloop; @@ -304,27 +305,27 @@ static void set_mirror_path() { static void exec_common_script(const char* stage) { DIR *dir; struct dirent *entry; - snprintf(buf2, PATH_MAX, "%s/%s.d", COREDIR, stage); + snprintf(buf2, PATH_MAX, "%s/%s.d", SECURE_DIR, stage); if (!(dir = xopendir(buf2))) return; + chdir(buf2); while ((entry = xreaddir(dir))) { if (entry->d_type == DT_REG) { - snprintf(buf2, PATH_MAX, "%s/%s.d/%s", COREDIR, stage, entry->d_name); - if (access(buf2, X_OK) == -1) + if (access(entry->d_name, X_OK) == -1) continue; LOGI("%s.d: exec [%s]\n", stage, entry->d_name); - int pid = exec_command( - 0, nullptr, + int pid = exec_command(0, nullptr, strcmp(stage, "post-fs-data") ? set_path : set_mirror_path, - "sh", buf2, nullptr); + "sh", entry->d_name, nullptr); if (pid != -1) waitpid(pid, nullptr, 0); } } closedir(dir); + chdir("/"); } static void exec_module_script(const char* stage) { @@ -427,6 +428,10 @@ static bool magisk_env() { xmkdir(MOUNTPOINT, 0755); xmkdir(BLOCKDIR, 0755); + // Boot script directories + xmkdir(SECURE_DIR "/post-fs-data.d", 0755); + xmkdir(SECURE_DIR "/service.d", 0755); + LOGI("* Mounting mirrors"); Vector mounts; file_to_vector("/proc/mounts", mounts); @@ -447,7 +452,7 @@ static bool magisk_env() { LOGI("mount: %s\n", MIRRDIR "/system"); #endif } else if (line.contains(" /vendor ")) { - seperate_vendor = 1; + seperate_vendor = true; sscanf(line, "%s %*s %s", buf, buf2); vendor_block = strdup2(buf); xmkdir(MIRRDIR "/vendor", 0755); @@ -475,7 +480,10 @@ static bool magisk_env() { LOGI("* Setting up internal busybox"); exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, nullptr); xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox"); + return true; +} +static bool prepare_img() { const char *alt_img[] = { "/cache/magisk.img", "/data/magisk_merge.img", "/data/adb/magisk_merge.img" }; @@ -496,9 +504,21 @@ static bool magisk_env() { if (magiskloop == nullptr) return false; - xmkdir(COREDIR, 0755); - xmkdir(COREDIR "/post-fs-data.d", 0755); - xmkdir(COREDIR "/service.d", 0755); + // Migrate legacy boot scripts + struct stat st; + if (stat(LEGACY_CORE "/post-fs-data.d", &st) == 0 && S_ISDIR(st.st_mode)) { + cp_afc(LEGACY_CORE "/post-fs-data.d", SECURE_DIR "/post-fs-data.d"); + rm_rf(LEGACY_CORE "/post-fs-data.d"); + } + if (stat(LEGACY_CORE "/service.d", &st) == 0 && S_ISDIR(st.st_mode)) { + cp_afc(LEGACY_CORE "/service.d", SECURE_DIR "/service.d"); + rm_rf(LEGACY_CORE "/service.d"); + } + + // Links for legacy paths + xmkdir(LEGACY_CORE, 0755); + symlink(SECURE_DIR "/post-fs-data.d", LEGACY_CORE "/post-fs-data.d"); + symlink(SECURE_DIR "/service.d", LEGACY_CORE "/service.d"); DIR *dir = xopendir(MOUNTPOINT); struct dirent *entry; @@ -581,18 +601,16 @@ static bool check_data() { extern int launch_magiskhide(int client = -1); -static void *start_magisk_hide(void *) { - launch_magiskhide(); - return nullptr; -} - static void auto_start_magiskhide() { if (!start_log_daemon()) return; CharArray hide_prop = getprop(MAGISKHIDE_PROP, true); if (hide_prop != "0") { pthread_t thread; - xpthread_create(&thread, nullptr, start_magisk_hide, nullptr); + xpthread_create(&thread, nullptr, [](void*) -> void* { + launch_magiskhide(); + return nullptr; + }, nullptr); pthread_detach(thread); } } @@ -622,7 +640,7 @@ void unlock_blocks() { * Entry points * ****************/ -static void unblock_boot_process() { +[[noreturn]] static void unblock_boot_process() { close(xopen(UNBLOCKFILE, O_RDONLY | O_CREAT, 0)); pthread_exit(nullptr); } @@ -642,7 +660,7 @@ void startup() { /* If the folder is not automatically created by the system, * do NOT proceed further. Manual creation of the folder * will cause bootloops on FBE devices. */ - LOGE(SECURE_DIR" is not present, abort..."); + LOGE(SECURE_DIR " is not present, abort..."); unblock_boot_process(); } @@ -751,7 +769,7 @@ void startup() { execl("/sbin/magisk.bin", "magisk", "--post-fs-data", nullptr); } -static void core_only() { +[[noreturn]] static void core_only() { auto_start_magiskhide(); unblock_boot_process(); } @@ -761,23 +779,24 @@ void post_fs_data(int client) { write_int(client, 0); close(client); - // If post-fs-data mode is started, it means startup succeeded - setup_done = 1; - xmount(nullptr, "/", nullptr, MS_REMOUNT | MS_RDONLY, nullptr); LOGI("** post-fs-data mode running\n"); - // If magisk environment setup failed, only run core only operations if (!magisk_env()) { - free(magiskloop); - magiskloop = nullptr; - core_only(); - return; + LOGE("* Magisk environment setup incomplete, abort\n"); + unblock_boot_process(); } start_log_daemon(); + if (!prepare_img()) { + LOGE("* Magisk image mount failed, switch to core-only mode\n"); + free(magiskloop); + magiskloop = nullptr; + creat(DISABLEFILE, 0644); + } + restorecon(); chmod(SECURE_DIR, 0700); @@ -786,10 +805,8 @@ void post_fs_data(int client) { exec_common_script("post-fs-data"); // Core only mode - if (access(DISABLEFILE, F_OK) == 0) { + if (access(DISABLEFILE, F_OK) == 0) core_only(); - return; - } // Execute module scripts LOGI("* Running module post-fs-data scripts\n"); @@ -858,12 +875,8 @@ void late_start(int client) { if (access(SECURE_DIR, F_OK) != 0) { // It's safe to create the folder at this point if the system didn't create it xmkdir(SECURE_DIR, 0700); - } - - if (!setup_done) { - // The setup failed for some reason, reboot and try again + // And reboot to make proper setup possible exec_command_sync("/system/bin/reboot", nullptr); - return; } auto_start_magiskhide(); diff --git a/native/jni/daemon/daemon.cpp b/native/jni/daemon/daemon.cpp index 1712c5d57..83cf5f1cc 100644 --- a/native/jni/daemon/daemon.cpp +++ b/native/jni/daemon/daemon.cpp @@ -20,9 +20,6 @@ #include "selinux.h" #include "flags.h" -int setup_done = 0; -int seperate_vendor = 0; - static void get_client_cred(int fd, struct ucred *cred) { socklen_t ucred_length = sizeof(*cred); if(getsockopt(fd, SOL_SOCKET, SO_PEERCRED, cred, &ucred_length)) diff --git a/native/jni/include/daemon.h b/native/jni/include/daemon.h index 44fc6b2e0..7588cd512 100644 --- a/native/jni/include/daemon.h +++ b/native/jni/include/daemon.h @@ -9,9 +9,6 @@ #include #include -extern int setup_done; -extern int seperate_vendor; - // Commands require connecting to daemon enum { DO_NOTHING = 0, diff --git a/native/jni/include/magisk.h b/native/jni/include/magisk.h index 0b751a29d..2ed55913c 100644 --- a/native/jni/include/magisk.h +++ b/native/jni/include/magisk.h @@ -17,7 +17,7 @@ #define MIRRDIR MAGISKTMP "/mirror" #define BBPATH MAGISKTMP "/busybox" #define MOUNTPOINT MAGISKTMP "/img" -#define COREDIR MOUNTPOINT "/.core" +#define LEGACY_CORE MOUNTPOINT "/.core" #define SECURE_DIR "/data/adb" #define MAINIMG SECURE_DIR "/magisk.img" #define DATABIN SECURE_DIR "/magisk"