diff --git a/native/jni/core/bootstages.cpp b/native/jni/core/bootstages.cpp index 3a3c5a9fb..1b198ef9c 100644 --- a/native/jni/core/bootstages.cpp +++ b/native/jni/core/bootstages.cpp @@ -307,13 +307,13 @@ static int bind_mount(const char *from, const char *to, bool log) { #define MIRRMNT(part) MIRRDIR "/" #part #define PARTBLK(part) BLOCKDIR "/" #part +#define DIR_IS(part) (me->mnt_dir == "/" #part ""sv) #define mount_mirror(part, flag) { \ - sscanf(line.data(), "%s %*s %s", buf, buf2); \ - xstat(buf, &st); \ + xstat(me->mnt_fsname, &st); \ mknod(PARTBLK(part), (st.st_mode & S_IFMT) | 0600, st.st_rdev); \ xmkdir(MIRRMNT(part), 0755); \ - xmount(PARTBLK(part), MIRRMNT(part), buf2, flag, nullptr); \ + xmount(PARTBLK(part), MIRRMNT(part), me->mnt_type, flag, nullptr); \ VLOGI("mount", PARTBLK(part), MIRRMNT(part)); \ } @@ -364,21 +364,19 @@ static bool magisk_env() { LOGI("* Mounting mirrors"); bool system_as_root = false; struct stat st; - file_readline("/proc/mounts", [&](string_view line) -> bool { - if (str_contains(line, " /system_root ")) { + parse_mnt("/proc/mounts", [&](mntent *me) { + if (DIR_IS(system_root)) { mount_mirror(system_root, MS_RDONLY); xsymlink(MIRRMNT(system_root) "/system", MIRRMNT(system)); VLOGI("link", MIRRMNT(system_root) "/system", MIRRMNT(system)); system_as_root = true; - } else if (!system_as_root && str_contains(line, " /system ")) { + } else if (!system_as_root && DIR_IS(system)) { mount_mirror(system, MS_RDONLY); - } else if (str_contains(line, " /vendor ")) { + } else if (DIR_IS(vendor)) { mount_mirror(vendor, MS_RDONLY); - } else if (str_contains(line, " /data ") && !str_contains(line, "tmpfs")) { + } else if (DIR_IS(data) && me->mnt_type != "tmpfs"sv) { mount_mirror(data, 0); - } else if (SDK_INT >= 24 && - str_contains(line, " /proc ") && !str_contains(line, "hidepid=2")) { - // Enforce hidepid + } else if (SDK_INT >= 24 && DIR_IS(proc) && !strstr(me->mnt_opts, "hidepid=2")) { xmount(nullptr, "/proc", nullptr, MS_REMOUNT, "hidepid=2,gid=3009"); } return true; diff --git a/native/jni/magiskhide/hide_policy.cpp b/native/jni/magiskhide/hide_policy.cpp index e462c32d1..891b0ec3f 100644 --- a/native/jni/magiskhide/hide_policy.cpp +++ b/native/jni/magiskhide/hide_policy.cpp @@ -44,6 +44,9 @@ void hide_daemon(int pid) { hide_unmount(pid); } +#define TMPFS_MNT(dir) (mentry->mnt_type == "tmpfs"sv && \ +strncmp(mentry->mnt_dir, "/" #dir, sizeof("/" #dir) - 1) == 0) + void hide_unmount(int pid) { if (switch_mnt_ns(pid)) return; @@ -60,7 +63,7 @@ void hide_unmount(int pid) { chmod(SELINUX_POLICY, 0440); } - getprop([](const char *name, auto, auto) -> void { + getprop([](const char *name, auto, auto) { if (strstr(name, "magisk")) deleteprop(name); }, nullptr, false); @@ -68,14 +71,9 @@ void hide_unmount(int pid) { vector targets; // Unmount dummy skeletons and /sbin links - file_readline("/proc/self/mounts", [&](string_view s) -> bool { - if (str_contains(s, "tmpfs /system/") || str_contains(s, "tmpfs /vendor/") || - str_contains(s, "tmpfs /sbin")) { - char *path = (char *) s.data(); - // Skip first token - strtok_r(nullptr, " ", &path); - targets.emplace_back(strtok_r(nullptr, " ", &path)); - } + parse_mnt("/proc/self/mounts", [&](mntent *mentry) { + if (TMPFS_MNT(system) || TMPFS_MNT(vendor) || TMPFS_MNT(sbin)) + targets.emplace_back(mentry->mnt_dir); return true; }); @@ -84,13 +82,9 @@ void hide_unmount(int pid) { targets.clear(); // Unmount all Magisk created mounts - file_readline("/proc/self/mounts", [&](string_view s) -> bool { - if (str_contains(s, BLOCKDIR)) { - char *path = (char *) s.data(); - // Skip first token - strtok_r(nullptr, " ", &path); - targets.emplace_back(strtok_r(nullptr, " ", &path)); - } + parse_mnt("/proc/self/mounts", [&](mntent *mentry) { + if (strstr(mentry->mnt_fsname, BLOCKDIR)) + targets.emplace_back(mentry->mnt_dir); return true; }); diff --git a/native/jni/utils/file.cpp b/native/jni/utils/file.cpp index 9f92d0bde..b81f1e380 100644 --- a/native/jni/utils/file.cpp +++ b/native/jni/utils/file.cpp @@ -1,15 +1,15 @@ /* file.cpp - Contains all files related utilities */ +#include +#include +#include #include #include #include #include #include #include -#include -#include -#include #include #include @@ -396,3 +396,14 @@ void parse_prop_file(const char *file, const function &fn) { + unique_ptr fp(xfopen(file, "rce"), &fclose); + if (fp) { + mntent *mentry; + while ((mentry = getmntent(fp.get())) != nullptr) { + if (!fn(mentry)) + break; + } + } +} diff --git a/native/jni/utils/include/utils.h b/native/jni/utils/include/utils.h index 8574eb054..51fe19f68 100644 --- a/native/jni/utils/include/utils.h +++ b/native/jni/utils/include/utils.h @@ -3,13 +3,14 @@ #pragma once +#include +#include +#include #include #include #include #include -#include -#include -#include +#include #ifdef __cplusplus extern "C" { @@ -173,6 +174,7 @@ void parse_prop_file(const char *file, const std::function void *__mmap(const char *filename, size_t *size, bool rw); void frm_rf(int dirfd, std::initializer_list excl = std::initializer_list()); void clone_dir(int src, int dest, bool overwrite = true); +void parse_mnt(const char *file, const std::function &fn); template void mmap_ro(const char *filename, B &buf, size_t &sz) {