diff --git a/native/jni/core/module.cpp b/native/jni/core/module.cpp index 5f0fb3413..7b7cbff1b 100644 --- a/native/jni/core/module.cpp +++ b/native/jni/core/module.cpp @@ -22,6 +22,7 @@ using namespace std; #define TYPE_SKEL (1 << 2) /* replace with tmpfs */ #define TYPE_MODULE (1 << 3) /* mount from module */ #define TYPE_ROOT (1 << 4) /* partition root */ +#define TYPE_CUSTOM (1 << 5) /* custom node type overrides all */ #define TYPE_DIR (TYPE_INTER|TYPE_MIRROR|TYPE_SKEL|TYPE_ROOT) vector module_list; @@ -43,7 +44,7 @@ static int bind_mount(const char *from, const char *to) { return ret; } -template uint8_t type_id() { return 0; } +template uint8_t type_id() { return TYPE_CUSTOM; } template<> uint8_t type_id() { return TYPE_DIR; } template<> uint8_t type_id() { return TYPE_INTER; } template<> uint8_t type_id() { return TYPE_MIRROR; } @@ -62,6 +63,10 @@ public: uint8_t type() { return node_type; } const string &name() { return _name; } + // Paths + const string &node_path(); + string mirror_path() { return mirror_dir + node_path(); } + dir_node *parent() { return _parent; } virtual void mount() = 0; @@ -77,10 +82,6 @@ protected: template node_entry(T*) : node_type(type_id()) {} - // Paths - const string &node_path(); - string mirror_path() { return mirror_dir + node_path(); } - void create_and_mount(const string &src); /* Use top bit of _file_type for node exist status */ @@ -470,6 +471,47 @@ bool dir_node::collect_files(const char *module, int dfd) { return true; } +class magisk_node : public node_entry { +public: + magisk_node(const char *name) : node_entry(name, DT_REG, this) {} + + void mount() override { + const string &dir_name = parent()->node_path(); + if (name() == "magisk") { + for (int i = 0; applet_names[i]; ++i) { + string dest = dir_name + "/" + applet_names[i]; + VLOGI("create", "./magisk", dest.data()); + xsymlink("./magisk", dest.data()); + } + } else { + for (int i = 0; init_applet[i]; ++i) { + string dest = dir_name + "/" + init_applet[i]; + VLOGI("create", "./magiskinit", dest.data()); + xsymlink("./magiskinit", dest.data()); + } + } + create_and_mount(MAGISKTMP + "/" + name()); + } +}; + +static void inject_magisk_bins(root_node *system) { + auto bin = system->child("bin"); + if (!bin) { + bin = new inter_node("bin", ""); + system->insert(bin); + } + + // Insert binaries + bin->insert(new magisk_node("magisk")); + bin->insert(new magisk_node("magiskinit")); + + // Also delete all applets to make sure no modules can override it + for (int i = 0; applet_names[i]; ++i) + delete bin->extract(applet_names[i]); + for (int i = 0; init_applet[i]; ++i) + delete bin->extract(init_applet[i]); +} + static void mount_modules() { node_entry::mirror_dir = MAGISKTMP + "/" MIRRDIR; node_entry::module_mnt = MAGISKTMP + "/" MODULEMNT "/"; @@ -518,6 +560,12 @@ static void mount_modules() { system->collect_files(module, fd); close(fd); } + + if (MAGISKTMP != "/sbin") { + // Need to inject our binaries into /system/bin + inject_magisk_bins(system); + } + if (system->is_empty()) return; diff --git a/native/jni/include/magisk.hpp b/native/jni/include/magisk.hpp index af338e372..2e03851fc 100644 --- a/native/jni/include/magisk.hpp +++ b/native/jni/include/magisk.hpp @@ -26,6 +26,7 @@ extern std::string MAGISKTMP; #define ROOTMNT ROOTOVL "/.mount_list" constexpr const char *applet_names[] = { "su", "resetprop", "magiskhide", nullptr }; +constexpr const char *init_applet[] = { "magiskpolicy", "supolicy", nullptr }; // Multi-call entrypoints int magisk_main(int argc, char *argv[]); diff --git a/native/jni/init/init.cpp b/native/jni/init/init.cpp index 64548160d..cd3b3c2a6 100644 --- a/native/jni/init/init.cpp +++ b/native/jni/init/init.cpp @@ -24,10 +24,8 @@ using namespace std; -constexpr const char *init_applet[] = - { "magiskpolicy", "supolicy", "magisk", nullptr }; constexpr int (*init_applet_main[])(int, char *[]) = - { magiskpolicy_main, magiskpolicy_main, magisk_proxy_main, nullptr }; + { magiskpolicy_main, magiskpolicy_main, nullptr }; #ifdef MAGISK_DEBUG static FILE *kmsg; @@ -187,8 +185,11 @@ public: int main(int argc, char *argv[]) { umask(0); + auto name = basename(argv[0]); + if (name == "magisk"sv) + return magisk_proxy_main(argc, argv); for (int i = 0; init_applet[i]; ++i) { - if (strcmp(basename(argv[0]), init_applet[i]) == 0) + if (strcmp(name, init_applet[i]) == 0) return (*init_applet_main[i])(argc, argv); }