From 7681fde4d06e838db30c170764725f81c739821b Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Tue, 19 Nov 2019 00:16:20 -0500 Subject: [PATCH] Record mounts to be cleaned up in a vector --- native/jni/init/early_mount.cpp | 23 +++++++++-------------- native/jni/init/init.h | 16 +++++----------- native/jni/init/rootdir.cpp | 9 +++++---- native/jni/utils/misc.h | 21 ++++++++++++++++++++- 4 files changed, 39 insertions(+), 30 deletions(-) diff --git a/native/jni/init/early_mount.cpp b/native/jni/init/early_mount.cpp index eef42c888..672584ba2 100644 --- a/native/jni/init/early_mount.cpp +++ b/native/jni/init/early_mount.cpp @@ -84,6 +84,14 @@ static bool is_lnk(const char *name) { return S_ISLNK(st.st_mode); } +void BaseInit::cleanup() { + // Unmount in reverse order + for (auto &p : reversed(mount_list)) { + LOGD("Unmount [%s]\n", p.data()); + umount(p.data()); + } +} + bool MagiskInit::read_dt_fstab(const char *name, char *partname, char *fstype) { char path[128]; int fd; @@ -118,7 +126,7 @@ if (!is_lnk("/" #name) && read_dt_fstab(#name, partname, fstype)) { \ setup_block(partname, block_dev); \ xmkdir("/" #name, 0755); \ xmount(block_dev, "/" #name, fstype, MS_RDONLY, nullptr); \ - mnt_##name = true; \ + mount_list.emplace_back("/" #name); \ } void RootFSInit::early_mount() { @@ -237,16 +245,3 @@ void SecondStageInit::early_mount() { switch_root("/system_root"); } - -#define umount_root(name) \ -if (mnt_##name) \ - umount("/" #name); - -void MagiskInit::cleanup() { - umount(SELINUX_MNT); - BaseInit::cleanup(); - umount_root(system); - umount_root(vendor); - umount_root(product); - umount_root(odm); -} diff --git a/native/jni/init/init.h b/native/jni/init/init.h index fc03cb541..cb28a6ffa 100644 --- a/native/jni/init/init.h +++ b/native/jni/init/init.h @@ -1,6 +1,7 @@ #include #include #include +#include struct cmdline { bool system_as_root; @@ -34,19 +35,17 @@ class BaseInit { protected: cmdline *cmd; char **argv; + std::vector mount_list; void exec_init(const char *init = "/init") { cleanup(); execv(init, argv); exit(1); } - virtual void cleanup() { - umount("/sys"); - umount("/proc"); - umount("/dev"); - } + virtual void cleanup(); public: - BaseInit(char *argv[], cmdline *cmd) : cmd(cmd), argv(argv) {} + BaseInit(char *argv[], cmdline *cmd) : + cmd(cmd), argv(argv), mount_list{"/sys", "/proc", "/dev"} {} virtual ~BaseInit() = default; virtual void start() = 0; }; @@ -54,15 +53,10 @@ public: class MagiskInit : public BaseInit { protected: raw_data self; - bool mnt_system = false; - bool mnt_vendor = false; - bool mnt_product = false; - bool mnt_odm = false; virtual void early_mount() = 0; bool read_dt_fstab(const char *name, char *partname, char *fstype); bool patch_sepolicy(const char *file = "/sepolicy"); - void cleanup() override; public: MagiskInit(char *argv[], cmdline *cmd) : BaseInit(argv, cmd) {}; }; diff --git a/native/jni/init/rootdir.cpp b/native/jni/init/rootdir.cpp index 9c3afd1ba..9b59b34d7 100644 --- a/native/jni/init/rootdir.cpp +++ b/native/jni/init/rootdir.cpp @@ -167,6 +167,7 @@ bool MagiskInit::patch_sepolicy(const char *file) { // Mount selinuxfs to communicate with kernel xmount("selinuxfs", SELINUX_MNT, "selinuxfs", 0, nullptr); + mount_list.emplace_back(SELINUX_MNT); if (patch_init) load_split_cil(); @@ -230,7 +231,7 @@ static void sbin_overlay(const raw_data &self, const raw_data &config) { #define PATCHPOLICY "/sbin/.se" #define LIBSELINUX "/system/" LIBNAME "/libselinux.so" -static string mount_list; +static string magic_mount_list; static void magic_mount(int dirfd, const string &path) { DIR *dir = xfdopendir(dirfd); @@ -248,8 +249,8 @@ static void magic_mount(int dirfd, const string &path) { string src = ROOTOVL + dest; LOGD("Mount [%s] -> [%s]\n", src.data(), dest.data()); xmount(src.data(), dest.data(), nullptr, MS_BIND, nullptr); - mount_list += dest; - mount_list += '\n'; + magic_mount_list += dest; + magic_mount_list += '\n'; } } } @@ -379,7 +380,7 @@ void SARBase::patch_rootdir() { magic_mount(src, ""); close(src); dest = xopen(ROOTMNT, O_WRONLY | O_CREAT | O_CLOEXEC); - write(dest, mount_list.data(), mount_list.length()); + write(dest, magic_mount_list.data(), magic_mount_list.length()); close(dest); } diff --git a/native/jni/utils/misc.h b/native/jni/utils/misc.h index c5addb0fa..8733c0dfe 100644 --- a/native/jni/utils/misc.h +++ b/native/jni/utils/misc.h @@ -56,9 +56,28 @@ public: ~run_finally() { if (fn) fn(); } private: - std::function fn; + std::function fn; }; +template +class reversed_container { +public: + reversed_container(T &base) : base(base) {} + decltype(std::declval().rbegin()) begin() { return base.rbegin(); } + decltype(std::declval().crbegin()) begin() const { return base.crbegin(); } + decltype(std::declval().crbegin()) cbegin() const { return base.crbegin(); } + decltype(std::declval().rend()) end() { return base.rend(); } + decltype(std::declval().crend()) end() const { return base.crend(); } + decltype(std::declval().crend()) cend() const { return base.crend(); } +private: + T &base; +}; + +template +reversed_container reversed(T &base) { + return reversed_container(base); +} + static inline int parse_int(std::string s) { return parse_int(s.data()); } static inline int parse_int(std::string_view s) { return parse_int(s.data()); }