diff --git a/native/src/base/misc.cpp b/native/src/base/misc.cpp index 0dc6189f6..267ea9404 100644 --- a/native/src/base/misc.cpp +++ b/native/src/base/misc.cpp @@ -33,23 +33,29 @@ int fork_no_orphan() { return 0; } -int gen_rand_str(char *buf, int len, bool varlen) { - constexpr char ALPHANUM[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - static std::mt19937 gen([]{ - if (access("/dev/urandom", F_OK) != 0) - mknod("/dev/urandom", 0600 | S_IFCHR, makedev(1, 9)); - int fd = xopen("/dev/urandom", O_RDONLY | O_CLOEXEC); - unsigned seed; - xxread(fd, &seed, sizeof(seed)); +int gen_rand_str(char *buf, int len, const void *seed_buf, bool varlen) { + static mt19937_64 gen([&] { + mt19937_64::result_type seed; + if (seed_buf == nullptr) { + int fd = xopen("/dev/urandom", O_RDONLY | O_CLOEXEC); + xxread(fd, &seed, sizeof(seed)); + close(fd); + } else { + memcpy(&seed, seed_buf, sizeof(seed)); + } return seed; }()); - std::uniform_int_distribution dist(0, sizeof(ALPHANUM) - 2); + + if (len == 0) + return 0; if (varlen) { std::uniform_int_distribution len_dist(len / 2, len); len = len_dist(gen); } - for (int i = 0; i < len - 1; ++i) - buf[i] = ALPHANUM[dist(gen)]; + std::uniform_int_distribution alphabet('a', 'z'); + for (int i = 0; i < len - 1; ++i) { + buf[i] = static_cast(alphabet(gen)); + } buf[len - 1] = '\0'; return len - 1; } @@ -134,19 +140,36 @@ void set_nice_name(const char *name) { prctl(PR_SET_NAME, name); } +template +static T parse_num(string_view s, int base) { + T acc = 0; + for (char c: s) { + if (isdigit(c)) { + c -= '0'; + } else if (base > 10 && isalpha(c)) { + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + } else { + return -1; + } + if (c >= base) { + return -1; + } + acc *= base; + acc += c; + } + return acc; +} + /* * Bionic's atoi runs through strtol(). * Use our own implementation for faster conversion. */ int parse_int(string_view s) { - int val = 0; - for (char c : s) { - if (!c) break; - if (c > '9' || c < '0') - return -1; - val = val * 10 + c - '0'; - } - return val; + return parse_num(s, 10); +} + +uint64_t parse_uint64_hex(string_view s) { + return parse_num(s, 16); } uint32_t binary_gcd(uint32_t u, uint32_t v) { diff --git a/native/src/base/misc.hpp b/native/src/base/misc.hpp index c193a2c12..dc47cd3a4 100644 --- a/native/src/base/misc.hpp +++ b/native/src/base/misc.hpp @@ -125,6 +125,7 @@ rust::Slice byte_slice(T *buf, size_t sz) { return rust::Slice(reinterpret_cast(buf), sz); } +uint64_t parse_uint64_hex(std::string_view s); int parse_int(std::string_view s); using thread_entry = void *(*)(void *); @@ -158,7 +159,7 @@ void init_argv0(int argc, char **argv); void set_nice_name(const char *name); uint32_t binary_gcd(uint32_t u, uint32_t v); int switch_mnt_ns(int pid); -int gen_rand_str(char *buf, int len, bool varlen = true); +int gen_rand_str(char *buf, int len, const void *seed_buf = nullptr, bool varlen = true); std::string &replace_all(std::string &str, std::string_view from, std::string_view to); std::vector split(const std::string &s, const std::string &delims); std::vector split_ro(std::string_view, std::string_view delims); diff --git a/native/src/init/rootdir.cpp b/native/src/init/rootdir.cpp index 7a84e151c..73056dfcc 100644 --- a/native/src/init/rootdir.cpp +++ b/native/src/init/rootdir.cpp @@ -199,13 +199,17 @@ static void extract_files(bool sbin) { } void MagiskInit::parse_config_file() { - parse_prop_file("/data/.backup/.magisk", [this](auto key, auto value) -> bool { + uint64_t seed = 0; + parse_prop_file("/data/.backup/.magisk", [&](auto key, auto value) -> bool { if (key == "PREINITDEVICE") { preinit_dev = value; - return false; + } else if (key == "RANDOMSEED") { + value.remove_prefix(2); // 0x + seed = parse_uint64_hex(value); } return true; }); + gen_rand_str(nullptr, 0, &seed); } #define ROOTMIR MIRRDIR "/system_root" @@ -220,7 +224,7 @@ void MagiskInit::patch_ro_root() { if (access("/sbin", F_OK) == 0) { tmp_dir = "/sbin"; } else { - char buf[8]; + char buf[16]; gen_rand_str(buf, sizeof(buf)); tmp_dir = "/dev/"s + buf; xmkdir(tmp_dir.data(), 0); diff --git a/native/src/su/connect.cpp b/native/src/su/connect.cpp index 68595fb92..cc36c9422 100644 --- a/native/src/su/connect.cpp +++ b/native/src/su/connect.cpp @@ -194,7 +194,7 @@ int app_request(const su_context &ctx) { // Create FIFO char fifo[64]; strcpy(fifo, "/dev/socket/"); - gen_rand_str(fifo + 12, 32, true); + gen_rand_str(fifo + 12, 32); mkfifo(fifo, 0600); chown(fifo, ctx.info->mgr_uid, ctx.info->mgr_uid); setfilecon(fifo, "u:object_r:" SEPOL_FILE_TYPE ":s0"); diff --git a/scripts/avd_patch.sh b/scripts/avd_patch.sh index 1508cab1e..fa4fa8a35 100644 --- a/scripts/avd_patch.sh +++ b/scripts/avd_patch.sh @@ -70,6 +70,8 @@ fi # For API 28, we also patch advancedFeatures.ini to disable SAR # Manually override skip_initramfs by setting RECOVERYMODE=true [ $API = "28" ] && echo 'RECOVERYMODE=true' >> config +RANDOMSEED=$(tr -dc 'a-f0-9' < /dev/urandom | head -c 16) +echo "RANDOMSEED=0x$RANDOMSEED" >> config ./magiskboot compress=xz magisk32 magisk32.xz ./magiskboot compress=xz magisk64 magisk64.xz diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index 1a42f7d77..7616cd564 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -173,6 +173,8 @@ if [ -n "$PREINITDEVICE" ]; then echo "PREINITDEVICE=$PREINITDEVICE" >> config fi [ -n "$SHA1" ] && echo "SHA1=$SHA1" >> config +RANDOMSEED=$(tr -dc 'a-f0-9' < /dev/urandom | head -c 16) +echo "RANDOMSEED=0x$RANDOMSEED" >> config ./magiskboot cpio ramdisk.cpio \ "add 0750 $INIT magiskinit" \