From 0dad06cdfec5df6cb235e831a93b7f4cb1ed5f33 Mon Sep 17 00:00:00 2001 From: LoveSy <631499712@qq.com> Date: Sat, 14 Aug 2021 13:29:12 +0800 Subject: [PATCH] Fix meizu compatibility --- native/jni/init/init.hpp | 52 ++++++++++++++++++++++--------------- native/jni/init/mount.cpp | 18 ++++++++++--- native/jni/init/rootdir.cpp | 12 +++++++-- native/jni/utils/files.cpp | 2 +- 4 files changed, 56 insertions(+), 28 deletions(-) diff --git a/native/jni/init/init.hpp b/native/jni/init/init.hpp index 17c30f684..8b7258cdf 100644 --- a/native/jni/init/init.hpp +++ b/native/jni/init/init.hpp @@ -42,8 +42,8 @@ void setup_klog(); class BaseInit { protected: - cmdline *cmd; - char **argv; + cmdline *cmd = nullptr; + char **argv = nullptr; [[noreturn]] void exec_init(); void read_dt_fstab(std::vector &fstab); @@ -67,7 +67,7 @@ public: MagiskInit(char *argv[], cmdline *cmd) : BaseInit(argv, cmd) {} }; -class SARBase : public MagiskInit { +class SARBase : virtual public MagiskInit { protected: std::vector overlays; @@ -75,7 +75,7 @@ protected: void patch_rootdir(); void mount_system_root(); public: - SARBase(char *argv[], cmdline *cmd) : MagiskInit(argv, cmd) {} + SARBase() = default; }; /*************** @@ -95,20 +95,6 @@ public: } }; -class SecondStageInit : public SARBase { -private: - void prepare(); -public: - SecondStageInit(char *argv[]) : SARBase(argv, nullptr) { - LOGD("%s\n", __FUNCTION__); - }; - void start() override { - prepare(); - patch_rootdir(); - exec_init(); - } -}; - /************* * Legacy SAR *************/ @@ -120,7 +106,7 @@ private: void early_mount(); void first_stage_prep(); public: - SARInit(char *argv[], cmdline *cmd) : SARBase(argv, cmd), is_two_stage(false) { + SARInit(char *argv[], cmdline *cmd) : MagiskInit(argv, cmd), is_two_stage(false) { LOGD("%s\n", __FUNCTION__); }; void start() override { @@ -137,10 +123,18 @@ public: * Initramfs ************/ -class RootFSInit : public MagiskInit { +class RootFSBase : virtual public MagiskInit { +protected: + void patch_rootfs(); +public: + RootFSBase() = default; + void start() = 0; +}; + +class RootFSInit : public RootFSBase { private: void early_mount(); - void patch_rootfs(); + public: RootFSInit(char *argv[], cmdline *cmd) : MagiskInit(argv, cmd) { LOGD("%s\n", __FUNCTION__); @@ -152,6 +146,22 @@ public: } }; +class SecondStageInit : public RootFSBase, public SARBase { +private: + bool prepare(); +public: + SecondStageInit(char *argv[]) : MagiskInit(argv, nullptr) { + LOGD("%s\n", __FUNCTION__); + }; + + void start() override { + if (prepare()) patch_rootfs(); + else patch_rootdir(); + exec_init(); + } +}; + + class MagiskProxy : public MagiskInit { public: explicit MagiskProxy(char *argv[]) : MagiskInit(argv, nullptr) { diff --git a/native/jni/init/mount.cpp b/native/jni/init/mount.cpp index 8fc15e78d..714c3d2d8 100644 --- a/native/jni/init/mount.cpp +++ b/native/jni/init/mount.cpp @@ -185,7 +185,7 @@ static void switch_root(const string &path) { }); for (auto &dir : mounts) { auto new_path = path + dir; - mkdir(new_path.data(), 0755); + xmkdir(new_path.data(), 0755); xmount(dir.data(), new_path.data(), nullptr, MS_MOVE, nullptr); } chdir(path.data()); @@ -355,14 +355,24 @@ void SARInit::early_mount() { } } -void SecondStageInit::prepare() { +bool SecondStageInit::prepare() { backup_files(); umount2("/init", MNT_DETACH); umount2("/proc/self/exe", MNT_DETACH); - if (access("/system_root", F_OK) == 0) - switch_root("/system_root"); + // some weird devices, like meizu, embrace two stage init but still have legacy rootfs behaviour + bool legacy = false; + if (access("/system_root", F_OK) == 0) { + if (access("/system_root/proc", F_OK) == 0) { + switch_root("/system_root"); + } else { + xmount("/system_root", "/system", nullptr, MS_MOVE, nullptr); + rmdir("/system_root"); + legacy = true; + } + } + return legacy; } void BaseInit::exec_init() { diff --git a/native/jni/init/rootdir.cpp b/native/jni/init/rootdir.cpp index daab2e164..6db917bf1 100644 --- a/native/jni/init/rootdir.cpp +++ b/native/jni/init/rootdir.cpp @@ -15,6 +15,10 @@ static vector rc_list; static void patch_init_rc(const char *src, const char *dest, const char *tmp_dir) { FILE *rc = xfopen(dest, "we"); + if (!rc) { + PLOGE("%s: open %s failed", __PRETTY_FUNCTION__, src); + return; + } file_readline(src, [=](string_view line) -> bool { // Do not start vaultkeeper if (str_contains(line, "start vaultkeeper")) { @@ -157,6 +161,7 @@ static string magic_mount_list; static void magic_mount(const string &sdir, const string &ddir = "") { auto dir = xopen_dir(sdir.data()); + if (!dir) return; for (dirent *entry; (entry = xreaddir(dir.get()));) { string src = sdir + "/" + entry->d_name; string dest = ddir + "/" + entry->d_name; @@ -321,7 +326,7 @@ void SARBase::patch_rootdir() { #define TMP_MNTDIR "/dev/mnt" #define TMP_RULESDIR "/.backup/.sepolicy.rules" -void RootFSInit::patch_rootfs() { +void RootFSBase::patch_rootfs() { // Create hardlink mirror of /sbin to /root mkdir("/root", 0777); clone_attr("/sbin", "/root"); @@ -338,8 +343,11 @@ void RootFSInit::patch_rootfs() { } if (patch_sepolicy("/sepolicy")) { - auto init = mmap_data::rw("/init"); + auto init = mmap_data::ro(access("/system/bin/init",F_OK) == 0 ? "/system/bin/init" : "/init"); init.patch({ make_pair(SPLIT_PLAT_CIL, "xxx") }); + int dest = xopen("/init", O_TRUNC | O_WRONLY | O_CLOEXEC, 0); + xwrite(dest, init.buf, init.sz); + close(dest); } // Handle overlays diff --git a/native/jni/utils/files.cpp b/native/jni/utils/files.cpp index 5a9cffd0a..525b4aea2 100644 --- a/native/jni/utils/files.cpp +++ b/native/jni/utils/files.cpp @@ -423,7 +423,7 @@ void restore_folder(const char *dir, vector &files) { mkdirs(path.data(), 0); } else if (S_ISREG(file.attr.st.st_mode)) { auto fp = xopen_file(path.data(), "we"); - fwrite(file.buf, 1, file.sz, fp.get()); + if (fp) fwrite(file.buf, 1, file.sz, fp.get()); } else if (S_ISLNK(file.attr.st.st_mode)) { symlink((char *)file.buf, path.data()); }