From d2c2456fbef6cff0491c88808a479f4a9de12485 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Sat, 5 Feb 2022 15:19:12 +0800 Subject: [PATCH] Don't use `getmntent_r` from system's libc Fix #5354 Co-authored-by: topjohnwu --- native/jni/core/bootstages.cpp | 51 +++++++++++++++++------------- native/jni/utils/compat/compat.cpp | 26 --------------- native/jni/utils/files.cpp | 29 ++++++++++++++++- 3 files changed, 57 insertions(+), 49 deletions(-) diff --git a/native/jni/core/bootstages.cpp b/native/jni/core/bootstages.cpp index 93c6a103f..ac202bc22 100644 --- a/native/jni/core/bootstages.cpp +++ b/native/jni/core/bootstages.cpp @@ -25,6 +25,7 @@ bool zygisk_enabled = false; *********/ #define MNT_DIR_IS(dir) (me->mnt_dir == string_view(dir)) +#define MNT_TYPE_IS(type) (me->mnt_type == string_view(type)) #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()) @@ -38,9 +39,12 @@ bool zygisk_enabled = false; LOGI("mount: %s\n", buf1); \ } -#define mount_mirror(part, flag) \ -else if (MNT_DIR_IS("/" #part) && me->mnt_type != "tmpfs"sv && me->mnt_type != "overlay"sv && lstat(me->mnt_dir, &st) == 0) \ - do_mount_mirror(part, flag) +#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 link_mirror(part) \ SETMIR(buf1, part); \ @@ -50,11 +54,12 @@ if (access("/system/" #part, F_OK) == 0 && access(buf1, F_OK) != 0) { \ } #define link_orig_dir(dir, part) \ -else if (MNT_DIR_IS(dir) && me->mnt_type != "tmpfs"sv && me->mnt_type != "overlay"sv) { \ - SETMIR(buf1, part); \ - rmdir(buf1); \ - xsymlink(dir, buf1); \ - LOGI("link: %s\n", buf1); \ +if (MNT_DIR_IS(dir) && !MNT_TYPE_IS("tmpfs") && !MNT_TYPE_IS("overlay")) { \ + SETMIR(buf1, part); \ + rmdir(buf1); \ + xsymlink(dir, buf1); \ + LOGI("link: %s\n", buf1); \ + break; \ } #define link_orig(part) link_orig_dir("/" #part, part) @@ -66,20 +71,22 @@ static void mount_mirrors() { LOGI("* Mounting mirrors\n"); parse_mnt("/proc/mounts", [&](mntent *me) { - struct stat st; - if (0) {} - 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) - link_orig(cache) - link_orig(metadata) - link_orig(persist) - link_orig_dir("/mnt/vendor/persist", persist) - else if (SDK_INT >= 24 && MNT_DIR_IS("/proc") && !strstr(me->mnt_opts, "hidepid=2")) { - xmount(nullptr, "/proc", nullptr, MS_REMOUNT, "hidepid=2,gid=3009"); - } + 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) + link_orig(cache) + link_orig(metadata) + link_orig(persist) + link_orig_dir("/mnt/vendor/persist", persist) + if (SDK_INT >= 24 && MNT_DIR_IS("/proc") && !strstr(me->mnt_opts, "hidepid=2")) { + xmount(nullptr, "/proc", nullptr, MS_REMOUNT, "hidepid=2,gid=3009"); + break; + } + } while (false); return true; }); SETMIR(buf1, system); diff --git a/native/jni/utils/compat/compat.cpp b/native/jni/utils/compat/compat.cpp index 4d5083e5e..e208e53d8 100644 --- a/native/jni/utils/compat/compat.cpp +++ b/native/jni/utils/compat/compat.cpp @@ -53,32 +53,6 @@ ssize_t getline(char **buf, size_t *bufsiz, FILE *fp) { return getdelim(buf, bufsiz, '\n', fp); } -// Original source: https://android.googlesource.com/platform/bionic/+/master/libc/bionic/mntent.cpp -// License: AOSP, full copyright notice please check original source - -struct mntent *getmntent_r(FILE *fp, struct mntent *e, char *buf, int buf_len) { - memset(e, 0, sizeof(*e)); - while (fgets(buf, buf_len, fp) != nullptr) { - // Entries look like "proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0". - // That is: mnt_fsname mnt_dir mnt_type mnt_opts 0 0. - int fsname0, fsname1, dir0, dir1, type0, type1, opts0, opts1; - if (sscanf(buf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d", - &fsname0, &fsname1, &dir0, &dir1, &type0, &type1, &opts0, &opts1, - &e->mnt_freq, &e->mnt_passno) == 2) { - e->mnt_fsname = &buf[fsname0]; - buf[fsname1] = '\0'; - e->mnt_dir = &buf[dir0]; - buf[dir1] = '\0'; - e->mnt_type = &buf[type0]; - buf[type1] = '\0'; - e->mnt_opts = &buf[opts0]; - buf[opts1] = '\0'; - return e; - } - } - return nullptr; -} - FILE *setmntent(const char *path, const char *mode) { return fopen(path, mode); } diff --git a/native/jni/utils/files.cpp b/native/jni/utils/files.cpp index 36584efce..83ca0e5ee 100644 --- a/native/jni/utils/files.cpp +++ b/native/jni/utils/files.cpp @@ -352,12 +352,39 @@ void parse_prop_file(const char *file, const functionmnt_freq, &e->mnt_passno) == 2) { + e->mnt_fsname = &buf[fsname0]; + buf[fsname1] = '\0'; + e->mnt_dir = &buf[dir0]; + buf[dir1] = '\0'; + e->mnt_type = &buf[type0]; + buf[type1] = '\0'; + e->mnt_opts = &buf[opts0]; + buf[opts1] = '\0'; + return e; + } + } + return nullptr; +} + void parse_mnt(const char *file, const function &fn) { auto fp = sFILE(setmntent(file, "re"), endmntent); if (fp) { mntent mentry{}; char buf[4096]; - while (getmntent_r(fp.get(), &mentry, buf, sizeof(buf))) { + // getmntent_r from system's libc.so is broken on old platform + // use the compat one instead + while (compat_getmntent_r(fp.get(), &mentry, buf, sizeof(buf))) { if (!fn(&mentry)) break; }