Commit 1443a5b1 authored by topjohnwu's avatar topjohnwu

Use mmap_data more widely

parent 2d82ad93
......@@ -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 \
......
......@@ -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");
}
......
#include <utils.hpp>
#include "raw_data.hpp"
using kv_pairs = std::vector<std::pair<std::string, std::string>>;
struct BootConfig {
......
......@@ -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() {
......
#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;
}
#pragma once
#include <utils.hpp>
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<std::pair<std::string_view, std::string_view>>;
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);
};
......@@ -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));
......
......@@ -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);
......
This diff is collapsed.
......@@ -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;
......
......@@ -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<char *>(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);
}
......
......@@ -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<uint8_t*>(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<uint8_t*>(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;
}
......
......@@ -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<uint8_t> pattern(strlen(from) / 2);
vector<uint8_t> 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<uint8_t*>(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;
......
......@@ -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[]);
......
......@@ -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") {
......
......@@ -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) {
......
......@@ -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) {
......
......@@ -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<uint8_t *>(b);
}
......@@ -26,16 +26,36 @@ struct file_attr {
char con[128];
};
struct raw_file {
struct byte_data {
using str_pairs = std::initializer_list<std::pair<std::string_view, std::string_view>>;
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<bool(std::string_view, std::string_view)> &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<bool(mntent*)> &fn);
......@@ -86,30 +105,6 @@ void fd_full_read(int fd, T &buf, size_t &size) {
fd_full_read(fd, reinterpret_cast<void**>(&buf), &size);
}
template <typename B>
void mmap_ro(const char *filename, B &buf, size_t &sz) {
buf = (B) __mmap(filename, &sz, false);
}
template <typename B, typename L>
void mmap_ro(const char *filename, B &buf, L &sz) {
size_t __sz;
buf = (B) __mmap(filename, &__sz, false);
sz = __sz;
}
template <typename B>
void mmap_rw(const char *filename, B &buf, size_t &sz) {
buf = (B) __mmap(filename, &sz, true);
}
template <typename B, typename L>
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<FILE, decltype(&fclose)>;
using sDIR = std::unique_ptr<DIR, decltype(&closedir)>;
sDIR make_dir(DIR *dp);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment