diff --git a/native/jni/init/init.cpp b/native/jni/init/init.cpp index 080131967..a3685a507 100644 --- a/native/jni/init/init.cpp +++ b/native/jni/init/init.cpp @@ -24,6 +24,61 @@ using namespace std; constexpr int (*init_applet_main[])(int, char *[]) = { magiskpolicy_main, magiskpolicy_main, nullptr }; +int data_holder::patch(str_pairs list) { + int count = 0; + for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) { + for (auto [from, to] : list) { + if (memcmp(p, from.data(), from.length() + 1) == 0) { + LOGD("Replace [%s] -> [%s]\n", from.data(), to.data()); + memset(p, 0, from.length()); + memcpy(p, to.data(), to.length()); + ++count; + p += from.length(); + } + } + } + return count; +} + +void data_holder::consume(data_holder &other) { + buf = other.buf; + sz = other.sz; + other.buf = nullptr; + other.sz = 0; +} + +template <> +auto_data::~auto_data() { + if (buf) munmap(buf, sz); +} + +template <> +auto_data::~auto_data() { + free(buf); +} + +auto_data raw_data::read(int fd) { + auto_data data; + fd_full_read(fd, data.buf, data.sz); + return data; +} + +auto_data raw_data::read(const char *name) { + auto_data data; + full_read(name, data.buf, data.sz); + return data; +} + +auto_data raw_data::mmap_rw(const char *name) { + auto_data data; + ::mmap_rw(name, data.buf, data.sz); + return data; +} + +// Explicit instantiation +template struct auto_data; +template struct auto_data; + static bool unxz(int fd, const uint8_t *buf, size_t size) { uint8_t out[8192]; xz_crc32_init(); diff --git a/native/jni/init/init.hpp b/native/jni/init/init.hpp index c95a17351..a5ba15f0c 100644 --- a/native/jni/init/init.hpp +++ b/native/jni/init/init.hpp @@ -16,23 +16,32 @@ struct cmdline { char hardware_plat[32]; }; -struct raw_data { +struct data_holder { uint8_t *buf = nullptr; size_t sz = 0; - - raw_data() = default; - raw_data(const raw_data&) = delete; - raw_data(raw_data &&d) { - buf = d.buf; - sz = d.sz; - d.buf = nullptr; - d.sz = 0; - } - ~raw_data() { - free(buf); - } + using str_pairs = std::initializer_list>; + int patch(str_pairs list); +protected: + void consume(data_holder &other); }; +enum data_type { HEAP, MMAP }; + +template +struct auto_data : public data_holder { + auto_data() = default; + auto_data(const auto_data&) = delete; + auto_data(auto_data &&other) { consume(other); } + ~auto_data() {} + auto_data& operator=(auto_data &&other) { consume(other); return *this; } +}; + +namespace raw_data { + auto_data read(const char *name); + auto_data read(int fd); + auto_data mmap_rw(const char *name); +} + struct fstab_entry { std::string dev; std::string mnt_point; @@ -41,7 +50,7 @@ struct fstab_entry { std::string fsmgr_flags; fstab_entry() = default; - fstab_entry(const fstab_entry &o) = delete; + fstab_entry(const fstab_entry &) = delete; fstab_entry(fstab_entry &&o) = default; void to_file(FILE *fp); }; @@ -53,10 +62,7 @@ void load_kernel_info(cmdline *cmd); int dump_magisk(const char *path, mode_t mode); int magisk_proxy_main(int argc, char *argv[]); void setup_klog(); -void setup_tmp(const char *path, const raw_data &self, const raw_data &config); - -using str_pairs = std::initializer_list>; -int raw_data_patch(void *addr, size_t sz, str_pairs list); +void setup_tmp(const char *path, const data_holder &self, const data_holder &config); /*************** * Base classes @@ -85,7 +91,7 @@ public: class MagiskInit : public BaseInit { protected: - raw_data self; + auto_data self; std::string persist_dir; virtual void early_mount() = 0; @@ -96,7 +102,7 @@ public: class SARBase : public MagiskInit { protected: - raw_data config; + auto_data config; std::vector overlays; void backup_files(); diff --git a/native/jni/init/mount.cpp b/native/jni/init/mount.cpp index 01ff233af..bf39ec6c4 100644 --- a/native/jni/init/mount.cpp +++ b/native/jni/init/mount.cpp @@ -219,7 +219,7 @@ static void mount_persist(const char *dev_base, const char *mnt_base) { } void RootFSInit::early_mount() { - full_read("/init", self.buf, self.sz); + self = raw_data::read("/init"); LOGD("Restoring /init\n"); rename("/.backup/init", "/init"); @@ -236,9 +236,9 @@ void SARBase::backup_files() { if (access("/overlay.d", F_OK) == 0) backup_folder("/overlay.d", overlays); - full_read("/proc/self/exe", self.buf, self.sz); + self = raw_data::read("/proc/self/exe"); if (access("/.backup/.magisk", R_OK) == 0) - full_read("/.backup/.magisk", config.buf, config.sz); + config = raw_data::read("/.backup/.magisk"); } void SARBase::mount_system_root() { @@ -304,14 +304,11 @@ void BaseInit::cleanup() { static void patch_socket_name(const char *path) { char rstr[16]; gen_rand_str(rstr, sizeof(rstr)); - char *buf; - size_t size; - mmap_rw(path, buf, size); - raw_data_patch(buf, size, { make_pair(MAIN_SOCKET, rstr) }); - munmap(buf, size); + auto bin = raw_data::mmap_rw(path); + bin.patch({ make_pair(MAIN_SOCKET, rstr) }); } -void setup_tmp(const char *path, const raw_data &self, const raw_data &config) { +void setup_tmp(const char *path, const data_holder &self, const data_holder &config) { LOGD("Setup Magisk tmp at %s\n", path); xmount("tmpfs", path, "tmpfs", 0, "mode=755"); diff --git a/native/jni/init/rootdir.cpp b/native/jni/init/rootdir.cpp index ad5501bcd..c7b1ed41c 100644 --- a/native/jni/init/rootdir.cpp +++ b/native/jni/init/rootdir.cpp @@ -81,29 +81,10 @@ static void load_overlay_rc(const char *overlay) { } } -int raw_data_patch(void *addr, size_t sz, str_pairs list) { - int count = 0; - for (uint8_t *p = (uint8_t *)addr, *eof = (uint8_t *)addr + sz; p < eof; ++p) { - for (auto &[from, to] : list) { - if (memcmp(p, from.data(), from.length() + 1) == 0) { - LOGD("Replace [%s] -> [%s]\n", from.data(), to.data()); - memset(p, 0, from.length()); - memcpy(p, to.data(), to.length()); - ++count; - p += from.length(); - } - } - } - return count; -} - void RootFSInit::setup_rootfs() { if (patch_sepolicy("/sepolicy")) { - char *addr; - size_t size; - mmap_rw("/init", addr, size); - raw_data_patch(addr, size, {make_pair(SPLIT_PLAT_CIL, "xxx")}); - munmap(addr, size); + auto init = raw_data::mmap_rw("/init"); + init.patch({ make_pair(SPLIT_PLAT_CIL, "xxx") }); } // Handle overlays @@ -267,10 +248,9 @@ void SARBase::patch_rootdir() { recreate_sbin(ROOTMIR "/sbin", true); // Patch init - raw_data init; int src = xopen("/init", O_RDONLY | O_CLOEXEC); - fd_full_read(src, init.buf, init.sz); - int patch_count = raw_data_patch(init.buf, init.sz, { + auto init = raw_data::read(src); + int patch_count = init.patch({ make_pair(SPLIT_PLAT_CIL, "xxx"), /* Force loading monolithic sepolicy */ make_pair(MONOPOLICY, sepol) /* Redirect /sepolicy to custom path */ }); @@ -283,9 +263,8 @@ void SARBase::patch_rootdir() { if (patch_count != 2 && access(LIBSELINUX, F_OK) == 0) { // init is dynamically linked, need to patch libselinux - raw_data lib; - full_read(LIBSELINUX, lib.buf, lib.sz); - raw_data_patch(lib.buf, lib.sz, {make_pair(MONOPOLICY, sepol)}); + auto lib = raw_data::read(LIBSELINUX); + lib.patch({make_pair(MONOPOLICY, sepol)}); xmkdirs(dirname(ROOTOVL LIBSELINUX), 0755); dest = xopen(ROOTOVL LIBSELINUX, O_CREAT | O_WRONLY | O_CLOEXEC, 0); xwrite(dest, lib.buf, lib.sz); @@ -341,11 +320,8 @@ void SARBase::patch_rootdir() { int magisk_proxy_main(int argc, char *argv[]) { setup_klog(); - raw_data config; - raw_data self; - - full_read("/sbin/magisk", self.buf, self.sz); - full_read("/.backup/.magisk", config.buf, config.sz); + auto config = raw_data::read("/sbin/magisk"); + auto self = raw_data::read("/.backup/.magisk"); xmount(nullptr, "/", nullptr, MS_REMOUNT, nullptr); diff --git a/native/jni/init/twostage.cpp b/native/jni/init/twostage.cpp index 8af4eb547..7abbdb510 100644 --- a/native/jni/init/twostage.cpp +++ b/native/jni/init/twostage.cpp @@ -108,14 +108,9 @@ void FirstStageInit::prepare() { sprintf(fstab_file, "fstab.%s", hw); } - // Patch init to force ignore dt fstab - uint8_t *addr; - size_t sz; - mmap_rw("/init", addr, sz); - raw_data_patch(addr, sz, { - make_pair("android,fstab", "xxx") /* Force IsDtFstabCompatible() to return false */ - }); - munmap(addr, sz); + // Patch init to force IsDtFstabCompatible() return false + auto init = raw_data::mmap_rw("/init"); + init.patch({ make_pair("android,fstab", "xxx") }); } { @@ -150,9 +145,8 @@ void SARFirstStageInit::prepare() { int src = xopen("/init", O_RDONLY); int dest = xopen("/dev/init", O_CREAT | O_WRONLY, 0); { - raw_data init; - fd_full_read(src, init.buf, init.sz); - raw_data_patch(init.buf, init.sz, { make_pair(INIT_PATH, REDIR_PATH) }); + auto init = raw_data::read(dest); + init.patch({ make_pair(INIT_PATH, REDIR_PATH) }); write(dest, init.buf, init.sz); fclone_attr(src, dest); close(dest); diff --git a/native/jni/magiskpolicy/policydb.cpp b/native/jni/magiskpolicy/policydb.cpp index 4560202a0..d444d1ccd 100644 --- a/native/jni/magiskpolicy/policydb.cpp +++ b/native/jni/magiskpolicy/policydb.cpp @@ -143,7 +143,7 @@ sepolicy *sepolicy::compile_split() { sprintf(path, SYSEXT_POLICY_DIR "mapping/%s.cil", plat_ver); if (access(path, R_OK) == 0) load_cil(db, path); - + cil_file = SYSEXT_POLICY_DIR "system_ext_sepolicy.cil"; if (access(cil_file, R_OK) == 0) load_cil(db, cil_file);