From 46275b90c27865ee4fb9f243cd2e7002de8516f9 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 21 Sep 2023 05:47:21 -0700 Subject: [PATCH] Generalize unxz --- native/src/init/init.cpp | 20 ++++---------------- native/src/init/init.hpp | 4 ++-- native/src/init/rootdir.cpp | 9 ++++++--- native/src/init/selinux.cpp | 14 ++++++++++++-- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/native/src/init/init.cpp b/native/src/init/init.cpp index 9b6ad4721..65a21b9a3 100644 --- a/native/src/init/init.cpp +++ b/native/src/init/init.cpp @@ -12,12 +12,13 @@ using namespace std; -bool unxz(int fd, const uint8_t *buf, size_t size) { +bool unxz(out_stream &strm, rust::Slice bytes) { uint8_t out[8192]; xz_crc32_init(); + size_t size = bytes.size(); struct xz_dec *dec = xz_dec_init(XZ_DYNALLOC, 1 << 26); struct xz_buf b = { - .in = buf, + .in = bytes.data(), .in_pos = 0, .in_size = size, .out = out, @@ -29,20 +30,11 @@ bool unxz(int fd, const uint8_t *buf, size_t size) { ret = xz_dec_run(dec, &b); if (ret != XZ_OK && ret != XZ_STREAM_END) return false; - write(fd, out, b.out_pos); + strm.write(out, b.out_pos); b.out_pos = 0; } while (b.in_pos != size); return true; -} -static int dump_bin(const uint8_t *buf, size_t sz, const char *path, mode_t mode) { - int fd = xopen(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, mode); - if (fd < 0) - return 1; - if (!unxz(fd, buf, sz)) - return 1; - close(fd); - return 0; } void restore_ramdisk_init() { @@ -59,10 +51,6 @@ void restore_ramdisk_init() { } } -int dump_preload(const char *path, mode_t mode) { - return dump_bin(init_ld_xz, sizeof(init_ld_xz), path, mode); -} - class RecoveryInit : public BaseInit { public: using BaseInit::BaseInit; diff --git a/native/src/init/init.hpp b/native/src/init/init.hpp index 96592421e..e5c5e2d01 100644 --- a/native/src/init/init.hpp +++ b/native/src/init/init.hpp @@ -1,4 +1,5 @@ #include +#include #include "init-rs.hpp" @@ -26,12 +27,11 @@ struct BootConfig { extern std::vector mount_list; int magisk_proxy_main(int argc, char *argv[]); -bool unxz(int fd, const uint8_t *buf, size_t size); +bool unxz(out_stream &strm, rust::Slice bytes); void load_kernel_info(BootConfig *config); bool check_two_stage(); const char *backup_init(); void restore_ramdisk_init(); -int dump_preload(const char *path, mode_t mode); /*************** * Base classes diff --git a/native/src/init/rootdir.cpp b/native/src/init/rootdir.cpp index 9b2d3d649..ac058f587 100644 --- a/native/src/init/rootdir.cpp +++ b/native/src/init/rootdir.cpp @@ -167,14 +167,16 @@ static void extract_files(bool sbin) { mmap_data magisk(m32); unlink(m32); int fd = xopen("magisk32", O_WRONLY | O_CREAT, 0755); - unxz(fd, magisk.buf(), magisk.sz()); + fd_channel ch(fd); + unxz(ch, magisk); close(fd); } if (access(m64, F_OK) == 0) { mmap_data magisk(m64); unlink(m64); int fd = xopen("magisk64", O_WRONLY | O_CREAT, 0755); - unxz(fd, magisk.buf(), magisk.sz()); + fd_channel ch(fd); + unxz(ch, magisk); close(fd); xsymlink("./magisk64", "magisk"); } else { @@ -184,7 +186,8 @@ static void extract_files(bool sbin) { mmap_data stub(stub_xz); unlink(stub_xz); int fd = xopen("stub.apk", O_WRONLY | O_CREAT, 0); - unxz(fd, stub.buf(), stub.sz()); + fd_channel ch(fd); + unxz(ch, stub); close(fd); } } diff --git a/native/src/init/selinux.cpp b/native/src/init/selinux.cpp index 4ddb92350..2eff10411 100644 --- a/native/src/init/selinux.cpp +++ b/native/src/init/selinux.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include "init.hpp" @@ -38,6 +38,16 @@ void MagiskInit::patch_sepolicy(const char *in, const char *out) { } } +static void dump_preload() { + int fd = xopen("/dev/preload.so", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644); + if (fd < 0) + return; + fd_channel ch(fd); + if (!unxz(ch, byte_view(init_ld_xz, sizeof(init_ld_xz)))) + return; + close(fd); +} + #define MOCK_COMPAT SELINUXMOCK "/compatible" #define MOCK_LOAD SELINUXMOCK "/load" #define MOCK_ENFORCE SELINUXMOCK "/enforce" @@ -50,7 +60,7 @@ bool MagiskInit::hijack_sepolicy() { // This meant that instead of going through convoluted methods trying to alter // and block init's control flow, we can just LD_PRELOAD and replace the // security_load_policy function with our own implementation. - dump_preload("/dev/preload.so", 0644); + dump_preload(); setenv("LD_PRELOAD", "/dev/preload.so", 1); }