diff --git a/native/jni/core/bootstages.cpp b/native/jni/core/bootstages.cpp index de1cb271b..5fc36eb4e 100644 --- a/native/jni/core/bootstages.cpp +++ b/native/jni/core/bootstages.cpp @@ -148,12 +148,10 @@ static bool magisk_env() { if (access(DATABIN "/busybox", X_OK) == -1) return false; - // TODO: Remove. Backwards compatibility for old manager - LOGI("* Setting up internal busybox\n"); sprintf(buf, "%s/" BBPATH "/busybox", MAGISKTMP.data()); mkdir(dirname(buf), 0755); cp_afc(DATABIN "/busybox", buf); - exec_command_sync(buf, "--install", "-s", dirname(buf)); + exec_command_async(buf, "--install", "-s", dirname(buf)); return true; } diff --git a/native/jni/core/scripting.cpp b/native/jni/core/scripting.cpp index 199e6dd03..a0839a08d 100644 --- a/native/jni/core/scripting.cpp +++ b/native/jni/core/scripting.cpp @@ -10,15 +10,25 @@ using namespace std; -#define BBEXEC_CMD DATABIN "/busybox", "sh" +#define BBEXEC_CMD bbpath(), "sh" -static void set_standalone() { +static const char *bbpath() { + static string path; + if (path.empty()) + path = MAGISKTMP + "/" BBPATH "/busybox"; + return path.data(); +} + +static void set_script_env() { setenv("ASH_STANDALONE", "1", 1); + char new_path[4096]; + sprintf(new_path, "%s:%s", getenv("PATH"), MAGISKTMP.data()); + setenv("PATH", new_path, 1); }; void exec_script(const char *script) { exec_t exec { - .pre_exec = set_standalone, + .pre_exec = set_script_env, .fork = fork_no_zombie }; exec_command_sync(exec, BBEXEC_CMD, script); @@ -43,7 +53,7 @@ void exec_common_scripts(const char *stage) { LOGI("%s.d: exec [%s]\n", stage, entry->d_name); strcpy(name, entry->d_name); exec_t exec { - .pre_exec = set_standalone, + .pre_exec = set_script_env, .fork = pfs ? fork_no_zombie : fork_dont_care }; if (pfs) @@ -59,13 +69,13 @@ void exec_module_scripts(const char *stage, const vector &module_list) { char path[4096]; bool pfs = stage == "post-fs-data"sv; for (auto &m : module_list) { - const char* module = m.c_str(); + const char* module = m.data(); sprintf(path, MODULEROOT "/%s/%s.sh", module, stage); if (access(path, F_OK) == -1) continue; LOGI("%s: exec [%s.sh]\n", module, stage); exec_t exec { - .pre_exec = set_standalone, + .pre_exec = set_script_env, .fork = pfs ? fork_no_zombie : fork_dont_care }; if (pfs) @@ -78,30 +88,35 @@ void exec_module_scripts(const char *stage, const vector &module_list) { constexpr char install_script[] = R"EOF( APK=%s log -t Magisk "apk_install: $APK" -log -t Magisk "apk_install: `pm install -r $APK 2>&1`" +log -t Magisk "apk_install: $(pm install -r $APK 2>&1)" rm -f $APK )EOF"; void install_apk(const char *apk) { setfilecon(apk, "u:object_r:" SEPOL_FILE_TYPE ":s0"); exec_t exec { - .pre_exec = set_standalone, .fork = fork_no_zombie }; char cmds[sizeof(install_script) + 4096]; sprintf(cmds, install_script, apk); - exec_command_sync(exec, BBEXEC_CMD, "-c", cmds); + exec_command_sync(exec, "/system/bin/sh", "-c", cmds); } -[[noreturn]] static void abort(const char *msg) { - fprintf(stderr, "%s\n\n", msg); +[[noreturn]] __printflike(1, 2) +static void abort(const char *fmt, ...) { + va_list valist; + va_start(valist, fmt); + vfprintf(stderr, fmt, valist); + fprintf(stderr, "\n\n"); + va_end(valist); exit(1); } constexpr char install_module_script[] = R"EOF( +exec $(magisk --path)/.magisk/busybox/busybox sh -c ' . /data/adb/magisk/util_functions.sh install_module -exit 0 +exit 0' )EOF"; void install_module(const char *file) { @@ -112,20 +127,18 @@ void install_module(const char *file) { access(DATABIN "/util_functions.sh", F_OK)) abort("Incomplete Magisk install"); if (access(file, F_OK)) { - char msg[4096]; - sprintf(msg, "'%s' does not exist", file); - abort(msg); + abort("'%s' does not exist", file); } - setenv("OUTFD", "1", true); - setenv("ZIPFILE", file, true); + setenv("OUTFD", "1", 1); + setenv("ZIPFILE", file, 1); setenv("ASH_STANDALONE", "1", 1); int fd = xopen("/dev/null", O_RDONLY); xdup2(fd, STDERR_FILENO); close(fd); - const char *argv[] = { BBEXEC_CMD, "-c", install_module_script }; + const char *argv[] = { "/system/bin/sh", "-c", install_module_script }; execve(argv[0], (char **) argv, environ); abort("Failed to execute BusyBox shell"); } diff --git a/native/jni/utils/misc.hpp b/native/jni/utils/misc.hpp index 85060b609..69114311b 100644 --- a/native/jni/utils/misc.hpp +++ b/native/jni/utils/misc.hpp @@ -58,13 +58,24 @@ reversed_container reversed(T &base) { } int parse_int(const char *s); -static inline int parse_int(std::string s) { return parse_int(s.data()); } +static inline int parse_int(const std::string &s) { return parse_int(s.data()); } static inline int parse_int(std::string_view s) { return parse_int(s.data()); } using thread_entry = void *(*)(void *); int new_daemon_thread(thread_entry entry, void *arg = nullptr, const pthread_attr_t *attr = nullptr); int new_daemon_thread(std::function &&entry); +bool ends_with(const std::string_view &s1, const std::string_view &s2); +int fork_dont_care(); +int fork_no_zombie(); +int strend(const char *s1, const char *s2); +void init_argv0(int argc, char **argv); +void set_nice_name(const char *name); +uint32_t binary_gcd(uint32_t u, uint32_t v); +int switch_mnt_ns(int pid); +int gen_rand_str(char *buf, int len, bool varlen = true); +std::string &replace_all(std::string &str, std::string_view from, std::string_view to); + struct exec_t { bool err = false; int fd = -2; @@ -92,14 +103,12 @@ int exec_command_sync(Args &&...args) { exec_t exec{}; return exec_command_sync(exec, args...); } - -bool ends_with(const std::string_view &s1, const std::string_view &s2); -int fork_dont_care(); -int fork_no_zombie(); -int strend(const char *s1, const char *s2); -void init_argv0(int argc, char **argv); -void set_nice_name(const char *name); -uint32_t binary_gcd(uint32_t u, uint32_t v); -int switch_mnt_ns(int pid); -int gen_rand_str(char *buf, int len, bool varlen = true); -std::string &replace_all(std::string &str, std::string_view from, std::string_view to); +template +void exec_command_async(Args &&...args) { + const char *argv[] = {args..., nullptr}; + exec_t exec { + .argv = argv, + .fork = fork_dont_care + }; + exec_command(exec); +}