mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-18 05:58:30 +00:00
Eliminate unnecessarily copy on magiskinit
This patch reuses the abused /data tmpfs for magisktmp
This commit is contained in:
parent
0d38c94c9c
commit
4ed34cd648
@ -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
|
||||||
|
@ -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("/");
|
||||||
}
|
}
|
||||||
|
@ -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[]) {
|
||||||
|
@ -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);
|
||||||
{
|
// Redirect original init to magiskinit
|
||||||
auto init = mmap_data("/init", true);
|
init.patch({ make_pair(INIT_PATH, REDIR_PATH) });
|
||||||
// Redirect original init to magiskinit
|
|
||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user