diff --git a/native/jni/Android.mk b/native/jni/Android.mk index 1307d6703..b45766b4d 100644 --- a/native/jni/Android.mk +++ b/native/jni/Android.mk @@ -56,7 +56,6 @@ LOCAL_SRC_FILES := \ init/rootdir.cpp \ init/getinfo.cpp \ init/twostage.cpp \ - init/raw_data.cpp \ core/socket.cpp \ magiskpolicy/sepolicy.cpp \ magiskpolicy/magiskpolicy.cpp \ diff --git a/native/jni/init/getinfo.cpp b/native/jni/init/getinfo.cpp index aa3c9a899..b385432df 100644 --- a/native/jni/init/getinfo.cpp +++ b/native/jni/init/getinfo.cpp @@ -252,7 +252,7 @@ bool check_two_stage() { if (access("/system/bin/init", F_OK) == 0) return true; // If we still have no indication, parse the original init and see what's up - auto init = mmap_data::ro(backup_init()); + auto init = mmap_data(backup_init()); return init.contains("selinux_setup"); } diff --git a/native/jni/init/init.hpp b/native/jni/init/init.hpp index 8b78137f3..409ed1d9f 100644 --- a/native/jni/init/init.hpp +++ b/native/jni/init/init.hpp @@ -1,7 +1,5 @@ #include -#include "raw_data.hpp" - using kv_pairs = std::vector>; struct BootConfig { diff --git a/native/jni/init/mount.cpp b/native/jni/init/mount.cpp index 32d7b17ad..a355f86ca 100644 --- a/native/jni/init/mount.cpp +++ b/native/jni/init/mount.cpp @@ -286,7 +286,7 @@ success: } void RootFSInit::early_mount() { - self = mmap_data::ro("/init"); + self = mmap_data("/init"); LOGD("Restoring /init\n"); rename(backup_init(), "/init"); @@ -298,9 +298,9 @@ void SARBase::backup_files() { if (access("/overlay.d", F_OK) == 0) backup_folder("/overlay.d", overlays); - self = mmap_data::ro("/proc/self/exe"); + self = mmap_data("/proc/self/exe"); if (access("/.backup/.magisk", R_OK) == 0) - magisk_config = mmap_data::ro("/.backup/.magisk"); + magisk_config = mmap_data("/.backup/.magisk"); } void SARBase::mount_system_root() { diff --git a/native/jni/init/raw_data.cpp b/native/jni/init/raw_data.cpp deleted file mode 100644 index 3fa1027ee..000000000 --- a/native/jni/init/raw_data.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "raw_data.hpp" - -using namespace std; - -int mmap_data::patch(str_pairs list) { - if (buf == nullptr) - return 0; - int count = 0; - for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) { - for (auto [from, to] : list) { - if (memcmp(p, from.data(), from.length() + 1) == 0) { - LOGD("Replace [%s] -> [%s]\n", from.data(), to.data()); - memset(p, 0, from.length()); - memcpy(p, to.data(), to.length()); - ++count; - p += from.length(); - } - } - } - return count; -} - -bool mmap_data::contains(string_view pattern) { - if (buf == nullptr) - return false; - for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) { - if (memcmp(p, pattern.data(), pattern.length() + 1) == 0) { - LOGD("Found pattern [%s]\n", pattern.data()); - return true; - } - } - return false; -} - -void mmap_data::consume(mmap_data &other) { - buf = other.buf; - sz = other.sz; - other.buf = nullptr; - other.sz = 0; -} - -mmap_data mmap_data::rw(const char *name) { - mmap_data data; - mmap_rw(name, data.buf, data.sz); - return data; -} - -mmap_data mmap_data::ro(const char *name) { - mmap_data data; - mmap_ro(name, data.buf, data.sz); - return data; -} diff --git a/native/jni/init/raw_data.hpp b/native/jni/init/raw_data.hpp deleted file mode 100644 index 6732ea826..000000000 --- a/native/jni/init/raw_data.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include - -struct mmap_data { - uint8_t *buf = nullptr; - size_t sz = 0; - - mmap_data() = default; - mmap_data(const mmap_data&) = delete; - mmap_data(mmap_data &&other) { consume(other); } - ~mmap_data() { if (buf) munmap(buf, sz); } - mmap_data& operator=(mmap_data &&other) { consume(other); return *this; } - - using str_pairs = std::initializer_list>; - int patch(str_pairs list); - bool contains(std::string_view pattern); - - static mmap_data rw(const char *name); - static mmap_data ro(const char *name); - -private: - void consume(mmap_data &other); -}; diff --git a/native/jni/init/rootdir.cpp b/native/jni/init/rootdir.cpp index 436748f0f..62077bd4a 100644 --- a/native/jni/init/rootdir.cpp +++ b/native/jni/init/rootdir.cpp @@ -183,7 +183,7 @@ static void patch_socket_name(const char *path) { static char rstr[16] = { 0 }; if (rstr[0] == '\0') gen_rand_str(rstr, sizeof(rstr)); - auto bin = mmap_data::rw(path); + auto bin = mmap_data(path, true); bin.patch({ make_pair(MAIN_SOCKET, rstr) }); } @@ -224,7 +224,7 @@ void SARBase::patch_rootdir() { int patch_count; { int src = xopen("/init", O_RDONLY | O_CLOEXEC); - auto init = mmap_data::ro("/init"); + auto init = mmap_data("/init"); patch_count = init.patch({ make_pair(SPLIT_PLAT_CIL, "xxx"), /* Force loading monolithic sepolicy */ make_pair(MONOPOLICY, sepol) /* Redirect /sepolicy to custom path */ @@ -248,8 +248,8 @@ void SARBase::patch_rootdir() { if (path) { char ovl[128]; sprintf(ovl, ROOTOVL "%s", path); - auto lib = mmap_data::ro(path); - lib.patch({make_pair(MONOPOLICY, sepol)}); + auto lib = mmap_data(path); + lib.patch({ make_pair(MONOPOLICY, sepol) }); xmkdirs(dirname(ovl), 0755); int dest = xopen(ovl, O_CREAT | O_WRONLY | O_CLOEXEC, 0); xwrite(dest, lib.buf, lib.sz); @@ -290,19 +290,19 @@ void SARBase::patch_rootdir() { xmkdirs(dirname(ROOTOVL NEW_INITRC), 0755); patch_init_rc(NEW_INITRC, ROOTOVL NEW_INITRC, tmp_dir.data()); } else { - patch_init_rc("/init.rc", ROOTOVL "/init.rc", tmp_dir.data()); + patch_init_rc("/init.rc", ROOTOVL "/init.rc", tmp_dir.data()); } // Extract magisk { - auto magisk = mmap_data::ro("magisk32.xz"); + auto magisk = mmap_data("magisk32.xz"); unlink("magisk32.xz"); int fd = xopen("magisk32", O_WRONLY | O_CREAT, 0755); unxz(fd, magisk.buf, magisk.sz); close(fd); patch_socket_name("magisk32"); if (access("magisk64.xz", F_OK) == 0) { - magisk = mmap_data::ro("magisk64.xz"); + magisk = mmap_data("magisk64.xz"); unlink("magisk64.xz"); fd = xopen("magisk64", O_WRONLY | O_CREAT, 0755); unxz(fd, magisk.buf, magisk.sz); @@ -344,13 +344,13 @@ void RootFSBase::patch_rootfs() { if (patch_sepolicy("/sepolicy")) { if (access("/system/bin/init", F_OK) == 0) { - auto init = mmap_data::ro("/system/bin/init"); + auto init = mmap_data("/system/bin/init"); init.patch({ make_pair(SPLIT_PLAT_CIL, "xxx") }); int dest = xopen("/init", O_TRUNC | O_WRONLY | O_CLOEXEC, 0); xwrite(dest, init.buf, init.sz); close(dest); } else { - auto init = mmap_data::rw("/init"); + auto init = mmap_data("/init", true); init.patch({ make_pair(SPLIT_PLAT_CIL, "xxx") }); } } @@ -376,10 +376,10 @@ void MagiskProxy::start() { xmount(nullptr, "/", nullptr, MS_REMOUNT, nullptr); // Backup stuffs before removing them - self = mmap_data::ro("/sbin/magisk"); - magisk_config = mmap_data::ro("/.backup/.magisk"); - auto magisk = mmap_data::ro("/sbin/magisk32.xz"); - auto magisk64 = mmap_data::ro("/sbin/magisk64.xz"); + self = mmap_data("/sbin/magisk"); + magisk_config = mmap_data("/.backup/.magisk"); + auto magisk = mmap_data("/sbin/magisk32.xz"); + auto magisk64 = mmap_data("/sbin/magisk64.xz"); char custom_rules_dir[64]; custom_rules_dir[0] = '\0'; xreadlink(TMP_RULESDIR, custom_rules_dir, sizeof(custom_rules_dir)); diff --git a/native/jni/init/twostage.cpp b/native/jni/init/twostage.cpp index 405f66fb2..b929435a1 100644 --- a/native/jni/init/twostage.cpp +++ b/native/jni/init/twostage.cpp @@ -122,7 +122,7 @@ exit_loop: } // Patch init to force IsDtFstabCompatible() return false - auto init = mmap_data::rw("/init"); + auto init = mmap_data("/init", true); init.patch({ make_pair("android,fstab", "xxx") }); } else { // Parse and load the fstab file @@ -192,7 +192,7 @@ void SARInit::first_stage_prep() { int src = xopen("/init", O_RDONLY); int dest = xopen("/dev/init", O_CREAT | O_WRONLY, 0); { - auto init = mmap_data::ro("/init"); + auto init = mmap_data("/init"); init.patch({ make_pair(INIT_PATH, REDIR_PATH) }); write(dest, init.buf, init.sz); fclone_attr(src, dest); diff --git a/native/jni/magiskboot/bootimg.cpp b/native/jni/magiskboot/bootimg.cpp index 7bd6b66d3..3b1d213df 100644 --- a/native/jni/magiskboot/bootimg.cpp +++ b/native/jni/magiskboot/bootimg.cpp @@ -148,11 +148,10 @@ void dyn_img_hdr::load_hdr_file() { }); } -boot_img::boot_img(const char *image) { - mmap_ro(image, map_addr, map_size); +boot_img::boot_img(const char *image) : map(image) { fprintf(stderr, "Parsing boot image: [%s]\n", image); - for (uint8_t *addr = map_addr; addr < map_addr + map_size; ++addr) { - format_t fmt = check_fmt(addr, map_size); + for (uint8_t *addr = map.buf; addr < map.buf + map.sz; ++addr) { + format_t fmt = check_fmt(addr, map.sz); switch (fmt) { case CHROMEOS: // chromeos require external signing @@ -182,7 +181,6 @@ boot_img::boot_img(const char *image) { } boot_img::~boot_img() { - munmap(map_addr, map_size); delete hdr; } @@ -405,9 +403,9 @@ void boot_img::parse_image(uint8_t *addr, format_t type) { fprintf(stderr, "%-*s [%s]\n", PADDING, "EXTRA_FMT", fmt2name[e_fmt]); } - if (addr + off < map_addr + map_size) { + if (addr + off < map.buf + map.sz) { tail = addr + off; - tail_size = map_addr + map_size - tail; + tail_size = map.buf + map.sz - tail; // Check special flags if (tail_size >= 16 && BUFFER_MATCH(tail, SEANDROID_MAGIC)) { @@ -434,21 +432,18 @@ void boot_img::parse_image(uint8_t *addr, format_t type) { } int split_image_dtb(const char *filename) { - uint8_t *buf; - size_t sz; - mmap_ro(filename, buf, sz); - run_finally f([=]{ munmap(buf, sz); }); + auto img = mmap_data(filename); - if (int off = find_dtb_offset(buf, sz); off > 0) { - format_t fmt = check_fmt_lg(buf, sz); + if (int off = find_dtb_offset(img.buf, img.sz); off > 0) { + format_t fmt = check_fmt_lg(img.buf, img.sz); if (COMPRESSED(fmt)) { int fd = creat(KERNEL_FILE, 0644); - decompress(fmt, fd, buf, off); + decompress(fmt, fd, img.buf, off); close(fd); } else { - dump(buf, off, KERNEL_FILE); + dump(img.buf, off, KERNEL_FILE); } - dump(buf + off, sz - off, KER_DTB_FILE); + dump(img.buf + off, img.sz - off, KER_DTB_FILE); return 0; } else { fprintf(stderr, "Cannot find DTB in %s\n", filename); @@ -546,11 +541,11 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { // Skip DHTB header write_zero(fd, sizeof(dhtb_hdr)); } else if (boot.flags[BLOB_FLAG]) { - xwrite(fd, boot.map_addr, sizeof(blob_hdr)); + xwrite(fd, boot.map.buf, sizeof(blob_hdr)); } else if (boot.flags[NOOKHD_FLAG]) { - xwrite(fd, boot.map_addr, NOOKHD_PRE_HEADER_SZ); + xwrite(fd, boot.map.buf, NOOKHD_PRE_HEADER_SZ); } else if (boot.flags[ACCLAIM_FLAG]) { - xwrite(fd, boot.map_addr, ACCLAIM_PRE_HEADER_SZ); + xwrite(fd, boot.map.buf, ACCLAIM_PRE_HEADER_SZ); } // Copy raw header @@ -568,15 +563,13 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { xwrite(fd, boot.z_hdr, boot.z_info.hdr_sz); } if (access(KERNEL_FILE, R_OK) == 0) { - size_t raw_size; - void *raw_buf; - mmap_ro(KERNEL_FILE, raw_buf, raw_size); - if (!COMPRESSED_ANY(check_fmt(raw_buf, raw_size)) && COMPRESSED(boot.k_fmt)) { + auto m = mmap_data(KERNEL_FILE); + if (!COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.k_fmt)) { // Always use zopfli for zImage compression auto fmt = (boot.flags[ZIMAGE_KERNEL] && boot.k_fmt == GZIP) ? ZOPFLI : boot.k_fmt; - hdr->kernel_size() = compress(fmt, fd, raw_buf, raw_size); + hdr->kernel_size() = compress(fmt, fd, m.buf, m.sz); } else { - hdr->kernel_size() = xwrite(fd, raw_buf, raw_size); + hdr->kernel_size() = xwrite(fd, m.buf, m.sz); } if (boot.flags[ZIMAGE_KERNEL]) { @@ -587,7 +580,7 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { } else { // Pad zeros to make sure the zImage file size does not change // Also ensure the last 4 bytes are the uncompressed vmlinux size - uint32_t sz = raw_size; + uint32_t sz = m.sz; write_zero(fd, boot.hdr->kernel_size() - hdr->kernel_size() - sizeof(sz)); xwrite(fd, &sz, sizeof(sz)); } @@ -595,8 +588,6 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { // zImage size shall remain the same hdr->kernel_size() = boot.hdr->kernel_size(); } - - munmap(raw_buf, raw_size); } if (boot.flags[ZIMAGE_KERNEL]) { // Copy zImage tail and adjust size accordingly @@ -616,15 +607,12 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { xwrite(fd, boot.r_hdr, sizeof(mtk_hdr)); } if (access(RAMDISK_FILE, R_OK) == 0) { - size_t raw_size; - void *raw_buf; - mmap_ro(RAMDISK_FILE, raw_buf, raw_size); - if (!skip_comp && !COMPRESSED_ANY(check_fmt(raw_buf, raw_size)) && COMPRESSED(boot.r_fmt)) { - hdr->ramdisk_size() = compress(boot.r_fmt, fd, raw_buf, raw_size); + auto m = mmap_data(RAMDISK_FILE); + if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.r_fmt)) { + hdr->ramdisk_size() = compress(boot.r_fmt, fd, m.buf, m.sz); } else { - hdr->ramdisk_size() = xwrite(fd, raw_buf, raw_size); + hdr->ramdisk_size() = xwrite(fd, m.buf, m.sz); } - munmap(raw_buf, raw_size); file_align(); } @@ -638,15 +626,12 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { // extra off.extra = lseek(fd, 0, SEEK_CUR); if (access(EXTRA_FILE, R_OK) == 0) { - size_t raw_size; - void *raw_buf; - mmap_ro(EXTRA_FILE, raw_buf, raw_size); - if (!skip_comp && !COMPRESSED_ANY(check_fmt(raw_buf, raw_size)) && COMPRESSED(boot.e_fmt)) { - hdr->extra_size() = compress(boot.e_fmt, fd, raw_buf, raw_size); + auto m = mmap_data(EXTRA_FILE); + if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.e_fmt)) { + hdr->extra_size() = compress(boot.e_fmt, fd, m.buf, m.sz); } else { - hdr->extra_size() = xwrite(fd, raw_buf, raw_size); + hdr->extra_size() = xwrite(fd, m.buf, m.sz); } - munmap(raw_buf, raw_size); file_align(); } @@ -696,8 +681,8 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { // Pad image to original size if not chromeos (as it requires post processing) if (!boot.flags[CHROMEOS_FLAG]) { off_t current = lseek(fd, 0, SEEK_CUR); - if (current < boot.map_size) { - write_zero(fd, boot.map_size - current); + if (current < boot.map.sz) { + write_zero(fd, boot.map.sz - current); } } @@ -708,18 +693,16 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { ******************/ // Map output image as rw - uint8_t *new_addr; - size_t new_size; - mmap_rw(out_img, new_addr, new_size); + auto out = mmap_data(out_img, true); // MTK headers if (boot.flags[MTK_KERNEL]) { - auto m_hdr = reinterpret_cast(new_addr + off.kernel); + auto m_hdr = reinterpret_cast(out.buf + off.kernel); m_hdr->size = hdr->kernel_size(); hdr->kernel_size() += sizeof(mtk_hdr); } if (boot.flags[MTK_RAMDISK]) { - auto m_hdr = reinterpret_cast(new_addr + off.ramdisk); + auto m_hdr = reinterpret_cast(out.buf + off.ramdisk); m_hdr->size = hdr->ramdisk_size(); hdr->ramdisk_size() += sizeof(mtk_hdr); } @@ -732,28 +715,28 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { HASH_CTX ctx; boot.flags[SHA256_FLAG] ? SHA256_init(&ctx) : SHA_init(&ctx); uint32_t size = hdr->kernel_size(); - HASH_update(&ctx, new_addr + off.kernel, size); + HASH_update(&ctx, out.buf + off.kernel, size); HASH_update(&ctx, &size, sizeof(size)); size = hdr->ramdisk_size(); - HASH_update(&ctx, new_addr + off.ramdisk, size); + HASH_update(&ctx, out.buf + off.ramdisk, size); HASH_update(&ctx, &size, sizeof(size)); size = hdr->second_size(); - HASH_update(&ctx, new_addr + off.second, size); + HASH_update(&ctx, out.buf + off.second, size); HASH_update(&ctx, &size, sizeof(size)); size = hdr->extra_size(); if (size) { - HASH_update(&ctx, new_addr + off.extra, size); + HASH_update(&ctx, out.buf + off.extra, size); HASH_update(&ctx, &size, sizeof(size)); } uint32_t ver = hdr->header_version(); if (ver == 1 || ver == 2) { size = hdr->recovery_dtbo_size(); - HASH_update(&ctx, new_addr + hdr->recovery_dtbo_offset(), size); + HASH_update(&ctx, out.buf + hdr->recovery_dtbo_offset(), size); HASH_update(&ctx, &size, sizeof(size)); } if (ver == 2) { size = hdr->dtb_size(); - HASH_update(&ctx, new_addr + off.dtb, size); + HASH_update(&ctx, out.buf + off.dtb, size); HASH_update(&ctx, &size, sizeof(size)); } memset(id, 0, BOOT_ID_SIZE); @@ -764,12 +747,12 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { hdr->print(); // Copy main header - memcpy(new_addr + off.header, hdr->raw_hdr(), hdr->hdr_size()); + memcpy(out.buf + off.header, hdr->raw_hdr(), hdr->hdr_size()); if (boot.flags[AVB_FLAG]) { // Copy and patch AVB structures - auto footer = reinterpret_cast(new_addr + new_size - sizeof(AvbFooter)); - auto vbmeta = reinterpret_cast(new_addr + off.vbmeta); + auto footer = reinterpret_cast(out.buf + out.sz - sizeof(AvbFooter)); + auto vbmeta = reinterpret_cast(out.buf + off.vbmeta); memcpy(footer, boot.avb_footer, sizeof(AvbFooter)); footer->original_image_size = __builtin_bswap64(off.total); footer->vbmeta_offset = __builtin_bswap64(off.vbmeta); @@ -780,15 +763,13 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { if (boot.flags[DHTB_FLAG]) { // DHTB header - auto d_hdr = reinterpret_cast(new_addr); + auto d_hdr = reinterpret_cast(out.buf); memcpy(d_hdr, DHTB_MAGIC, 8); d_hdr->size = off.total - sizeof(dhtb_hdr); - SHA256_hash(new_addr + sizeof(dhtb_hdr), d_hdr->size, d_hdr->checksum); + SHA256_hash(out.buf + sizeof(dhtb_hdr), d_hdr->size, d_hdr->checksum); } else if (boot.flags[BLOB_FLAG]) { // Blob header - auto b_hdr = reinterpret_cast(new_addr); + auto b_hdr = reinterpret_cast(out.buf); b_hdr->size = off.total - sizeof(blob_hdr); } - - munmap(new_addr, new_size); } diff --git a/native/jni/magiskboot/bootimg.hpp b/native/jni/magiskboot/bootimg.hpp index eb9f960bd..6f7097835 100644 --- a/native/jni/magiskboot/bootimg.hpp +++ b/native/jni/magiskboot/bootimg.hpp @@ -563,8 +563,7 @@ enum { struct boot_img { // Memory map of the whole image - uint8_t *map_addr; - size_t map_size; + mmap_data map; // Android image header dyn_img_hdr *hdr; diff --git a/native/jni/magiskboot/cpio.cpp b/native/jni/magiskboot/cpio.cpp index eca5cc8be..8b64c47da 100644 --- a/native/jni/magiskboot/cpio.cpp +++ b/native/jni/magiskboot/cpio.cpp @@ -151,12 +151,9 @@ void cpio::dump(FILE *out) { } void cpio::load_cpio(const char *file) { - char *buf; - size_t sz; - mmap_ro(file, buf, sz); fprintf(stderr, "Loading cpio: [%s]\n", file); - load_cpio(buf, sz); - munmap(buf, sz); + auto m = mmap_data(file); + load_cpio(reinterpret_cast(m.buf), m.sz); } void cpio::insert(string_view name, cpio_entry *e) { @@ -169,14 +166,11 @@ void cpio::insert(string_view name, cpio_entry *e) { } void cpio::add(mode_t mode, const char *name, const char *file) { - void *buf; - size_t sz; - mmap_ro(file, buf, sz); + auto m = mmap_data(file); auto e = new cpio_entry(S_IFREG | mode); - e->filesize = sz; - e->data = xmalloc(sz); - memcpy(e->data, buf, sz); - munmap(buf, sz); + e->filesize = m.sz; + e->data = xmalloc(m.sz); + memcpy(e->data, m.buf, m.sz); insert(name, e); fprintf(stderr, "Add entry [%s] (%04o)\n", name, mode); } diff --git a/native/jni/magiskboot/dtb.cpp b/native/jni/magiskboot/dtb.cpp index fa6f839c6..d8f0e4bc7 100644 --- a/native/jni/magiskboot/dtb.cpp +++ b/native/jni/magiskboot/dtb.cpp @@ -94,32 +94,29 @@ static int find_fstab(const void *fdt, int node = 0) { } static void dtb_print(const char *file, bool fstab) { - size_t size; - uint8_t *dtb; fprintf(stderr, "Loading dtbs from [%s]\n", file); - mmap_ro(file, dtb, size); + auto m = mmap_data(file); // Loop through all the dtbs int dtb_num = 0; - uint8_t * const end = dtb + size; - for (uint8_t *fdt = dtb; fdt < end;) { + uint8_t * const end = m.buf + m.sz; + for (uint8_t *fdt = m.buf; fdt < end;) { fdt = static_cast(memmem(fdt, end - fdt, DTB_MAGIC, sizeof(fdt32_t))); if (fdt == nullptr) break; if (fstab) { int node = find_fstab(fdt); if (node >= 0) { - fprintf(stderr, "Found fstab in dtb.%04d\n", dtb_num); + fprintf(stderr, "Found fstab in buf.%04d\n", dtb_num); print_node(fdt, node); } } else { - fprintf(stderr, "Printing dtb.%04d\n", dtb_num); + fprintf(stderr, "Printing buf.%04d\n", dtb_num); print_node(fdt); } ++dtb_num; fdt += fdt_totalsize(fdt); } fprintf(stderr, "\n"); - munmap(dtb, size); } [[maybe_unused]] @@ -128,14 +125,12 @@ static bool dtb_patch_rebuild(uint8_t *dtb, size_t dtb_sz, const char *file); static bool dtb_patch(const char *file) { bool keep_verity = check_env("KEEPVERITY"); - size_t size; - uint8_t *dtb; fprintf(stderr, "Loading dtbs from [%s]\n", file); - mmap_rw(file, dtb, size); + auto m = mmap_data(file, true); bool patched = false; - uint8_t * const end = dtb + size; - for (uint8_t *fdt = dtb; fdt < end;) { + uint8_t * const end = m.buf + m.sz; + for (uint8_t *fdt = m.buf; fdt < end;) { fdt = static_cast(memmem(fdt, end - fdt, DTB_MAGIC, sizeof(fdt32_t))); if (fdt == nullptr) break; @@ -165,8 +160,6 @@ static bool dtb_patch(const char *file) { } fdt += fdt_totalsize(fdt); } - - munmap(dtb, size); return patched; } diff --git a/native/jni/magiskboot/hexpatch.cpp b/native/jni/magiskboot/hexpatch.cpp index b32d99553..65ecb5849 100644 --- a/native/jni/magiskboot/hexpatch.cpp +++ b/native/jni/magiskboot/hexpatch.cpp @@ -15,13 +15,10 @@ static void hex2byte(const char *hex, uint8_t *buf) { } } -int hexpatch(const char *image, const char *from, const char *to) { +int hexpatch(const char *file, const char *from, const char *to) { int patched = 1; - uint8_t *buf; - size_t sz; - mmap_rw(image, buf, sz); - run_finally f([=]{ munmap(buf, sz); }); + auto m = mmap_data(file, true); vector pattern(strlen(from) / 2); vector patch(strlen(to) / 2); @@ -29,12 +26,12 @@ int hexpatch(const char *image, const char *from, const char *to) { hex2byte(from, pattern.data()); hex2byte(to, patch.data()); - uint8_t * const end = buf + sz; - for (uint8_t *curr = buf; curr < end; curr += pattern.size()) { + uint8_t * const end = m.buf + m.sz; + for (uint8_t *curr = m.buf; curr < end; curr += pattern.size()) { curr = static_cast(memmem(curr, end - curr, pattern.data(), pattern.size())); if (curr == nullptr) return patched; - fprintf(stderr, "Patch @ %08X [%s] -> [%s]\n", (unsigned)(curr - buf), from, to); + fprintf(stderr, "Patch @ %08X [%s] -> [%s]\n", (unsigned)(curr - m.buf), from, to); memset(curr, 0, pattern.size()); memcpy(curr, patch.data(), patch.size()); patched = 0; diff --git a/native/jni/magiskboot/magiskboot.hpp b/native/jni/magiskboot/magiskboot.hpp index 320e13616..eebc11df1 100644 --- a/native/jni/magiskboot/magiskboot.hpp +++ b/native/jni/magiskboot/magiskboot.hpp @@ -15,7 +15,7 @@ int unpack(const char *image, bool skip_decomp = false, bool hdr = false); void repack(const char *src_img, const char *out_img, bool skip_comp = false); int split_image_dtb(const char *filename); -int hexpatch(const char *image, const char *from, const char *to); +int hexpatch(const char *file, const char *from, const char *to); int cpio_commands(int argc, char *argv[]); int dtb_commands(int argc, char *argv[]); diff --git a/native/jni/magiskboot/main.cpp b/native/jni/magiskboot/main.cpp index 5cc88caf8..f55b52a5c 100644 --- a/native/jni/magiskboot/main.cpp +++ b/native/jni/magiskboot/main.cpp @@ -137,14 +137,11 @@ int main(int argc, char *argv[]) { unlink(DTB_FILE); } else if (argc > 2 && action == "sha1") { uint8_t sha1[SHA_DIGEST_SIZE]; - void *buf; - size_t size; - mmap_ro(argv[2], buf, size); - SHA_hash(buf, size, sha1); + auto m = mmap_data(argv[2]); + SHA_hash(m.buf, m.sz, sha1); for (uint8_t i : sha1) printf("%02x", i); printf("\n"); - munmap(buf, size); } else if (argc > 2 && action == "split") { return split_image_dtb(argv[2]); } else if (argc > 2 && action == "unpack") { diff --git a/native/jni/magiskpolicy/policydb.cpp b/native/jni/magiskpolicy/policydb.cpp index 380eea63d..24154e821 100644 --- a/native/jni/magiskpolicy/policydb.cpp +++ b/native/jni/magiskpolicy/policydb.cpp @@ -74,12 +74,9 @@ static bool check_precompiled(const char *precompiled) { } static void load_cil(struct cil_db *db, const char *file) { - char *addr; - size_t size; - mmap_ro(file, addr, size); - cil_add_file(db, (char *) file, addr, size); + auto d = mmap_data(file); + cil_add_file(db, (char *) file, (char *) d.buf, d.sz); LOGD("cil_add [%s]\n", file); - munmap(addr, size); } sepolicy *sepolicy::from_file(const char *file) { diff --git a/native/jni/resetprop/persist_properties.cpp b/native/jni/resetprop/persist_properties.cpp index ad0acd51b..410eed1e0 100644 --- a/native/jni/resetprop/persist_properties.cpp +++ b/native/jni/resetprop/persist_properties.cpp @@ -137,12 +137,9 @@ static void pb_getprop(prop_cb *prop_cb) { PersistentProperties props = {}; props.properties.funcs.decode = prop_decode; props.properties.arg = prop_cb; - pb_byte_t *buf; - size_t size; - mmap_ro(PERSISTENT_PROPERTY_DIR "/persistent_properties", buf, size); - pb_istream_t stream = pb_istream_from_buffer(buf, size); + auto m = mmap_data(PERSISTENT_PROPERTY_DIR "/persistent_properties"); + pb_istream_t stream = pb_istream_from_buffer(m.buf, m.sz); pb_decode(&stream, &PersistentProperties_msg, &props); - munmap(buf, size); } static bool file_getprop(const char *name, char *value) { diff --git a/native/jni/utils/files.cpp b/native/jni/utils/files.cpp index cbb8bd669..36584efce 100644 --- a/native/jni/utils/files.cpp +++ b/native/jni/utils/files.cpp @@ -272,28 +272,6 @@ void fclone_attr(int src, int dest) { fsetattr(dest, &a); } -void *__mmap(const char *filename, size_t *size, bool rw) { - int fd = xopen(filename, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC); - if (fd < 0) { - *size = 0; - return nullptr; - } - struct stat st; - if (fstat(fd, &st)) { - *size = 0; - return nullptr; - } - if (S_ISBLK(st.st_mode)) - ioctl(fd, BLKGETSIZE64, size); - else - *size = st.st_size; - void *buf = *size > 0 ? - xmmap(nullptr, *size, PROT_READ | PROT_WRITE, rw ? MAP_SHARED : MAP_PRIVATE, fd, 0) : - nullptr; - close(fd); - return buf; -} - void fd_full_read(int fd, void **buf, size_t *size) { *size = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); @@ -439,15 +417,58 @@ sFILE make_file(FILE *fp) { return sFILE(fp, [](FILE *fp){ return fp ? fclose(fp) : 1; }); } -raw_file::raw_file(raw_file &&o) { - path.swap(o.path); - attr = o.attr; - buf = o.buf; - sz = o.sz; - o.buf = nullptr; - o.sz = 0; +int byte_data::patch(bool log, str_pairs list) { + if (buf == nullptr) + return 0; + int count = 0; + for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) { + for (auto [from, to] : list) { + if (memcmp(p, from.data(), from.length() + 1) == 0) { + if (log) LOGD("Replace [%s] -> [%s]\n", from.data(), to.data()); + memset(p, 0, from.length()); + memcpy(p, to.data(), to.length()); + ++count; + p += from.length(); + } + } + } + return count; } -raw_file::~raw_file() { - free(buf); +bool byte_data::contains(string_view pattern, bool log) const { + if (buf == nullptr) + return false; + for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) { + if (memcmp(p, pattern.data(), pattern.length() + 1) == 0) { + if (log) LOGD("Found pattern [%s]\n", pattern.data()); + return true; + } + } + return false; +} + +void byte_data::swap(byte_data &o) { + std::swap(buf, o.buf); + std::swap(sz, o.sz); +} + +mmap_data::mmap_data(const char *name, bool rw) { + int fd = xopen(name, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC); + if (fd < 0) + return; + struct stat st; + if (fstat(fd, &st)) + return; + if (S_ISBLK(st.st_mode)) { + uint64_t size; + ioctl(fd, BLKGETSIZE64, &size); + sz = size; + } else { + sz = st.st_size; + } + void *b = sz > 0 + ? xmmap(nullptr, sz, PROT_READ | PROT_WRITE, rw ? MAP_SHARED : MAP_PRIVATE, fd, 0) + : nullptr; + close(fd); + buf = static_cast(b); } diff --git a/native/jni/utils/files.hpp b/native/jni/utils/files.hpp index 9e78c4afd..555ab1461 100644 --- a/native/jni/utils/files.hpp +++ b/native/jni/utils/files.hpp @@ -26,16 +26,36 @@ struct file_attr { char con[128]; }; -struct raw_file { +struct byte_data { + using str_pairs = std::initializer_list>; + + uint8_t *buf = nullptr; + size_t sz = 0; + + int patch(str_pairs list) { return patch(true, list); } + int patch(bool log, str_pairs list); + bool contains(std::string_view pattern, bool log = true) const; +protected: + void swap(byte_data &o); +}; + +struct raw_file : public byte_data { std::string path; file_attr attr; - uint8_t *buf; - size_t sz; - raw_file() : attr({}), buf(nullptr), sz(0) {} + raw_file() : attr{} {} raw_file(const raw_file&) = delete; - raw_file(raw_file &&o); - ~raw_file(); + raw_file(raw_file &&o) : path(std::move(o.path)), attr(o.attr) { swap(o); } + ~raw_file() { free(buf); } +}; + +struct mmap_data : public byte_data { + mmap_data() = default; + mmap_data(const mmap_data&) = delete; + mmap_data(mmap_data &&o) { swap(o); } + mmap_data(const char *name, bool rw = false); + ~mmap_data() { if (buf) munmap(buf, sz); } + mmap_data& operator=(mmap_data &&other) { swap(other); return *this; } }; ssize_t fd_path(int fd, char *path, size_t size); @@ -67,7 +87,6 @@ static inline void file_readline(const char *file, } void parse_prop_file(const char *file, const std::function &fn); -void *__mmap(const char *filename, size_t *size, bool rw); void frm_rf(int dirfd); void clone_dir(int src, int dest); void parse_mnt(const char *file, const std::function &fn); @@ -86,30 +105,6 @@ void fd_full_read(int fd, T &buf, size_t &size) { fd_full_read(fd, reinterpret_cast(&buf), &size); } -template -void mmap_ro(const char *filename, B &buf, size_t &sz) { - buf = (B) __mmap(filename, &sz, false); -} - -template -void mmap_ro(const char *filename, B &buf, L &sz) { - size_t __sz; - buf = (B) __mmap(filename, &__sz, false); - sz = __sz; -} - -template -void mmap_rw(const char *filename, B &buf, size_t &sz) { - buf = (B) __mmap(filename, &sz, true); -} - -template -void mmap_rw(const char *filename, B &buf, L &sz) { - size_t __sz; - buf = (B) __mmap(filename, &__sz, true); - sz = __sz; -} - using sFILE = std::unique_ptr; using sDIR = std::unique_ptr; sDIR make_dir(DIR *dp);