diff --git a/native/jni/magiskpolicy/policydb.cpp b/native/jni/magiskpolicy/policydb.cpp index ec115efb7..120c209ff 100644 --- a/native/jni/magiskpolicy/policydb.cpp +++ b/native/jni/magiskpolicy/policydb.cpp @@ -21,11 +21,12 @@ int load_policydb(const char *file) { pf.type = PF_USE_STDIO; magisk_policydb = static_cast(xmalloc(sizeof(policydb_t))); - if (policydb_init(magisk_policydb) || policydb_read(magisk_policydb, &pf, 0)) + if (policydb_init(magisk_policydb) || policydb_read(magisk_policydb, &pf, 0)) { + LOGE("Fail to load policy from %s\n", file); return 1; + } fclose(pf.fp); - return 0; } @@ -172,22 +173,27 @@ int compile_split_cil() { } int dump_policydb(const char *file) { - int fd, ret; - void *data = nullptr; + struct policy_file pf; + policy_file_init(&pf); + + uint8_t *data; size_t len; - policydb_to_image(nullptr, magisk_policydb, &data, &len); - if (data == nullptr) { - LOGE("Fail to dump policy image!\n"); + + pf.type = PF_USE_STDIO; + pf.fp = open_memfile(data, len); + if (policydb_write(magisk_policydb, &pf)) { + LOGE("Fail to create policy image\n"); return 1; } + fclose(pf.fp); - fd = xopen(file, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644); + int fd = xopen(file, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644); if (fd < 0) return 1; - ret = xwrite(fd, data, len); + xwrite(fd, data, len); + close(fd); - if (ret < 0) - return 1; + free(data); return 0; } diff --git a/native/jni/utils/file.cpp b/native/jni/utils/file.cpp index 42f8463b5..c85523359 100644 --- a/native/jni/utils/file.cpp +++ b/native/jni/utils/file.cpp @@ -407,3 +407,87 @@ void parse_mnt(const char *file, const function &fn) { } } } + +struct io_buf { + uint8_t *&buf; + size_t &len; + size_t cap = 0; + size_t pos = 0; + + io_buf(uint8_t *&buf, size_t &len) : buf(buf), len(len) { + buf = nullptr; + len = 0; + } + uint8_t *cur() { + return buf + pos; + } + int max_read() { + return len - pos; + } + void resize(int new_pos, bool zero = false) { + bool resize = false; + size_t old_cap = cap; + while (new_pos > cap) { + cap = cap ? (cap << 1) - (cap >> 1) : 1 << 12; + resize = true; + } + if (resize) { + buf = (uint8_t *) xrealloc(buf, cap); + if (zero) + memset(buf + old_cap, 0, cap - old_cap); + } + } +}; + +static int mem_read(void *v, char *buf, int len) { + auto io = reinterpret_cast(v); + len = std::min(len, io->max_read()); + memcpy(buf, io->cur(), len); + return len; +} + +static int mem_write(void *v, const char *buf, int len) { + auto io = reinterpret_cast(v); + io->resize(io->pos + len); + memcpy(io->cur(), buf, len); + io->pos += len; + io->len = std::max(io->len, io->pos); + return len; +} + +static fpos_t mem_seek(void *v, fpos_t off, int whence) { + auto io = reinterpret_cast(v); + off_t new_pos; + switch (whence) { + case SEEK_CUR: + new_pos = io->pos + off; + break; + case SEEK_END: + new_pos = io->len + off; + break; + case SEEK_SET: + new_pos = off; + break; + default: + return -1; + } + if (new_pos < 0) + return -1; + + io->resize(new_pos, true); + io->pos = new_pos; + return new_pos; +} + +static int mem_close(void *v) { + auto io = reinterpret_cast(v); + delete io; + return 0; +} + +FILE *open_memfile(uint8_t *&buf, size_t &len) { + auto io = new io_buf(buf, len); + FILE *fp = funopen(io, mem_read, mem_write, mem_seek, mem_close); + setbuf(fp, nullptr); + return fp; +} diff --git a/native/jni/utils/files.h b/native/jni/utils/files.h index e23fba6b1..a0c3a12fc 100644 --- a/native/jni/utils/files.h +++ b/native/jni/utils/files.h @@ -38,6 +38,7 @@ 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); +FILE *open_memfile(uint8_t *&buf, size_t &len); template void full_read(const char *filename, T &buf, size_t &size) {