From 548d70f30cf60c704f779732b277adc2414a31d0 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Tue, 1 Mar 2022 20:09:59 -0800 Subject: [PATCH] Mount with original option Fix #5481, close #5486 --- native/jni/core/bootstages.cpp | 46 +++++++++++++++++++++------------- native/jni/utils/misc.cpp | 18 ++++++++++--- native/jni/utils/misc.hpp | 3 ++- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/native/jni/core/bootstages.cpp b/native/jni/core/bootstages.cpp index 32a944915..5e0134ae3 100644 --- a/native/jni/core/bootstages.cpp +++ b/native/jni/core/bootstages.cpp @@ -29,21 +29,31 @@ bool zygisk_enabled = false; #define SETMIR(b, part) snprintf(b, sizeof(b), "%s/" MIRRDIR "/" #part, MAGISKTMP.data()) #define SETBLK(b, part) snprintf(b, sizeof(b), "%s/" BLOCKDIR "/" #part, MAGISKTMP.data()) -#define do_mount_mirror(part, flag) {\ - SETMIR(buf1, part); \ - SETBLK(buf2, part); \ - unlink(buf2); \ +#define do_mount_mirror(part) { \ + SETMIR(buf1, part); \ + SETBLK(buf2, part); \ + unlink(buf2); \ mknod(buf2, S_IFBLK | 0600, st.st_dev); \ - xmkdir(buf1, 0755); \ - xmount(buf2, buf1, me->mnt_type, flag, nullptr); \ - LOGI("mount: %s\n", buf1); \ + xmkdir(buf1, 0755); \ + int flags = 0; \ + auto opts = split_ro(me->mnt_opts, ",");\ + for (string_view s : opts) { \ + if (s == "ro") { \ + flags |= MS_RDONLY; \ + break; \ + } \ + } \ + xmount(buf2, buf1, me->mnt_type, flags, nullptr); \ + LOGI("mount: %s\n", buf1); \ } -#define mount_mirror(part, flag) \ -if (MNT_DIR_IS("/" #part) && !MNT_TYPE_IS("tmpfs") && !MNT_TYPE_IS("overlay") && \ - lstat(me->mnt_dir, &st) == 0) { \ - do_mount_mirror(part, flag); \ - break; \ +#define mount_mirror(part) \ +if (MNT_DIR_IS("/" #part) \ + && !MNT_TYPE_IS("tmpfs") \ + && !MNT_TYPE_IS("overlay") \ + && lstat(me->mnt_dir, &st) == 0) { \ + do_mount_mirror(part); \ + break; \ } #define link_mirror(part) \ @@ -73,11 +83,11 @@ static void mount_mirrors() { parse_mnt("/proc/mounts", [&](mntent *me) { struct stat st{}; do { - mount_mirror(system, MS_RDONLY) - mount_mirror(vendor, MS_RDONLY) - mount_mirror(product, MS_RDONLY) - mount_mirror(system_ext, MS_RDONLY) - mount_mirror(data, 0) + mount_mirror(system) + mount_mirror(vendor) + mount_mirror(product) + mount_mirror(system_ext) + mount_mirror(data) link_orig(cache) link_orig(metadata) link_orig(persist) @@ -96,7 +106,7 @@ static void mount_mirrors() { parse_mnt("/proc/mounts", [&](mntent *me) { struct stat st; if (MNT_DIR_IS("/") && me->mnt_type != "rootfs"sv && stat("/", &st) == 0) { - do_mount_mirror(system_root, MS_RDONLY) + do_mount_mirror(system_root) return false; } return true; diff --git a/native/jni/utils/misc.cpp b/native/jni/utils/misc.cpp index 3ac095b2f..56b5f8c65 100644 --- a/native/jni/utils/misc.cpp +++ b/native/jni/utils/misc.cpp @@ -189,15 +189,25 @@ string &replace_all(string &str, string_view from, string_view to) { return str; } -vector split(const string& s, const string& delimiters) { - vector result; +template +static auto split_impl(T s, T delims) { + vector> result; size_t base = 0; size_t found; while (true) { - found = s.find_first_of(delimiters, base); + found = s.find_first_of(delims, base); result.push_back(s.substr(base, found - base)); - if (found == string::npos) break; + if (found == string::npos) + break; base = found + 1; } return result; } + +vector split(const string &s, const string &delims) { + return split_impl(s, delims); +} + +vector split_ro(string_view s, string_view delims) { + return split_impl(s, delims); +} diff --git a/native/jni/utils/misc.hpp b/native/jni/utils/misc.hpp index 8a8828dcc..683094a50 100644 --- a/native/jni/utils/misc.hpp +++ b/native/jni/utils/misc.hpp @@ -159,7 +159,8 @@ uint32_t binary_gcd(uint32_t u, uint32_t v); int switch_mnt_ns(int pid); int gen_rand_str(char *buf, int len, bool varlen = true); std::string &replace_all(std::string &str, std::string_view from, std::string_view to); -std::vector split(const std::string& s, const std::string& delimiters); +std::vector split(const std::string &s, const std::string &delims); +std::vector split_ro(std::string_view, std::string_view delims); struct exec_t { bool err = false;