Record mounts to be cleaned up in a vector

This commit is contained in:
topjohnwu 2019-11-19 00:16:20 -05:00
parent d3b7b41927
commit 7681fde4d0
4 changed files with 39 additions and 30 deletions

View File

@ -84,6 +84,14 @@ static bool is_lnk(const char *name) {
return S_ISLNK(st.st_mode); 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) { bool MagiskInit::read_dt_fstab(const char *name, char *partname, char *fstype) {
char path[128]; char path[128];
int fd; int fd;
@ -118,7 +126,7 @@ if (!is_lnk("/" #name) && read_dt_fstab(#name, partname, fstype)) { \
setup_block(partname, block_dev); \ setup_block(partname, block_dev); \
xmkdir("/" #name, 0755); \ xmkdir("/" #name, 0755); \
xmount(block_dev, "/" #name, fstype, MS_RDONLY, nullptr); \ xmount(block_dev, "/" #name, fstype, MS_RDONLY, nullptr); \
mnt_##name = true; \ mount_list.emplace_back("/" #name); \
} }
void RootFSInit::early_mount() { void RootFSInit::early_mount() {
@ -237,16 +245,3 @@ void SecondStageInit::early_mount() {
switch_root("/system_root"); 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);
}

View File

@ -1,6 +1,7 @@
#include <sys/mount.h> #include <sys/mount.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <vector>
struct cmdline { struct cmdline {
bool system_as_root; bool system_as_root;
@ -34,19 +35,17 @@ class BaseInit {
protected: protected:
cmdline *cmd; cmdline *cmd;
char **argv; char **argv;
std::vector<std::string> mount_list;
void exec_init(const char *init = "/init") { void exec_init(const char *init = "/init") {
cleanup(); cleanup();
execv(init, argv); execv(init, argv);
exit(1); exit(1);
} }
virtual void cleanup() { virtual void cleanup();
umount("/sys");
umount("/proc");
umount("/dev");
}
public: 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 ~BaseInit() = default;
virtual void start() = 0; virtual void start() = 0;
}; };
@ -54,15 +53,10 @@ public:
class MagiskInit : public BaseInit { class MagiskInit : public BaseInit {
protected: protected:
raw_data self; raw_data self;
bool mnt_system = false;
bool mnt_vendor = false;
bool mnt_product = false;
bool mnt_odm = false;
virtual void early_mount() = 0; virtual void early_mount() = 0;
bool read_dt_fstab(const char *name, char *partname, char *fstype); bool read_dt_fstab(const char *name, char *partname, char *fstype);
bool patch_sepolicy(const char *file = "/sepolicy"); bool patch_sepolicy(const char *file = "/sepolicy");
void cleanup() override;
public: public:
MagiskInit(char *argv[], cmdline *cmd) : BaseInit(argv, cmd) {}; MagiskInit(char *argv[], cmdline *cmd) : BaseInit(argv, cmd) {};
}; };

View File

@ -167,6 +167,7 @@ bool MagiskInit::patch_sepolicy(const char *file) {
// Mount selinuxfs to communicate with kernel // Mount selinuxfs to communicate with kernel
xmount("selinuxfs", SELINUX_MNT, "selinuxfs", 0, nullptr); xmount("selinuxfs", SELINUX_MNT, "selinuxfs", 0, nullptr);
mount_list.emplace_back(SELINUX_MNT);
if (patch_init) if (patch_init)
load_split_cil(); load_split_cil();
@ -230,7 +231,7 @@ static void sbin_overlay(const raw_data &self, const raw_data &config) {
#define PATCHPOLICY "/sbin/.se" #define PATCHPOLICY "/sbin/.se"
#define LIBSELINUX "/system/" LIBNAME "/libselinux.so" #define LIBSELINUX "/system/" LIBNAME "/libselinux.so"
static string mount_list; static string magic_mount_list;
static void magic_mount(int dirfd, const string &path) { static void magic_mount(int dirfd, const string &path) {
DIR *dir = xfdopendir(dirfd); DIR *dir = xfdopendir(dirfd);
@ -248,8 +249,8 @@ static void magic_mount(int dirfd, const string &path) {
string src = ROOTOVL + dest; string src = ROOTOVL + dest;
LOGD("Mount [%s] -> [%s]\n", src.data(), dest.data()); LOGD("Mount [%s] -> [%s]\n", src.data(), dest.data());
xmount(src.data(), dest.data(), nullptr, MS_BIND, nullptr); xmount(src.data(), dest.data(), nullptr, MS_BIND, nullptr);
mount_list += dest; magic_mount_list += dest;
mount_list += '\n'; magic_mount_list += '\n';
} }
} }
} }
@ -379,7 +380,7 @@ void SARBase::patch_rootdir() {
magic_mount(src, ""); magic_mount(src, "");
close(src); close(src);
dest = xopen(ROOTMNT, O_WRONLY | O_CREAT | O_CLOEXEC); 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); close(dest);
} }

View File

@ -59,6 +59,25 @@ private:
std::function<void()> fn; std::function<void()> fn;
}; };
template <typename T>
class reversed_container {
public:
reversed_container(T &base) : base(base) {}
decltype(std::declval<T>().rbegin()) begin() { return base.rbegin(); }
decltype(std::declval<T>().crbegin()) begin() const { return base.crbegin(); }
decltype(std::declval<T>().crbegin()) cbegin() const { return base.crbegin(); }
decltype(std::declval<T>().rend()) end() { return base.rend(); }
decltype(std::declval<T>().crend()) end() const { return base.crend(); }
decltype(std::declval<T>().crend()) cend() const { return base.crend(); }
private:
T &base;
};
template <typename T>
reversed_container<T> reversed(T &base) {
return reversed_container<T>(base);
}
static inline int parse_int(std::string s) { return parse_int(s.data()); } 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()); } static inline int parse_int(std::string_view s) { return parse_int(s.data()); }