Eliminate unnecessarily copy on magiskinit

This patch reuses the abused /data tmpfs for magisktmp
This commit is contained in:
LoveSy 2022-12-14 21:14:12 +08:00 committed by John Wu
parent 0d38c94c9c
commit 4ed34cd648
4 changed files with 30 additions and 76 deletions

View File

@ -25,6 +25,7 @@ struct BootConfig {
#define DEFAULT_DT_DIR "/proc/device-tree/firmware/android" #define DEFAULT_DT_DIR "/proc/device-tree/firmware/android"
#define INIT_PATH "/system/bin/init" #define INIT_PATH "/system/bin/init"
#define REDIR_PATH "/data/magiskinit"
extern std::vector<std::string> mount_list; extern std::vector<std::string> mount_list;
@ -48,6 +49,7 @@ protected:
char **argv = nullptr; char **argv = nullptr;
[[noreturn]] void exec_init(); [[noreturn]] void exec_init();
void prepare_data();
public: public:
BaseInit(char *argv[], BootConfig *config = nullptr) : config(config), argv(argv) {} BaseInit(char *argv[], BootConfig *config = nullptr) : config(config), argv(argv) {}
virtual ~BaseInit() = default; virtual ~BaseInit() = default;
@ -58,8 +60,6 @@ class MagiskInit : public BaseInit {
private: private:
void mount_rules_dir(); void mount_rules_dir();
protected: protected:
mmap_data self;
mmap_data magisk_cfg;
std::string custom_rules_dir; std::string custom_rules_dir;
#if ENABLE_AVD_HACK #if ENABLE_AVD_HACK
@ -72,16 +72,12 @@ protected:
bool hijack_sepolicy(); bool hijack_sepolicy();
void setup_tmp(const char *path); void setup_tmp(const char *path);
void patch_rw_root(); void patch_rw_root();
void patch_ro_root();
public: public:
using BaseInit::BaseInit; using BaseInit::BaseInit;
}; };
class SARBase : public MagiskInit { class SARBase : public MagiskInit {
protected:
std::vector<raw_file> overlays;
void backup_files();
void patch_ro_root();
public: public:
using MagiskInit::MagiskInit; using MagiskInit::MagiskInit;
}; };
@ -134,6 +130,7 @@ public:
LOGD("%s\n", __FUNCTION__); LOGD("%s\n", __FUNCTION__);
}; };
void start() override { void start() override {
prepare_data();
if (mount_system_root()) if (mount_system_root())
first_stage_prep(); first_stage_prep();
else else

View File

@ -214,8 +214,6 @@ success:
} }
bool LegacySARInit::mount_system_root() { bool LegacySARInit::mount_system_root() {
backup_files();
LOGD("Mounting system_root\n"); LOGD("Mounting system_root\n");
// there's no /dev in stub cpio // there's no /dev in stub cpio
@ -296,11 +294,19 @@ void BaseInit::exec_init() {
exit(1); exit(1);
} }
void BaseInit::prepare_data() {
LOGD("Setup data tmp\n");
xmkdir("/data", 0755);
xmount("tmpfs", "/data", "tmpfs", 0, "mode=755");
cp_afc("/init", "/data/magiskinit");
cp_afc("/.backup", "/data/.backup");
cp_afc("/overlay.d", "/data/overlay.d");
}
void MagiskInit::setup_tmp(const char *path) { void MagiskInit::setup_tmp(const char *path) {
LOGD("Setup Magisk tmp at %s\n", path); LOGD("Setup Magisk tmp at %s\n", path);
xmount("tmpfs", path, "tmpfs", 0, "mode=755"); chdir("/data");
chdir(path);
xmkdir(INTLROOT, 0755); xmkdir(INTLROOT, 0755);
xmkdir(MIRRDIR, 0); xmkdir(MIRRDIR, 0);
@ -308,14 +314,15 @@ void MagiskInit::setup_tmp(const char *path) {
mount_rules_dir(); mount_rules_dir();
int fd = xopen(INTLROOT "/config", O_WRONLY | O_CREAT, 0); cp_afc(".backup/.magisk", INTLROOT "/config");
xwrite(fd, magisk_cfg.buf, magisk_cfg.sz); rm_rf(".backup");
close(fd);
// Create applet symlinks // Create applet symlinks
for (int i = 0; applet_names[i]; ++i) for (int i = 0; applet_names[i]; ++i)
xsymlink("./magisk", applet_names[i]); xsymlink("./magisk", applet_names[i]);
xsymlink("./magiskpolicy", "supolicy"); xsymlink("./magiskpolicy", "supolicy");
xmount(".", path, nullptr, MS_BIND, nullptr);
chdir("/"); chdir("/");
} }

View File

@ -130,19 +130,6 @@ static void magic_mount(const string &sdir, const string &ddir = "") {
} }
} }
void SARBase::backup_files() {
if (access("/overlay.d", F_OK) == 0)
backup_folder("/overlay.d", overlays);
else if (access("/data/overlay.d", F_OK) == 0)
backup_folder("/data/overlay.d", overlays);
self = mmap_data("/proc/self/exe");
if (access("/.backup/.magisk", R_OK) == 0)
magisk_cfg = mmap_data("/.backup/.magisk");
else if (access("/data/.backup/.magisk", R_OK) == 0)
magisk_cfg = mmap_data("/data/.backup/.magisk");
}
static void patch_socket_name(const char *path) { static void patch_socket_name(const char *path) {
static char rstr[16] = { 0 }; static char rstr[16] = { 0 };
if (rstr[0] == '\0') if (rstr[0] == '\0')
@ -181,7 +168,9 @@ static void extract_files(bool sbin) {
#define ROOTMIR MIRRDIR "/system_root" #define ROOTMIR MIRRDIR "/system_root"
#define NEW_INITRC "/system/etc/init/hw/init.rc" #define NEW_INITRC "/system/etc/init/hw/init.rc"
void SARBase::patch_ro_root() { void MagiskInit::patch_ro_root() {
mount_list.emplace_back("/data");
string tmp_dir; string tmp_dir;
if (access("/sbin", F_OK) == 0) { if (access("/sbin", F_OK) == 0) {
@ -205,7 +194,7 @@ void SARBase::patch_ro_root() {
if (tmp_dir == "/sbin") if (tmp_dir == "/sbin")
recreate_sbin(ROOTMIR "/sbin", true); recreate_sbin(ROOTMIR "/sbin", true);
xmkdir(ROOTOVL, 0); xrename("overlay.d", ROOTOVL);
#if ENABLE_AVD_HACK #if ENABLE_AVD_HACK
// Handle avd hack // Handle avd hack
@ -222,9 +211,6 @@ void SARBase::patch_ro_root() {
} }
#endif #endif
// Handle overlay.d
restore_folder(ROOTOVL, overlays);
overlays.clear();
load_overlay_rc(ROOTOVL); load_overlay_rc(ROOTOVL);
if (access(ROOTOVL "/sbin", F_OK) == 0) { if (access(ROOTOVL "/sbin", F_OK) == 0) {
// Move files in overlay.d/sbin into tmp_dir // Move files in overlay.d/sbin into tmp_dir
@ -260,9 +246,7 @@ void SARBase::patch_ro_root() {
} }
void RootFSInit::prepare() { void RootFSInit::prepare() {
self = mmap_data("/init"); prepare_data();
magisk_cfg = mmap_data("/.backup/.magisk");
LOGD("Restoring /init\n"); LOGD("Restoring /init\n");
rename(backup_init(), "/init"); rename(backup_init(), "/init");
} }
@ -270,6 +254,7 @@ void RootFSInit::prepare() {
#define PRE_TMPDIR "/magisk-tmp" #define PRE_TMPDIR "/magisk-tmp"
void MagiskInit::patch_rw_root() { void MagiskInit::patch_rw_root() {
mount_list.emplace_back("/data");
// Create hardlink mirror of /sbin to /root // Create hardlink mirror of /sbin to /root
mkdir("/root", 0777); mkdir("/root", 0777);
clone_attr("/sbin", "/root"); clone_attr("/sbin", "/root");
@ -307,9 +292,7 @@ void MagiskInit::patch_rw_root() {
chdir("/"); chdir("/");
// Dump magiskinit as magisk // Dump magiskinit as magisk
int fd = xopen("/sbin/magisk", O_WRONLY | O_CREAT, 0755); cp_afc(REDIR_PATH, "/sbin/magisk");
write(fd, self.buf, self.sz);
close(fd);
} }
int magisk_proxy_main(int argc, char *argv[]) { int magisk_proxy_main(int argc, char *argv[]) {

View File

@ -8,30 +8,15 @@
using namespace std; using namespace std;
#define REDIR_PATH "/data/magiskinit"
void FirstStageInit::prepare() { void FirstStageInit::prepare() {
xmkdirs("/data", 0755); prepare_data();
xmount("tmpfs", "/data", "tmpfs", 0, "mode=755");
cp_afc("/init" /* magiskinit */, REDIR_PATH);
restore_ramdisk_init(); restore_ramdisk_init();
{
auto init = mmap_data("/init", true); auto init = mmap_data("/init", true);
// Redirect original init to magiskinit // Redirect original init to magiskinit
init.patch({ make_pair(INIT_PATH, REDIR_PATH) }); init.patch({ make_pair(INIT_PATH, REDIR_PATH) });
}
// Copy files to tmpfs
cp_afc(".backup", "/data/.backup");
cp_afc("overlay.d", "/data/overlay.d");
} }
void LegacySARInit::first_stage_prep() { void LegacySARInit::first_stage_prep() {
xmkdir("/data", 0755);
xmount("tmpfs", "/data", "tmpfs", 0, "mode=755");
// Patch init binary // Patch init binary
int src = xopen("/init", O_RDONLY); int src = xopen("/init", O_RDONLY);
int dest = xopen("/data/init", O_CREAT | O_WRONLY, 0); int dest = xopen("/data/init", O_CREAT | O_WRONLY, 0);
@ -43,29 +28,11 @@ void LegacySARInit::first_stage_prep() {
close(dest); close(dest);
} }
xmount("/data/init", "/init", nullptr, MS_BIND, nullptr); xmount("/data/init", "/init", nullptr, MS_BIND, nullptr);
// Replace redirect init with magiskinit
dest = xopen(REDIR_PATH, O_CREAT | O_WRONLY, 0);
write(dest, self.buf, self.sz);
fclone_attr(src, dest);
close(src);
close(dest);
// Copy files to tmpfs
xmkdir("/data/.backup", 0);
xmkdir("/data/overlay.d", 0);
restore_folder("/data/overlay.d", overlays);
int cfg = xopen("/data/.backup/.magisk", O_WRONLY | O_CREAT, 0);
xwrite(cfg, magisk_cfg.buf, magisk_cfg.sz);
close(cfg);
} }
bool SecondStageInit::prepare() { bool SecondStageInit::prepare() {
backup_files();
umount2("/init", MNT_DETACH); umount2("/init", MNT_DETACH);
umount2("/proc/self/exe", MNT_DETACH); umount2("/proc/self/exe", MNT_DETACH);
umount2("/data", MNT_DETACH);
// Make sure init dmesg logs won't get messed up // Make sure init dmesg logs won't get messed up
argv[0] = (char *) INIT_PATH; argv[0] = (char *) INIT_PATH;