Commit e0a28158 authored by topjohnwu's avatar topjohnwu

Preparation for dynamic tmpfs path

parent d739dcac
...@@ -61,6 +61,7 @@ LOCAL_SRC_FILES := \ ...@@ -61,6 +61,7 @@ LOCAL_SRC_FILES := \
init/rootdir.cpp \ init/rootdir.cpp \
init/getinfo.cpp \ init/getinfo.cpp \
init/twostage.cpp \ init/twostage.cpp \
core/socket.cpp \
magiskpolicy/api.cpp \ magiskpolicy/api.cpp \
magiskpolicy/magiskpolicy.cpp \ magiskpolicy/magiskpolicy.cpp \
magiskpolicy/rules.cpp \ magiskpolicy/rules.cpp \
......
This diff is collapsed.
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.h>
#include <signal.h> #include <signal.h>
#include <libgen.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/mount.h> #include <sys/mount.h>
...@@ -16,8 +17,11 @@ ...@@ -16,8 +17,11 @@
#include <resetprop.hpp> #include <resetprop.hpp>
#include <flags.h> #include <flags.h>
using namespace std;
int SDK_INT = -1; int SDK_INT = -1;
bool RECOVERY_MODE = false; bool RECOVERY_MODE = false;
string MAGISKTMP;
static struct stat self_st; static struct stat self_st;
static void verify_client(int client, pid_t pid) { static void verify_client(int client, pid_t pid) {
...@@ -91,6 +95,10 @@ static void *request_handler(void *args) { ...@@ -91,6 +95,10 @@ static void *request_handler(void *args) {
} }
close(client); close(client);
break; break;
case GET_PATH:
write_string(client, MAGISKTMP.data());
close(client);
break;
default: default:
close(client); close(client);
break; break;
...@@ -114,11 +122,19 @@ static void main_daemon() { ...@@ -114,11 +122,19 @@ static void main_daemon() {
setsid(); setsid();
setcon("u:r:" SEPOL_PROC_DOMAIN ":s0"); setcon("u:r:" SEPOL_PROC_DOMAIN ":s0");
// Get self stat
char path[4096];
xreadlink("/proc/self/exe", path, sizeof(path));
MAGISKTMP = dirname(path);
xstat("/proc/self/exe", &self_st);
restore_rootcon(); restore_rootcon();
// Unmount pre-init patches // Unmount pre-init patches
if (access(ROOTMNT, F_OK) == 0) { auto mount_list = MAGISKTMP + "/" ROOTMNT;
file_readline(true, ROOTMNT, [](auto line) -> bool { if (access(mount_list.data(), F_OK) == 0) {
file_readline(true, mount_list.data(), [](string_view line) -> bool {
umount2(line.data(), MNT_DETACH); umount2(line.data(), MNT_DETACH);
return true; return true;
}); });
...@@ -126,9 +142,6 @@ static void main_daemon() { ...@@ -126,9 +142,6 @@ static void main_daemon() {
LOGI(NAME_WITH_VER(Magisk) " daemon started\n"); LOGI(NAME_WITH_VER(Magisk) " daemon started\n");
// Get server stat
stat("/proc/self/exe", &self_st);
// Get API level // Get API level
parse_prop_file("/system/build.prop", [](auto key, auto val) -> bool { parse_prop_file("/system/build.prop", [](auto key, auto val) -> bool {
if (key == "ro.build.version.sdk") { if (key == "ro.build.version.sdk") {
...@@ -148,7 +161,8 @@ static void main_daemon() { ...@@ -148,7 +161,8 @@ static void main_daemon() {
} }
// Load config status // Load config status
parse_prop_file(MAGISKTMP "/config", [](auto key, auto val) -> bool { auto config = MAGISKTMP + "/" INTLROOT "/config";
parse_prop_file(config.data(), [](auto key, auto val) -> bool {
if (key == "RECOVERYMODE" && val == "true") if (key == "RECOVERYMODE" && val == "true")
RECOVERY_MODE = true; RECOVERY_MODE = true;
return true; return true;
......
...@@ -37,7 +37,7 @@ Advanced Options (Internal APIs): ...@@ -37,7 +37,7 @@ Advanced Options (Internal APIs):
--clone-attr SRC DEST clone permission, owner, and selinux context --clone-attr SRC DEST clone permission, owner, and selinux context
--clone SRC DEST clone SRC to DEST --clone SRC DEST clone SRC to DEST
--sqlite SQL exec SQL commands to Magisk database --sqlite SQL exec SQL commands to Magisk database
--path print internal tmpfs mount path --path print Magisk tmpfs mount path
Available applets: Available applets:
)EOF"); )EOF");
...@@ -116,8 +116,10 @@ int magisk_main(int argc, char *argv[]) { ...@@ -116,8 +116,10 @@ int magisk_main(int argc, char *argv[]) {
write_int(fd, REMOVE_MODULES); write_int(fd, REMOVE_MODULES);
return read_int(fd); return read_int(fd);
} else if (argv[1] == "--path"sv) { } else if (argv[1] == "--path"sv) {
// TODO: hardcode /sbin for now, actual logic will be used for Android 11 int fd = connect_daemon();
printf("/sbin\n"); write_int(fd, GET_PATH);
char *path = read_string(fd);
printf("%s\n", path);
return 0; return 0;
} }
#if 0 #if 0
......
...@@ -81,20 +81,17 @@ void restorecon() { ...@@ -81,20 +81,17 @@ void restorecon() {
} }
void restore_rootcon() { void restore_rootcon() {
setfilecon("/sbin", ROOT_CON); setfilecon(MAGISKTMP.data(), ROOT_CON);
setfilecon(MAGISKTMP, ROOT_CON);
setfilecon(MIRRDIR, ROOT_CON);
setfilecon(BLOCKDIR, ROOT_CON);
auto dir = xopen_dir("/sbin"); auto dir = xopen_dir(MAGISKTMP.data());
int dfd = dirfd(dir.get()); int dfd = dirfd(dir.get());
for (dirent *entry; (entry = xreaddir(dir.get()));) { for (dirent *entry; (entry = xreaddir(dir.get()));) {
if (entry->d_name == "."sv || entry->d_name == ".."sv) if (entry->d_name == "."sv || entry->d_name == ".."sv)
continue; continue;
if (entry->d_name == "magisk"sv || entry->d_name == "magiskinit"sv)
setfilecon_at(dfd, entry->d_name, MAGISK_CON);
else
setfilecon_at(dfd, entry->d_name, ROOT_CON); setfilecon_at(dfd, entry->d_name, ROOT_CON);
} }
setfilecon("/sbin/magisk", MAGISK_CON);
setfilecon("/sbin/magiskinit", MAGISK_CON);
} }
/* socket.c - All socket related operations
*/
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h> #include <fcntl.h>
#include <endian.h> #include <endian.h>
#include <daemon.hpp> #include <socket.hpp>
#include <utils.hpp> #include <utils.hpp>
#include <logging.hpp> #include <logging.hpp>
......
#pragma once #pragma once
#include <pthread.h> #include <pthread.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <socket.hpp>
// Commands require connecting to daemon // Commands require connecting to daemon
enum { enum {
DO_NOTHING = 0, DO_NOTHING = 0,
...@@ -18,6 +18,7 @@ enum { ...@@ -18,6 +18,7 @@ enum {
MAGISKHIDE, MAGISKHIDE,
SQLITE_CMD, SQLITE_CMD,
REMOVE_MODULES, REMOVE_MODULES,
GET_PATH,
}; };
// Return codes for daemon // Return codes for daemon
...@@ -32,25 +33,6 @@ enum { ...@@ -32,25 +33,6 @@ enum {
int connect_daemon(bool create = false); int connect_daemon(bool create = false);
// socket.cpp
socklen_t setup_sockaddr(struct sockaddr_un *sun, const char *name);
int create_rand_socket(struct sockaddr_un *sun);
int socket_accept(int sockfd, int timeout);
void get_client_cred(int fd, struct ucred *cred);
int recv_fd(int sockfd);
void send_fd(int sockfd, int fd);
int read_int(int fd);
int read_int_be(int fd);
void write_int(int fd, int val);
void write_int_be(int fd, int val);
char *read_string(int fd);
char *read_string_be(int fd);
void write_string(int fd, const char *val);
void write_string_be(int fd, const char *val);
void write_key_value(int fd, const char *key, const char *val);
void write_key_token(int fd, const char *key, int tok);
/*************** /***************
* Boot Stages * * Boot Stages *
***************/ ***************/
......
#pragma once #pragma once
#include <logging.hpp> #include <logging.hpp>
#include <string>
#define MAIN_SOCKET "d30138f2310a9fb9c54a3e0c21f58591" #define MAIN_SOCKET "d30138f2310a9fb9c54a3e0c21f58591"
#define JAVA_PACKAGE_NAME "com.topjohnwu.magisk" #define JAVA_PACKAGE_NAME "com.topjohnwu.magisk"
#define LOGFILE "/cache/magisk.log" #define LOGFILE "/cache/magisk.log"
#define UNBLOCKFILE "/dev/.magisk_unblock" #define UNBLOCKFILE "/dev/.magisk_unblock"
#define DISABLEFILE "/cache/.disable_magisk" #define DISABLEFILE "/cache/.disable_magisk"
#define MAGISKTMP "/sbin/.magisk"
#define MIRRDIR MAGISKTMP "/mirror"
#define BLOCKDIR MAGISKTMP "/block"
#define BBPATH MAGISKTMP "/busybox"
#define MODULEMNT MAGISKTMP "/modules"
#define ROOTOVL MAGISKTMP "/rootdir"
#define ROOTMNT ROOTOVL "/.mount_list"
#define SECURE_DIR "/data/adb" #define SECURE_DIR "/data/adb"
#define MODULEROOT SECURE_DIR "/modules" #define MODULEROOT SECURE_DIR "/modules"
#define MODULEUPGRADE SECURE_DIR "/modules_update" #define MODULEUPGRADE SECURE_DIR "/modules_update"
...@@ -21,6 +15,16 @@ ...@@ -21,6 +15,16 @@
#define MAGISKDB SECURE_DIR "/magisk.db" #define MAGISKDB SECURE_DIR "/magisk.db"
#define MANAGERAPK DATABIN "/magisk.apk" #define MANAGERAPK DATABIN "/magisk.apk"
// tmpfs paths
extern std::string MAGISKTMP;
#define INTLROOT ".magisk"
#define MIRRDIR INTLROOT "/mirror"
#define BLOCKDIR INTLROOT "/block"
#define MODULEMNT INTLROOT "/modules"
#define BBPATH INTLROOT "/busybox"
#define ROOTOVL INTLROOT "/rootdir"
#define ROOTMNT ROOTOVL "/.mount_list"
constexpr const char *applet_names[] = { "su", "resetprop", "magiskhide", nullptr }; constexpr const char *applet_names[] = { "su", "resetprop", "magiskhide", nullptr };
// Multi-call entrypoints // Multi-call entrypoints
......
#pragma once
#include <sys/un.h>
#include <sys/socket.h>
socklen_t setup_sockaddr(struct sockaddr_un *sun, const char *name);
int create_rand_socket(struct sockaddr_un *sun);
int socket_accept(int sockfd, int timeout);
void get_client_cred(int fd, struct ucred *cred);
int recv_fd(int sockfd);
void send_fd(int sockfd, int fd);
int read_int(int fd);
int read_int_be(int fd);
void write_int(int fd, int val);
void write_int_be(int fd, int val);
char *read_string(int fd);
char *read_string_be(int fd);
void write_string(int fd, const char *val);
void write_string_be(int fd, const char *val);
void write_key_value(int fd, const char *key, const char *val);
void write_key_token(int fd, const char *key, int tok);
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <vector> #include <vector>
#include <magisk.hpp> #include <logging.hpp>
struct cmdline { struct cmdline {
bool skip_initramfs; bool skip_initramfs;
...@@ -57,26 +57,25 @@ public: ...@@ -57,26 +57,25 @@ public:
class MagiskInit : public BaseInit { class MagiskInit : public BaseInit {
protected: protected:
raw_data self; raw_data self;
const char *persist_dir; std::string persist_dir;
virtual void early_mount() = 0; virtual void early_mount() = 0;
bool patch_sepolicy(const char *file = "/sepolicy"); bool patch_sepolicy(const char *file = "/sepolicy");
public: public:
MagiskInit(char *argv[], cmdline *cmd) : BaseInit(argv, cmd) {}; MagiskInit(char *argv[], cmdline *cmd) : BaseInit(argv, cmd) {}
}; };
class SARBase : public MagiskInit { class SARBase : public MagiskInit {
protected: protected:
raw_data config; raw_data config;
std::vector<raw_file> overlays; std::vector<raw_file> overlays;
std::string tmp_dir;
void backup_files(); void backup_files();
void patch_rootdir(); void patch_rootdir();
void mount_system_root(); void mount_system_root();
public: public:
SARBase(char *argv[], cmdline *cmd) : MagiskInit(argv, cmd) { SARBase(char *argv[], cmdline *cmd) : MagiskInit(argv, cmd) {}
persist_dir = MIRRDIR "/persist/magisk";
}
void start() override { void start() override {
early_mount(); early_mount();
patch_rootdir(); patch_rootdir();
...@@ -92,7 +91,9 @@ class ForcedFirstStageInit : public BaseInit { ...@@ -92,7 +91,9 @@ class ForcedFirstStageInit : public BaseInit {
private: private:
void prepare(); void prepare();
public: public:
ForcedFirstStageInit(char *argv[], cmdline *cmd) : BaseInit(argv, cmd) {}; ForcedFirstStageInit(char *argv[], cmdline *cmd) : BaseInit(argv, cmd) {
LOGD("%s\n", __FUNCTION__);
};
void start() override { void start() override {
prepare(); prepare();
exec_init("/system/bin/init"); exec_init("/system/bin/init");
...@@ -103,7 +104,9 @@ class FirstStageInit : public BaseInit { ...@@ -103,7 +104,9 @@ class FirstStageInit : public BaseInit {
private: private:
void prepare(); void prepare();
public: public:
FirstStageInit(char *argv[], cmdline *cmd) : BaseInit(argv, cmd) {}; FirstStageInit(char *argv[], cmdline *cmd) : BaseInit(argv, cmd) {
LOGD("%s\n", __FUNCTION__);
};
void start() override { void start() override {
prepare(); prepare();
exec_init(); exec_init();
...@@ -116,7 +119,9 @@ private: ...@@ -116,7 +119,9 @@ private:
protected: protected:
void early_mount() override; void early_mount() override;
public: public:
SARFirstStageInit(char *argv[], cmdline *cmd) : SARBase(argv, cmd) {}; SARFirstStageInit(char *argv[], cmdline *cmd) : SARBase(argv, cmd) {
LOGD("%s\n", __FUNCTION__);
};
void start() override { void start() override {
early_mount(); early_mount();
traced_exec_init(); traced_exec_init();
...@@ -128,7 +133,9 @@ protected: ...@@ -128,7 +133,9 @@ protected:
void early_mount() override; void early_mount() override;
void cleanup() override { /* Do not do any cleanup */ } void cleanup() override { /* Do not do any cleanup */ }
public: public:
SecondStageInit(char *argv[]) : SARBase(argv, nullptr) {}; SecondStageInit(char *argv[]) : SARBase(argv, nullptr) {
LOGD("%s\n", __FUNCTION__);
};
}; };
/* *********** /* ***********
...@@ -139,7 +146,9 @@ class SARInit : public SARBase { ...@@ -139,7 +146,9 @@ class SARInit : public SARBase {
protected: protected:
void early_mount() override; void early_mount() override;
public: public:
SARInit(char *argv[], cmdline *cmd) : SARBase(argv, cmd) {}; SARInit(char *argv[], cmdline *cmd) : SARBase(argv, cmd) {
LOGD("%s\n", __FUNCTION__);
};
}; };
/* ********** /* **********
...@@ -148,13 +157,12 @@ public: ...@@ -148,13 +157,12 @@ public:
class RootFSInit : public MagiskInit { class RootFSInit : public MagiskInit {
private: private:
int root = -1;
void setup_rootfs(); void setup_rootfs();
protected: protected:
void early_mount() override; void early_mount() override;
public: public:
RootFSInit(char *argv[], cmdline *cmd) : MagiskInit(argv, cmd) { RootFSInit(char *argv[], cmdline *cmd) : MagiskInit(argv, cmd) {
persist_dir = "/dev/mnt/persist/magisk"; LOGD("%s\n", __FUNCTION__);
} }
void start() override { void start() override {
...@@ -164,9 +172,10 @@ public: ...@@ -164,9 +172,10 @@ public:
} }
}; };
#define INIT_SOCKET "MAGISKINIT"
void load_kernel_info(cmdline *cmd); void load_kernel_info(cmdline *cmd);
int dump_magisk(const char *path, mode_t mode); int dump_magisk(const char *path, mode_t mode);
int magisk_proxy_main(int argc, char *argv[]); int magisk_proxy_main(int argc, char *argv[]);
void setup_klog(); void setup_klog();
void mount_sbin(); void setup_tmp(const char *path, const raw_data &self, const raw_data &config);
socklen_t setup_sockaddr(struct sockaddr_un *sun);
...@@ -175,7 +175,6 @@ void RootFSInit::early_mount() { ...@@ -175,7 +175,6 @@ void RootFSInit::early_mount() {
full_read("/init", self.buf, self.sz); full_read("/init", self.buf, self.sz);
LOGD("Reverting /init\n"); LOGD("Reverting /init\n");
root = xopen("/", O_RDONLY | O_CLOEXEC);
rename("/.backup/init", "/init"); rename("/.backup/init", "/init");
mount_root(system); mount_root(system);
...@@ -186,7 +185,7 @@ void RootFSInit::early_mount() { ...@@ -186,7 +185,7 @@ void RootFSInit::early_mount() {
xmkdir("/dev/mnt", 0755); xmkdir("/dev/mnt", 0755);
mount_persist("/dev/block", "/dev/mnt"); mount_persist("/dev/block", "/dev/mnt");
mount_list.emplace_back("/dev/mnt/persist"); mount_list.emplace_back("/dev/mnt/persist");
mount_list.emplace_back("/dev/mnt/cache"); persist_dir = "/dev/mnt/persist/magisk";
} }
void SARBase::backup_files() { void SARBase::backup_files() {
...@@ -261,13 +260,45 @@ void BaseInit::cleanup() { ...@@ -261,13 +260,45 @@ void BaseInit::cleanup() {
mount_list.shrink_to_fit(); mount_list.shrink_to_fit();
} }
void mount_sbin() { static void patch_socket_name(const char *path) {
LOGD("Mount /sbin tmpfs overlay\n"); char *buf;
xmount("tmpfs", "/sbin", "tmpfs", 0, "mode=755"); size_t size;
mmap_rw(path, buf, size);
for (int i = 0; i < size; ++i) {
if (memcmp(buf + i, MAIN_SOCKET, sizeof(MAIN_SOCKET)) == 0) {
gen_rand_str(buf + i, 16);
i += sizeof(MAIN_SOCKET);
}
}
munmap(buf, size);
}
void setup_tmp(const char *path, const raw_data &self, const raw_data &config) {
LOGD("Setup Magisk tmp at %s\n", path);
xmount("tmpfs", path, "tmpfs", 0, "mode=755");
chdir(path);
xmkdir(MAGISKTMP, 0755); xmkdir(INTLROOT, 0755);
xmkdir(MIRRDIR, 0); xmkdir(MIRRDIR, 0);
xmkdir(BLOCKDIR, 0); xmkdir(BLOCKDIR, 0);
mount_persist(BLOCKDIR, MIRRDIR); mount_persist(BLOCKDIR, MIRRDIR);
int fd = xopen(INTLROOT "/config", O_WRONLY | O_CREAT, 0);
xwrite(fd, config.buf, config.sz);
close(fd);
fd = xopen("magiskinit", O_WRONLY | O_CREAT, 0755);
xwrite(fd, self.buf, self.sz);
close(fd);
dump_magisk("magisk", 0755);
patch_socket_name("magisk");
// Create applet symlinks
for (int i = 0; applet_names[i]; ++i)
xsymlink("./magisk", applet_names[i]);
xsymlink("./magiskinit", "magiskpolicy");
xsymlink("./magiskinit", "supolicy");
chdir("/");
} }
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <magisk.hpp> #include <magisk.hpp>
#include <magiskpolicy.hpp> #include <magiskpolicy.hpp>
#include <utils.hpp> #include <utils.hpp>
#include <socket.hpp>
#include "init.hpp" #include "init.hpp"
#include "magiskrc.inc" #include "magiskrc.inc"
...@@ -18,19 +19,6 @@ ...@@ -18,19 +19,6 @@
using namespace std; using namespace std;
static void patch_socket_name(const char *path) {
char *buf;
size_t size;
mmap_rw(path, buf, size);
for (int i = 0; i < size; ++i) {
if (memcmp(buf + i, MAIN_SOCKET, sizeof(MAIN_SOCKET)) == 0) {
gen_rand_str(buf + i, 16);
i += sizeof(MAIN_SOCKET);
}
}
munmap(buf, size);
}
static vector<raw_data> rc_list; static vector<raw_data> rc_list;
static void patch_init_rc(FILE *rc) { static void patch_init_rc(FILE *rc) {
...@@ -153,15 +141,14 @@ bool MagiskInit::patch_sepolicy(const char *file) { ...@@ -153,15 +141,14 @@ bool MagiskInit::patch_sepolicy(const char *file) {
sepol_allow(SEPOL_PROC_DOMAIN, ALL, ALL, ALL); sepol_allow(SEPOL_PROC_DOMAIN, ALL, ALL, ALL);
// Custom rules // Custom rules
if (auto dir = xopen_dir(persist_dir); dir) { if (auto dir = xopen_dir(persist_dir.data()); dir) {
char path[4096];
for (dirent *entry; (entry = xreaddir(dir.get()));) { for (dirent *entry; (entry = xreaddir(dir.get()));) {
if (entry->d_name == "."sv || entry->d_name == ".."sv) if (entry->d_name == "."sv || entry->d_name == ".."sv)
continue; continue;
snprintf(path, sizeof(path), "%s/%s/sepolicy.rule", persist_dir, entry->d_name); auto rule = persist_dir + "/" + entry->d_name + "/sepolicy.rule";
if (access(path, R_OK) == 0) { if (access(rule.data(), R_OK) == 0) {
LOGD("Loading custom sepolicy patch: %s\n", path); LOGD("Loading custom sepolicy patch: %s\n", rule.data());
load_rule_file(path); load_rule_file(rule.data());
} }
} }
} }
...@@ -178,30 +165,6 @@ bool MagiskInit::patch_sepolicy(const char *file) { ...@@ -178,30 +165,6 @@ bool MagiskInit::patch_sepolicy(const char *file) {
return patch_init; return patch_init;
} }
static void sbin_overlay(const raw_data &self, const raw_data &config) {
mount_sbin();
// Dump binaries
xmkdir(MAGISKTMP, 0755);
int fd = xopen(MAGISKTMP "/config", O_WRONLY | O_CREAT, 0000);
xwrite(fd, config.buf, config.sz);
close(fd);
fd = xopen("/sbin/magiskinit", O_WRONLY | O_CREAT, 0755);
xwrite(fd, self.buf, self.sz);
close(fd);
dump_magisk("/sbin/magisk", 0755);
patch_socket_name("/sbin/magisk");
// Create applet symlinks
char path[64];
for (int i = 0; applet_names[i]; ++i) {
sprintf(path, "/sbin/%s", applet_names[i]);
xsymlink("./magisk", path);
}
xsymlink("./magiskinit", "/sbin/magiskpolicy");
xsymlink("./magiskinit", "/sbin/supolicy");
}
static void recreate_sbin(const char *mirror, bool use_bind_mount) { static void recreate_sbin(const char *mirror, bool use_bind_mount) {
auto dp = xopen_dir(mirror); auto dp = xopen_dir(mirror);
int src = dirfd(dp.get()); int src = dirfd(dp.get());
...@@ -233,12 +196,6 @@ static void recreate_sbin(const char *mirror, bool use_bind_mount) { ...@@ -233,12 +196,6 @@ static void recreate_sbin(const char *mirror, bool use_bind_mount) {
} }
} }
#define ROOTMIR MIRRDIR "/system_root"
#define ROOTBLK BLOCKDIR "/system_root"
#define MONOPOLICY "/sepolicy"
#define PATCHPOLICY "/sbin/.se"
#define LIBSELINUX "/system/" LIBNAME "/libselinux.so"
static string magic_mount_list; static string magic_mount_list;
static void magic_mount(const string &sdir, const string &ddir = "") { static void magic_mount(const string &sdir, const string &ddir = "") {
...@@ -262,8 +219,20 @@ static void magic_mount(const string &sdir, const string &ddir = "") { ...@@ -262,8 +219,20 @@ static void magic_mount(const string &sdir, const string &ddir = "") {
} }
} }
#define ROOTMIR MIRRDIR "/system_root"
#define ROOTBLK BLOCKDIR "/system_root"
#define MONOPOLICY "/sepolicy"
#define PATCHPOLICY "/sbin/.se"
#define LIBSELINUX "/system/" LIBNAME "/libselinux.so"
void SARBase::patch_rootdir() { void SARBase::patch_rootdir() {
sbin_overlay(self, config); // TODO: dynamic paths
tmp_dir = "/sbin";
setup_tmp(tmp_dir.data(), self, config);
persist_dir = tmp_dir + "/" MIRRDIR "/persist";
chdir(tmp_dir.data());
// Mount system_root mirror // Mount system_root mirror
struct stat st; struct stat st;
...@@ -273,7 +242,8 @@ void SARBase::patch_rootdir() { ...@@ -273,7 +242,8 @@ void SARBase::patch_rootdir() {
if (xmount(ROOTBLK, ROOTMIR, "ext4", MS_RDONLY, nullptr)) if (xmount(ROOTBLK, ROOTMIR, "ext4", MS_RDONLY, nullptr))
xmount(ROOTBLK, ROOTMIR, "erofs", MS_RDONLY, nullptr); xmount(ROOTBLK, ROOTMIR, "erofs", MS_RDONLY, nullptr);
// Recreate original sbin structure // Recreate original sbin structure if necessary
if (tmp_dir == "/sbin")
recreate_sbin(ROOTMIR "/sbin", true); recreate_sbin(ROOTMIR "/sbin", true);
// Patch init // Patch init
...@@ -332,20 +302,21 @@ void SARBase::patch_rootdir() { ...@@ -332,20 +302,21 @@ void SARBase::patch_rootdir() {
patch_sepolicy(PATCHPOLICY); patch_sepolicy(PATCHPOLICY);
// Handle overlay // Handle overlay
struct sockaddr_un sun{}; struct sockaddr_un sun;
socklen_t len = setup_sockaddr(&sun); int sockfd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
int socketfd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); if (connect(sockfd, (struct sockaddr*) &sun, setup_sockaddr(&sun, INIT_SOCKET)) == 0) {
if (connect(socketfd, (struct sockaddr*) &sun, len) == 0) {
LOGD("ACK init tracer to write backup files\n"); LOGD("ACK init tracer to write backup files\n");
// Let tracer know where tmp_dir is
write_string(sockfd, tmp_dir.data());
// Wait for tracer to finish copying files
int ack; int ack;
// Wait for init tracer finish copying files read(sockfd, &ack, sizeof(ack));
read(socketfd, &ack, sizeof(ack));
} else { } else {
LOGD("Restore backup files locally\n"); LOGD("Restore backup files locally\n");
restore_folder(ROOTOVL, overlays); restore_folder(ROOTOVL, overlays);
overlays.clear(); overlays.clear();
} }
close(socketfd); close(sockfd);
if (access(ROOTOVL "/sbin", F_OK) == 0) { if (access(ROOTOVL "/sbin", F_OK) == 0) {
file_attr a; file_attr a;
getattr("/sbin", &a); getattr("/sbin", &a);
...@@ -362,9 +333,11 @@ void SARBase::patch_rootdir() { ...@@ -362,9 +333,11 @@ void SARBase::patch_rootdir() {
// Mount rootdir // Mount rootdir
magic_mount(ROOTOVL); magic_mount(ROOTOVL);
dest = xopen(ROOTMNT, O_WRONLY | O_CREAT | O_CLOEXEC); dest = xopen(ROOTMNT, O_WRONLY | O_CREAT | O_CLOEXEC, 0);
write(dest, magic_mount_list.data(), magic_mount_list.length()); write(dest, magic_mount_list.data(), magic_mount_list.length());
close(dest); close(dest);
chdir("/");
} }
int magisk_proxy_main(int argc, char *argv[]) { int magisk_proxy_main(int argc, char *argv[]) {
...@@ -381,7 +354,7 @@ int magisk_proxy_main(int argc, char *argv[]) { ...@@ -381,7 +354,7 @@ int magisk_proxy_main(int argc, char *argv[]) {
unlink("/sbin/magisk"); unlink("/sbin/magisk");
rm_rf("/.backup"); rm_rf("/.backup");
sbin_overlay(self, config); setup_tmp("/sbin", self, config);
// Create symlinks pointing back to /root // Create symlinks pointing back to /root
recreate_sbin("/root", false); recreate_sbin("/root", false);
......
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <magisk.hpp>
#include <utils.hpp> #include <utils.hpp>
#include <logging.hpp> #include <logging.hpp>
#include <socket.hpp>
#include "init.hpp" #include "init.hpp"
...@@ -103,14 +105,6 @@ static inline long xptrace(int request, pid_t pid, void *addr = nullptr, intptr_ ...@@ -103,14 +105,6 @@ static inline long xptrace(int request, pid_t pid, void *addr = nullptr, intptr_
return xptrace(request, pid, addr, reinterpret_cast<void *>(data)); return xptrace(request, pid, addr, reinterpret_cast<void *>(data));
} }
#define INIT_SOCKET "MAGISKINIT"
socklen_t setup_sockaddr(struct sockaddr_un *sun) {
sun->sun_family = AF_LOCAL;
strcpy(sun->sun_path + 1, INIT_SOCKET);
return sizeof(sa_family_t) + sizeof(INIT_SOCKET);
}
void SARFirstStageInit::traced_exec_init() { void SARFirstStageInit::traced_exec_init() {
int pid = getpid(); int pid = getpid();
...@@ -132,11 +126,6 @@ void SARFirstStageInit::traced_exec_init() { ...@@ -132,11 +126,6 @@ void SARFirstStageInit::traced_exec_init() {
// Re-exec init // Re-exec init
exec_init(); exec_init();
} else { } else {
// Close all file descriptors and stop logging
no_logging();
for (int i = 0; i < 20; ++i)
close(i);
// Attach to parent to trace exec // Attach to parent to trace exec
xptrace(PTRACE_ATTACH, pid); xptrace(PTRACE_ATTACH, pid);
waitpid(pid, nullptr, __WALL | __WNOTHREAD); waitpid(pid, nullptr, __WALL | __WNOTHREAD);
...@@ -155,18 +144,22 @@ void SARFirstStageInit::traced_exec_init() { ...@@ -155,18 +144,22 @@ void SARFirstStageInit::traced_exec_init() {
xumount2("/dev", MNT_DETACH); xumount2("/dev", MNT_DETACH);
// Establish socket for 2nd stage ack // Establish socket for 2nd stage ack
struct sockaddr_un sun{}; struct sockaddr_un sun;
int sockfd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); int sockfd = xsocket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
xbind(sockfd, (struct sockaddr*) &sun, setup_sockaddr(&sun)); xbind(sockfd, (struct sockaddr*) &sun, setup_sockaddr(&sun, INIT_SOCKET));
xlisten(sockfd, 1); xlisten(sockfd, 1);
// Resume init
xptrace(PTRACE_DETACH, pid); xptrace(PTRACE_DETACH, pid);
// Wait for second stage ack // Wait for second stage ack
int client = xaccept4(sockfd, nullptr, nullptr, SOCK_CLOEXEC); int client = xaccept4(sockfd, nullptr, nullptr, SOCK_CLOEXEC);
// Write backup files // Write backup files
int cfg = xopen(MAGISKTMP "/config", O_WRONLY | O_CREAT, 0000); char *tmp_dir = read_string(client);
chdir(tmp_dir);
free(tmp_dir);
int cfg = xopen(INTLROOT "/config", O_WRONLY | O_CREAT, 0);
xwrite(cfg, config.buf, config.sz); xwrite(cfg, config.buf, config.sz);
close(cfg); close(cfg);
restore_folder(ROOTOVL, overlays); restore_folder(ROOTOVL, overlays);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment