mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-22 16:07:39 +00:00
Avoid hexpatch /init for 2SI when possible
Previous we hexpatch /init from /system/bin/init to /data/magiskinit to redirect the second stage init. However, some devices like sony has /init that does not directly invoke /system/bin/init, and thus the hexpatch fails. In this patch, we further make use of AOSP `SwitchRoot` to help us bind mount /data/magisk to /system/bin/init after `SwitchRoot`. Two important assumption about 2SI are i) that the second stage init is always /system/bin/init and ii) that the /sdcard (path after `SwitchRoot`) is always a symlink to `/storage/self/primary`. When these assumptions hold, during first stage init (before `SwitchRoot`) we can bind mount magiskinit to /sdcard, and create a symlink /storage/self/primary to /system/system/bin/init. By these steps, during `SwitchRoot`, AOSP init will try to mount move /sdcard to /system/sdcard. And /system/sdcard is symlink to /storage/self/primary, it will try to mount move /sdcard to /storage/self/primary. And /storage/self/primary in ramfs is now a symlink that points to /system/system/bin/init, thus AOSP will try to mount move /sdcard (which is a bind mount to magiskinit) to /system/system/bin/init. After chroot done by AOSP init, we then have a magiskinit bind mount on /system/bin/init, which is the second stage init. An edge case is that some devices (like meizu) use 2SI but does not switch root. In this case, they must already have a /sdcard in the ramfs, thus we can check if /sdcard exists and fallback to hexpatch.
This commit is contained in:
parent
953d44302c
commit
a8c2ae223a
@ -10,11 +10,37 @@ using namespace std;
|
||||
|
||||
void FirstStageInit::prepare() {
|
||||
prepare_data();
|
||||
restore_ramdisk_init();
|
||||
auto init = mmap_data("/init", true);
|
||||
// Redirect original init to magiskinit
|
||||
for (size_t off : init.patch(INIT_PATH, REDIR_PATH)) {
|
||||
LOGD("Patch @ %08zX [" INIT_PATH "] -> [" REDIR_PATH "]\n", off);
|
||||
|
||||
if (struct stat st{}; fstatat(-1, "/sdcard", &st, AT_SYMLINK_NOFOLLOW) != 0 &&
|
||||
fstatat(-1, "/first_stage_ramdisk/sdcard", &st, AT_SYMLINK_NOFOLLOW) != 0) {
|
||||
if (config->force_normal_boot) {
|
||||
xmkdirs("/first_stage_ramdisk/storage/self", 0755);
|
||||
xsymlink("/system/system/bin/init", "/first_stage_ramdisk/storage/self/primary");
|
||||
LOGD("Symlink /first_stage_ramdisk/storage/self/primary -> /system/system/bin/init\n");
|
||||
close(xopen("/first_stage_ramdisk/sdcard", O_RDONLY | O_CREAT | O_CLOEXEC, 0));
|
||||
} else {
|
||||
xmkdirs("/storage/self", 0755);
|
||||
xsymlink("/system/system/bin/init", "/storage/self/primary");
|
||||
LOGD("Symlink /storage/self/primary -> /system/system/bin/init\n");
|
||||
}
|
||||
xrename("/init", "/sdcard");
|
||||
// Try to keep magiskinit in rootfs for samsung RKP
|
||||
if (mount("/sdcard", "/sdcard", nullptr, MS_BIND, nullptr) == 0) {
|
||||
LOGD("Bind mount /sdcard -> /sdcard\n");
|
||||
} else {
|
||||
// rootfs before 3.12
|
||||
xmount("/data/magiskinit", "/sdcard", nullptr, MS_BIND, nullptr);
|
||||
LOGD("Bind mount /sdcard -> /data/magiskinit\n");
|
||||
}
|
||||
restore_ramdisk_init();
|
||||
} else {
|
||||
restore_ramdisk_init();
|
||||
// fallback to hexpatch if /sdcard exists
|
||||
auto init = mmap_data("/init", true);
|
||||
// Redirect original init to magiskinit
|
||||
for (size_t off : init.patch(INIT_PATH, REDIR_PATH)) {
|
||||
LOGD("Patch @ %08zX [" INIT_PATH "] -> [" REDIR_PATH "]\n", off);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,6 +63,7 @@ void LegacySARInit::first_stage_prep() {
|
||||
|
||||
bool SecondStageInit::prepare() {
|
||||
umount2("/init", MNT_DETACH);
|
||||
umount2(INIT_PATH, MNT_DETACH); // just in case
|
||||
unlink("/data/init");
|
||||
|
||||
// Make sure init dmesg logs won't get messed up
|
||||
|
Loading…
x
Reference in New Issue
Block a user