Remove usage of MAGISKTMP

This commit is contained in:
topjohnwu 2023-11-02 15:50:36 -07:00
parent 3ba00858e6
commit 16ae4aedf1
12 changed files with 72 additions and 72 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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";

View File

@ -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"

View File

@ -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) {

View File

@ -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);