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);
}
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);
}

View File

@ -1,6 +1,7 @@
#include <sys/mount.h>
#include <unistd.h>
#include <stdlib.h>
#include <vector>
struct cmdline {
bool system_as_root;
@ -34,19 +35,17 @@ class BaseInit {
protected:
cmdline *cmd;
char **argv;
std::vector<std::string> 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) {};
};

View File

@ -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);
}

View File

@ -59,6 +59,25 @@ private:
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_view s) { return parse_int(s.data()); }