mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-22 07:57:39 +00:00
Remove usage of MAGISKTMP
This commit is contained in:
parent
3ba00858e6
commit
16ae4aedf1
@ -262,9 +262,9 @@ std::vector<std::string> split(std::string_view s, std::string_view delims);
|
||||
std::vector<std::string_view> split_view(std::string_view, std::string_view delims);
|
||||
|
||||
// Similar to vsnprintf, but the return value is the written number of bytes
|
||||
int vssprintf(char *dest, size_t size, const char *fmt, va_list ap);
|
||||
__printflike(3, 0) int vssprintf(char *dest, size_t size, const char *fmt, va_list ap);
|
||||
// Similar to snprintf, but the return value is the written number of bytes
|
||||
int ssprintf(char *dest, size_t size, const char *fmt, ...);
|
||||
__printflike(3, 4) int ssprintf(char *dest, size_t size, const char *fmt, ...);
|
||||
// This is not actually the strscpy from the Linux kernel.
|
||||
// Silently truncates, and returns the number of bytes written.
|
||||
extern "C" size_t strscpy(char *dest, const char *src, size_t size);
|
||||
|
@ -45,21 +45,24 @@ static bool mount_mirror(const std::string_view from, const std::string_view to)
|
||||
static void mount_mirrors() {
|
||||
LOGI("* Mounting mirrors\n");
|
||||
auto self_mount_info = parse_mount_info("self");
|
||||
char path[64];
|
||||
|
||||
// Bind remount module root to clear nosuid
|
||||
if (access(SECURE_DIR, F_OK) == 0 || SDK_INT < 24) {
|
||||
auto dest = MAGISKTMP + "/" MODULEMNT;
|
||||
ssprintf(path, sizeof(path), "%s/" MODULEMNT, get_magisk_tmp());
|
||||
xmkdir(SECURE_DIR, 0700);
|
||||
xmkdir(MODULEROOT, 0755);
|
||||
xmkdir(dest.data(), 0755);
|
||||
xmount(MODULEROOT, dest.data(), nullptr, MS_BIND, nullptr);
|
||||
xmount(nullptr, dest.data(), nullptr, MS_REMOUNT | MS_BIND | MS_RDONLY, nullptr);
|
||||
xmount(nullptr, dest.data(), nullptr, MS_PRIVATE, nullptr);
|
||||
xmkdir(path, 0755);
|
||||
xmount(MODULEROOT, path, nullptr, MS_BIND, nullptr);
|
||||
xmount(nullptr, path, nullptr, MS_REMOUNT | MS_BIND | MS_RDONLY, nullptr);
|
||||
xmount(nullptr, path, nullptr, MS_PRIVATE, nullptr);
|
||||
chmod(SECURE_DIR, 0700);
|
||||
}
|
||||
|
||||
// Check and mount preinit mirror
|
||||
if (struct stat st{}; stat((MAGISKTMP + "/" PREINITDEV).data(), &st) == 0 && (st.st_mode & S_IFBLK)) {
|
||||
char dev_path[64];
|
||||
ssprintf(dev_path, sizeof(dev_path), "%s/" PREINITDEV, get_magisk_tmp());
|
||||
if (struct stat st{}; stat(dev_path, &st) == 0 && S_ISBLK(st.st_mode)) {
|
||||
// DO NOT mount the block device directly, as we do not know the flags and configs
|
||||
// to properly mount the partition; mounting block devices directly as rw could cause
|
||||
// crashes if the filesystem driver is crap (e.g. some broken F2FS drivers).
|
||||
@ -67,6 +70,7 @@ static void mount_mirrors() {
|
||||
// mount point mounting our desired partition, and then bind mount the target folder.
|
||||
dev_t preinit_dev = st.st_rdev;
|
||||
bool mounted = false;
|
||||
ssprintf(path, sizeof(path), "%s/" PREINITMIRR, get_magisk_tmp());
|
||||
for (const auto &info: self_mount_info) {
|
||||
if (info.root == "/" && info.device == preinit_dev) {
|
||||
auto flags = split_view(info.fs_option, ",");
|
||||
@ -76,29 +80,28 @@ static void mount_mirrors() {
|
||||
if (!rw) continue;
|
||||
string preinit_dir = resolve_preinit_dir(info.target.data());
|
||||
xmkdir(preinit_dir.data(), 0700);
|
||||
auto mirror_dir = MAGISKTMP + "/" PREINITMIRR;
|
||||
if ((mounted = mount_mirror(preinit_dir, mirror_dir))) {
|
||||
xmount(nullptr, mirror_dir.data(), nullptr, MS_UNBINDABLE, nullptr);
|
||||
if ((mounted = mount_mirror(preinit_dir, path))) {
|
||||
xmount(nullptr, path, nullptr, MS_UNBINDABLE, nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!mounted) {
|
||||
LOGW("preinit mirror not mounted %u:%u\n", major(preinit_dev), minor(preinit_dev));
|
||||
unlink((MAGISKTMP + "/" PREINITDEV).data());
|
||||
unlink(dev_path);
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare worker
|
||||
auto worker_dir = MAGISKTMP + "/" WORKERDIR;
|
||||
xmount("worker", worker_dir.data(), "tmpfs", 0, "mode=755");
|
||||
xmount(nullptr, worker_dir.data(), nullptr, MS_PRIVATE, nullptr);
|
||||
ssprintf(path, sizeof(path), "%s/" WORKERDIR, get_magisk_tmp());
|
||||
xmount("worker", path, "tmpfs", 0, "mode=755");
|
||||
xmount(nullptr, path, nullptr, MS_PRIVATE, nullptr);
|
||||
|
||||
// Recursively bind mount / to mirror dir
|
||||
if (auto mirror_dir = MAGISKTMP + "/" MIRRDIR; !mount_mirror("/", mirror_dir)) {
|
||||
if (auto mirror_dir = get_magisk_tmp() + "/"s MIRRDIR; !mount_mirror("/", mirror_dir)) {
|
||||
LOGI("fallback to mount subtree\n");
|
||||
// rootfs may fail, fallback to bind mount each mount point
|
||||
set<string, greater<>> mounted_dirs {{ MAGISKTMP }};
|
||||
set<string, greater<>> mounted_dirs {{ get_magisk_tmp() }};
|
||||
for (const auto &info: self_mount_info) {
|
||||
if (info.type == "rootfs"sv) continue;
|
||||
// the greatest mount point that less than info.target, which is possibly a parent
|
||||
@ -231,13 +234,13 @@ static bool magisk_env() {
|
||||
if (access(DATABIN "/busybox", X_OK))
|
||||
return false;
|
||||
|
||||
sprintf(buf, "%s/" BBPATH "/busybox", MAGISKTMP.data());
|
||||
ssprintf(buf, sizeof(buf), "%s/" BBPATH "/busybox", get_magisk_tmp());
|
||||
mkdir(dirname(buf), 0755);
|
||||
cp_afc(DATABIN "/busybox", buf);
|
||||
exec_command_async(buf, "--install", "-s", dirname(buf));
|
||||
|
||||
if (access(DATABIN "/magiskpolicy", X_OK) == 0) {
|
||||
sprintf(buf, "%s/magiskpolicy", MAGISKTMP.data());
|
||||
ssprintf(buf, sizeof(buf), "%s/magiskpolicy", get_magisk_tmp());
|
||||
cp_afc(DATABIN "/magiskpolicy", buf);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
using namespace std;
|
||||
|
||||
int SDK_INT = -1;
|
||||
string MAGISKTMP;
|
||||
|
||||
bool RECOVERY_MODE = false;
|
||||
|
||||
@ -328,9 +327,6 @@ static void daemon_entry() {
|
||||
}
|
||||
|
||||
// Get self stat
|
||||
char buf[64];
|
||||
xreadlink("/proc/self/exe", buf, sizeof(buf));
|
||||
MAGISKTMP = dirname(buf);
|
||||
xstat("/proc/self/exe", &self_st);
|
||||
|
||||
// Get API level
|
||||
@ -353,9 +349,11 @@ static void daemon_entry() {
|
||||
restore_tmpcon();
|
||||
|
||||
// Cleanups
|
||||
auto mount_list = MAGISKTMP + "/" ROOTMNT;
|
||||
if (access(mount_list.data(), F_OK) == 0) {
|
||||
file_readline(true, mount_list.data(), [](string_view line) -> bool {
|
||||
const char *tmp = get_magisk_tmp();
|
||||
char path[64];
|
||||
ssprintf(path, sizeof(path), "%s/" ROOTMNT, tmp);
|
||||
if (access(path, F_OK) == 0) {
|
||||
file_readline(true, path, [](string_view line) -> bool {
|
||||
umount2(line.data(), MNT_DETACH);
|
||||
return true;
|
||||
});
|
||||
@ -364,11 +362,12 @@ static void daemon_entry() {
|
||||
xmount(nullptr, "/", nullptr, MS_REMOUNT | MS_RDONLY, nullptr);
|
||||
unsetenv("REMOUNT_ROOT");
|
||||
}
|
||||
rm_rf((MAGISKTMP + "/" ROOTOVL).data());
|
||||
ssprintf(path, sizeof(path), "%s/" ROOTOVL, tmp);
|
||||
rm_rf(path);
|
||||
|
||||
// Load config status
|
||||
auto config = MAGISKTMP + "/" MAIN_CONFIG;
|
||||
parse_prop_file(config.data(), [](auto key, auto val) -> bool {
|
||||
ssprintf(path, sizeof(path), "%s/" MAIN_CONFIG, tmp);
|
||||
parse_prop_file(path, [](auto key, auto val) -> bool {
|
||||
if (key == "RECOVERYMODE" && val == "true")
|
||||
RECOVERY_MODE = true;
|
||||
return true;
|
||||
@ -376,22 +375,22 @@ static void daemon_entry() {
|
||||
|
||||
// Use isolated devpts if kernel support
|
||||
if (access("/dev/pts/ptmx", F_OK) == 0) {
|
||||
auto pts = MAGISKTMP + "/" SHELLPTS;
|
||||
if (access(pts.data(), F_OK)) {
|
||||
xmkdirs(pts.data(), 0755);
|
||||
xmount("devpts", pts.data(), "devpts",
|
||||
MS_NOSUID | MS_NOEXEC, "newinstance");
|
||||
auto ptmx = pts + "/ptmx";
|
||||
if (access(ptmx.data(), F_OK)) {
|
||||
xumount(pts.data());
|
||||
rmdir(pts.data());
|
||||
ssprintf(path, sizeof(path), "%s/" SHELLPTS, tmp);
|
||||
if (access(path, F_OK)) {
|
||||
xmkdirs(path, 0755);
|
||||
xmount("devpts", path, "devpts", MS_NOSUID | MS_NOEXEC, "newinstance");
|
||||
char ptmx[64];
|
||||
ssprintf(ptmx, sizeof(ptmx), "%s/ptmx", path);
|
||||
if (access(ptmx, F_OK)) {
|
||||
xumount(path);
|
||||
rmdir(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
sockaddr_un addr = {.sun_family = AF_LOCAL};
|
||||
strcpy(addr.sun_path, (MAGISKTMP + "/" MAIN_SOCKET).data());
|
||||
ssprintf(addr.sun_path, sizeof(addr.sun_path), "%s/" MAIN_SOCKET, tmp);
|
||||
unlink(addr.sun_path);
|
||||
if (xbind(fd, (sockaddr *) &addr, sizeof(addr)))
|
||||
exit(1);
|
||||
|
@ -170,7 +170,7 @@ void tmpfs_node::mount() {
|
||||
else
|
||||
src_path = parent()->node_path().data();
|
||||
if (!isa<tmpfs_node>(parent())) {
|
||||
auto worker_dir = MAGISKTMP + "/" WORKERDIR + dest;
|
||||
auto worker_dir = get_magisk_tmp() + "/"s WORKERDIR + dest;
|
||||
mkdirs(worker_dir.data(), 0);
|
||||
create_and_mount(skip_mirror() ? "replace" : "tmpfs", worker_dir);
|
||||
} else {
|
||||
@ -190,7 +190,7 @@ public:
|
||||
explicit magisk_node(const char *name) : node_entry(name, DT_REG, this) {}
|
||||
|
||||
void mount() override {
|
||||
const string src = MAGISKTMP + "/" + name();
|
||||
const string src = get_magisk_tmp() + "/"s + name();
|
||||
if (access(src.data(), F_OK))
|
||||
return;
|
||||
|
||||
@ -236,7 +236,7 @@ int app_process_64 = -1;
|
||||
if (access("/system/bin/app_process" #bit, F_OK) == 0) { \
|
||||
app_process_##bit = xopen("/system/bin/app_process" #bit, O_RDONLY | O_CLOEXEC); \
|
||||
string zbin = zygisk_bin + "/app_process" #bit; \
|
||||
string mbin = MAGISKTMP + "/magisk" #bit; \
|
||||
string mbin = get_magisk_tmp() + "/magisk"s #bit; \
|
||||
int src = xopen(mbin.data(), O_RDONLY | O_CLOEXEC); \
|
||||
int out = xopen(zbin.data(), O_CREAT | O_WRONLY | O_CLOEXEC, 0); \
|
||||
xsendfile(out, src, nullptr, INT_MAX); \
|
||||
@ -247,8 +247,8 @@ if (access("/system/bin/app_process" #bit, F_OK) == 0) {
|
||||
}
|
||||
|
||||
void load_modules() {
|
||||
node_entry::mirror_dir = MAGISKTMP + "/" MIRRDIR;
|
||||
node_entry::module_mnt = MAGISKTMP + "/" MODULEMNT "/";
|
||||
node_entry::mirror_dir = get_magisk_tmp() + "/"s MIRRDIR;
|
||||
node_entry::module_mnt = get_magisk_tmp() + "/"s MODULEMNT "/";
|
||||
|
||||
auto root = make_unique<root_node>("");
|
||||
auto system = new root_node("system");
|
||||
@ -258,7 +258,7 @@ void load_modules() {
|
||||
LOGI("* Loading modules\n");
|
||||
for (const auto &m : *module_list) {
|
||||
const char *module = m.name.data();
|
||||
char *b = buf + sprintf(buf, "%s/" MODULEMNT "/%s/", MAGISKTMP.data(), module);
|
||||
char *b = buf + ssprintf(buf, sizeof(buf), "%s/" MODULEMNT "/%s/", get_magisk_tmp(), module);
|
||||
|
||||
// Read props
|
||||
strcpy(b, "system.prop");
|
||||
@ -284,7 +284,7 @@ void load_modules() {
|
||||
system->collect_module_files(module, fd);
|
||||
close(fd);
|
||||
}
|
||||
if (MAGISKTMP != "/sbin" || !str_contains(getenv("PATH") ?: "", "/sbin")) {
|
||||
if (get_magisk_tmp() != "/sbin"sv || !str_contains(getenv("PATH") ?: "", "/sbin")) {
|
||||
// Need to inject our binaries into /system/bin
|
||||
inject_magisk_bins(system);
|
||||
}
|
||||
@ -306,14 +306,14 @@ void load_modules() {
|
||||
|
||||
// Mount on top of modules to enable zygisk
|
||||
if (zygisk_enabled) {
|
||||
string zygisk_bin = MAGISKTMP + "/" ZYGISKBIN;
|
||||
string zygisk_bin = get_magisk_tmp() + "/"s ZYGISKBIN;
|
||||
mkdir(zygisk_bin.data(), 0);
|
||||
mount_zygisk(32)
|
||||
mount_zygisk(64)
|
||||
}
|
||||
|
||||
auto worker_dir = MAGISKTMP + "/" WORKERDIR;
|
||||
xmount(nullptr, worker_dir.data(), nullptr, MS_REMOUNT | MS_RDONLY, nullptr);
|
||||
ssprintf(buf, sizeof(buf), "%s/" WORKERDIR, get_magisk_tmp());
|
||||
xmount(nullptr, buf, nullptr, MS_REMOUNT | MS_RDONLY, nullptr);
|
||||
}
|
||||
|
||||
/************************
|
||||
@ -448,7 +448,7 @@ void handle_modules() {
|
||||
}
|
||||
|
||||
static int check_rules_dir(char *buf, size_t sz) {
|
||||
int off = ssprintf(buf, sz, "%s/%s", MAGISKTMP.data(), PREINITMIRR);
|
||||
int off = ssprintf(buf, sz, "%s/" PREINITMIRR, get_magisk_tmp());
|
||||
struct stat st1{};
|
||||
struct stat st2{};
|
||||
if (xstat(buf, &st1) < 0 || xstat(MODULEROOT, &st2) < 0)
|
||||
|
@ -73,7 +73,7 @@ vector<bool> get_app_no_list() {
|
||||
|
||||
void preserve_stub_apk() {
|
||||
mutex_guard g(pkg_lock);
|
||||
string stub_path = MAGISKTMP + "/stub.apk";
|
||||
string stub_path = get_magisk_tmp() + "/stub.apk"s;
|
||||
stub_apk_fd = xopen(stub_path.data(), O_RDONLY | O_CLOEXEC);
|
||||
unlink(stub_path.data());
|
||||
auto cert = read_certificate(stub_apk_fd, -1);
|
||||
|
@ -15,15 +15,17 @@ using namespace std;
|
||||
|
||||
static const char *bbpath() {
|
||||
static string path;
|
||||
if (path.empty())
|
||||
path = MAGISKTMP + "/" BBPATH "/busybox";
|
||||
if (path.empty()) {
|
||||
path = get_magisk_tmp();
|
||||
path += "/" BBPATH "/busybox";
|
||||
}
|
||||
return path.data();
|
||||
}
|
||||
|
||||
static void set_script_env() {
|
||||
setenv("ASH_STANDALONE", "1", 1);
|
||||
char new_path[4096];
|
||||
sprintf(new_path, "%s:%s", getenv("PATH"), MAGISKTMP.data());
|
||||
ssprintf(new_path, sizeof(new_path), "%s:%s", getenv("PATH"), get_magisk_tmp());
|
||||
setenv("PATH", new_path, 1);
|
||||
if (zygisk_enabled)
|
||||
setenv("ZYGISK_ENABLED", "1", 1);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <magisk.hpp>
|
||||
#include <base.hpp>
|
||||
#include <selinux.hpp>
|
||||
#include <daemon.hpp>
|
||||
#include <flags.h>
|
||||
|
||||
using namespace std;
|
||||
@ -121,17 +122,18 @@ void restorecon() {
|
||||
}
|
||||
|
||||
void restore_tmpcon() {
|
||||
if (MAGISKTMP == "/sbin")
|
||||
setfilecon(MAGISKTMP.data(), ROOT_CON);
|
||||
const char *tmp = get_magisk_tmp();
|
||||
if (tmp == "/sbin"sv)
|
||||
setfilecon(tmp, ROOT_CON);
|
||||
else
|
||||
chmod(MAGISKTMP.data(), 0711);
|
||||
chmod(tmp, 0711);
|
||||
|
||||
auto dir = xopen_dir(MAGISKTMP.data());
|
||||
auto dir = xopen_dir(tmp);
|
||||
int dfd = dirfd(dir.get());
|
||||
|
||||
for (dirent *entry; (entry = xreaddir(dir.get()));)
|
||||
setfilecon_at(dfd, entry->d_name, SYSTEM_CON);
|
||||
|
||||
string logd = MAGISKTMP + "/" LOG_PIPE;
|
||||
string logd = tmp + "/"s LOG_PIPE;
|
||||
setfilecon(logd.data(), MAGISK_FILE_CON);
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ void app_notify(const su_context &ctx) {
|
||||
int app_request(const su_context &ctx) {
|
||||
// Create FIFO
|
||||
char fifo[64];
|
||||
ssprintf(fifo, sizeof(fifo), "%s/" INTLROOT "/su_request_%d", MAGISKTMP.data(), ctx.pid);
|
||||
ssprintf(fifo, sizeof(fifo), "%s/" INTLROOT "/su_request_%d", get_magisk_tmp(), ctx.pid);
|
||||
mkfifo(fifo, 0600);
|
||||
chown(fifo, ctx.info->mgr_uid, ctx.info->mgr_uid);
|
||||
setfilecon(fifo, MAGISK_FILE_CON);
|
||||
|
@ -342,7 +342,7 @@ void su_daemon_handler(int client, const sock_cred *cred) {
|
||||
if (read_int(client)) {
|
||||
string pts;
|
||||
string ptmx;
|
||||
auto magiskpts = MAGISKTMP + "/" SHELLPTS;
|
||||
auto magiskpts = get_magisk_tmp() + "/"s SHELLPTS;
|
||||
if (access(magiskpts.data(), F_OK)) {
|
||||
pts = "/dev/pts";
|
||||
ptmx = "/dev/ptmx";
|
||||
|
@ -10,7 +10,6 @@
|
||||
#define MAGISKDB SECURE_DIR "/magisk.db"
|
||||
|
||||
// tmpfs paths
|
||||
extern std::string MAGISKTMP;
|
||||
#define INTLROOT ".magisk"
|
||||
#define MIRRDIR INTLROOT "/mirror"
|
||||
#define PREINITMIRR INTLROOT "/preinit"
|
||||
|
@ -52,10 +52,7 @@ extern "C" void zygisk_inject_entry(void *handle) {
|
||||
unsetenv("LD_PRELOAD");
|
||||
}
|
||||
|
||||
MAGISKTMP = getenv(MAGISKTMP_ENV);
|
||||
self_handle = handle;
|
||||
|
||||
unsetenv(MAGISKTMP_ENV);
|
||||
sanitize_environ();
|
||||
hook_functions();
|
||||
}
|
||||
@ -128,12 +125,13 @@ static void connect_companion(int client, bool is_64_bit) {
|
||||
socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds);
|
||||
zygiskd_socket = fds[0];
|
||||
if (fork_dont_care() == 0) {
|
||||
string exe = MAGISKTMP + "/magisk" + (is_64_bit ? "64" : "32");
|
||||
char exe[64];
|
||||
ssprintf(exe, sizeof(exe), "%s/magisk%s", get_magisk_tmp(), (is_64_bit ? "64" : "32"));
|
||||
// This fd has to survive exec
|
||||
fcntl(fds[1], F_SETFD, 0);
|
||||
char buf[16];
|
||||
ssprintf(buf, sizeof(buf), "%d", fds[1]);
|
||||
execl(exe.data(), "", "zygisk", "companion", buf, (char *) nullptr);
|
||||
execl(exe, "", "zygisk", "companion", buf, (char *) nullptr);
|
||||
exit(-1);
|
||||
}
|
||||
close(fds[1]);
|
||||
@ -170,11 +168,11 @@ static void setup_files(int client, const sock_cred *cred) {
|
||||
bool is_64_bit = str_ends(buf, "64");
|
||||
if (is_64_bit) {
|
||||
hbin = HIJACK_BIN64;
|
||||
mbin = MAGISKTMP + "/" ZYGISKBIN "/loader64.so";
|
||||
mbin = get_magisk_tmp() + "/"s ZYGISKBIN "/loader64.so";
|
||||
app_fd = app_process_64;
|
||||
} else {
|
||||
hbin = HIJACK_BIN32;
|
||||
mbin = MAGISKTMP + "/" ZYGISKBIN "/loader32.so";
|
||||
mbin = get_magisk_tmp() + "/"s ZYGISKBIN "/loader32.so";
|
||||
app_fd = app_process_32;
|
||||
}
|
||||
|
||||
@ -222,7 +220,6 @@ static void setup_files(int client, const sock_cred *cred) {
|
||||
xmount(mbin.data(), hbin, nullptr, MS_BIND, nullptr);
|
||||
|
||||
send_fd(client, app_fd);
|
||||
write_string(client, MAGISKTMP);
|
||||
}
|
||||
|
||||
static void magiskd_passthrough(int client) {
|
||||
|
@ -74,7 +74,6 @@ int app_process_main(int argc, char *argv[]) {
|
||||
if (app_proc_fd < 0)
|
||||
break;
|
||||
|
||||
string tmp = read_string(socket);
|
||||
if (char *ld = getenv("LD_PRELOAD")) {
|
||||
string env = ld;
|
||||
env += ':';
|
||||
@ -83,7 +82,6 @@ int app_process_main(int argc, char *argv[]) {
|
||||
} else {
|
||||
setenv("LD_PRELOAD", HIJACK_BIN, 1);
|
||||
}
|
||||
setenv(MAGISKTMP_ENV, tmp.data(), 1);
|
||||
|
||||
close(socket);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user