mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-27 12:37:39 +00:00
Fix lowmemorykiller crash hell in Pixel 3
This commit is contained in:
parent
d3947d2cfa
commit
4cdd66ceff
@ -20,7 +20,6 @@
|
|||||||
* preserved as it also provides CLI for sepolicy patching (magiskpolicy)
|
* preserved as it also provides CLI for sepolicy patching (magiskpolicy)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -50,6 +49,10 @@
|
|||||||
|
|
||||||
int (*init_applet_main[]) (int, char *[]) = { magiskpolicy_main, magiskpolicy_main, nullptr };
|
int (*init_applet_main[]) (int, char *[]) = { magiskpolicy_main, magiskpolicy_main, nullptr };
|
||||||
|
|
||||||
|
static int root = -1;
|
||||||
|
static bool mnt_system = false;
|
||||||
|
static bool mnt_vendor = false;
|
||||||
|
|
||||||
struct cmdline {
|
struct cmdline {
|
||||||
bool skip_initramfs;
|
bool skip_initramfs;
|
||||||
char slot[3];
|
char slot[3];
|
||||||
@ -110,13 +113,13 @@ static void parse_device(struct device *dev, const char *uevent) {
|
|||||||
LOGD("%s [%s] (%u, %u)\n", dev->devname, dev->partname, (unsigned) dev->major, (unsigned) dev->minor);
|
LOGD("%s [%s] (%u, %u)\n", dev->devname, dev->partname, (unsigned) dev->major, (unsigned) dev->minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_block(struct device *dev, const char *partname) {
|
static bool setup_block(struct device *dev, const char *partname) {
|
||||||
char path[128];
|
char path[128];
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
DIR *dir = opendir("/sys/dev/block");
|
DIR *dir = opendir("/sys/dev/block");
|
||||||
if (dir == nullptr)
|
if (dir == nullptr)
|
||||||
return 1;
|
return 1;
|
||||||
int found = 0;
|
bool found = false;
|
||||||
while ((entry = readdir(dir))) {
|
while ((entry = readdir(dir))) {
|
||||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||||
continue;
|
continue;
|
||||||
@ -124,29 +127,29 @@ static int setup_block(struct device *dev, const char *partname) {
|
|||||||
parse_device(dev, path);
|
parse_device(dev, path);
|
||||||
if (strcasecmp(dev->partname, partname) == 0) {
|
if (strcasecmp(dev->partname, partname) == 0) {
|
||||||
sprintf(dev->path, "/dev/block/%s", dev->devname);
|
sprintf(dev->path, "/dev/block/%s", dev->devname);
|
||||||
found = 1;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
return 1;
|
return false;
|
||||||
|
|
||||||
mkdir("/dev", 0755);
|
mkdir("/dev", 0755);
|
||||||
mkdir("/dev/block", 0755);
|
mkdir("/dev/block", 0755);
|
||||||
mknod(dev->path, S_IFBLK | 0600, makedev(dev->major, dev->minor));
|
mknod(dev->path, S_IFBLK | 0600, makedev(dev->major, dev->minor));
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_fstab_dt(const struct cmdline *cmd, const char *mnt_point, char *partname) {
|
static bool read_fstab_dt(const struct cmdline *cmd, const char *mnt_point, char *partname) {
|
||||||
char buf[128];
|
char buf[128];
|
||||||
struct stat st;
|
struct stat st;
|
||||||
sprintf(buf, "/%s", mnt_point);
|
sprintf(buf, "/%s", mnt_point);
|
||||||
lstat(buf, &st);
|
lstat(buf, &st);
|
||||||
// Don't early mount if the mount point is symlink
|
// Don't early mount if the mount point is symlink
|
||||||
if (S_ISLNK(st.st_mode))
|
if (S_ISLNK(st.st_mode))
|
||||||
return 1;
|
return false;
|
||||||
sprintf(buf, "%s/fstab/%s/dev", cmd->dt_dir, mnt_point);
|
sprintf(buf, "%s/fstab/%s/dev", cmd->dt_dir, mnt_point);
|
||||||
if (access(buf, F_OK) == 0) {
|
if (access(buf, F_OK) == 0) {
|
||||||
int fd = open(buf, O_RDONLY | O_CLOEXEC);
|
int fd = open(buf, O_RDONLY | O_CLOEXEC);
|
||||||
@ -154,12 +157,12 @@ static int read_fstab_dt(const struct cmdline *cmd, const char *mnt_point, char
|
|||||||
close(fd);
|
close(fd);
|
||||||
char *name = strrchr(buf, '/') + 1;
|
char *name = strrchr(buf, '/') + 1;
|
||||||
sprintf(partname, "%s%s", name, strend(name, cmd->slot) ? cmd->slot : "");
|
sprintf(partname, "%s%s", name, strend(name, cmd->slot) ? cmd->slot : "");
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int verify_precompiled() {
|
static bool verify_precompiled() {
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
int fd;
|
int fd;
|
||||||
@ -197,18 +200,18 @@ static int verify_precompiled() {
|
|||||||
return memcmp(sys_sha, ven_sha, sizeof(sys_sha)) == 0;
|
return memcmp(sys_sha, ven_sha, sizeof(sys_sha)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int patch_sepolicy() {
|
static bool patch_sepolicy() {
|
||||||
int init_patch = 0;
|
bool init_patch = false;
|
||||||
if (access(SPLIT_PRECOMPILE, R_OK) == 0 && verify_precompiled()) {
|
if (access(SPLIT_PRECOMPILE, R_OK) == 0 && verify_precompiled()) {
|
||||||
init_patch = 1;
|
init_patch = true;
|
||||||
load_policydb(SPLIT_PRECOMPILE);
|
load_policydb(SPLIT_PRECOMPILE);
|
||||||
} else if (access(SPLIT_PLAT_CIL, R_OK) == 0) {
|
} else if (access(SPLIT_PLAT_CIL, R_OK) == 0) {
|
||||||
init_patch = 1;
|
init_patch = true;
|
||||||
compile_split_cil();
|
compile_split_cil();
|
||||||
} else if (access("/sepolicy", R_OK) == 0) {
|
} else if (access("/sepolicy", R_OK) == 0) {
|
||||||
load_policydb("/sepolicy");
|
load_policydb("/sepolicy");
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sepol_magisk_rules();
|
sepol_magisk_rules();
|
||||||
@ -235,10 +238,10 @@ static int patch_sepolicy() {
|
|||||||
munmap(addr, size);
|
munmap(addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int unxz(int fd, const uint8_t *buf, size_t size) {
|
static bool unxz(int fd, const uint8_t *buf, size_t size) {
|
||||||
uint8_t out[8192];
|
uint8_t out[8192];
|
||||||
xz_crc32_init();
|
xz_crc32_init();
|
||||||
struct xz_dec *dec = xz_dec_init(XZ_DYNALLOC, 1 << 26);
|
struct xz_dec *dec = xz_dec_init(XZ_DYNALLOC, 1 << 26);
|
||||||
@ -254,18 +257,18 @@ static int unxz(int fd, const uint8_t *buf, size_t size) {
|
|||||||
do {
|
do {
|
||||||
ret = xz_dec_run(dec, &b);
|
ret = xz_dec_run(dec, &b);
|
||||||
if (ret != XZ_OK && ret != XZ_STREAM_END)
|
if (ret != XZ_OK && ret != XZ_STREAM_END)
|
||||||
return 1;
|
return false;
|
||||||
write(fd, out, b.out_pos);
|
write(fd, out, b.out_pos);
|
||||||
b.out_pos = 0;
|
b.out_pos = 0;
|
||||||
} while (b.in_pos != size);
|
} while (b.in_pos != size);
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dump_magisk(const char *path, mode_t mode) {
|
static int dump_magisk(const char *path, mode_t mode) {
|
||||||
int fd = creat(path, mode);
|
int fd = creat(path, mode);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return 1;
|
return 1;
|
||||||
if (unxz(fd, magisk_xz, sizeof(magisk_xz)))
|
if (!unxz(fd, magisk_xz, sizeof(magisk_xz)))
|
||||||
return 1;
|
return 1;
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
@ -275,7 +278,7 @@ static int dump_manager(const char *path, mode_t mode) {
|
|||||||
int fd = creat(path, mode);
|
int fd = creat(path, mode);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return 1;
|
return 1;
|
||||||
if (unxz(fd, manager_xz, sizeof(manager_xz)))
|
if (!unxz(fd, manager_xz, sizeof(manager_xz)))
|
||||||
return 1;
|
return 1;
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
@ -316,6 +319,19 @@ static void patch_socket_name(const char *path) {
|
|||||||
munmap(buf, size);
|
munmap(buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void exec_init(char *argv[]) {
|
||||||
|
// Clean up
|
||||||
|
close(root);
|
||||||
|
umount("/proc");
|
||||||
|
umount("/sys");
|
||||||
|
if (mnt_system)
|
||||||
|
umount("/system");
|
||||||
|
if (mnt_vendor)
|
||||||
|
umount("/vendor");
|
||||||
|
|
||||||
|
execv("/init", argv);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
umask(0);
|
umask(0);
|
||||||
|
|
||||||
@ -359,9 +375,7 @@ int main(int argc, char *argv[]) {
|
|||||||
* Initialize
|
* Initialize
|
||||||
* ***********/
|
* ***********/
|
||||||
|
|
||||||
int root = open("/", O_RDONLY | O_CLOEXEC);
|
root = open("/", O_RDONLY | O_CLOEXEC);
|
||||||
bool mnt_system = false;
|
|
||||||
bool mnt_vendor = false;
|
|
||||||
|
|
||||||
if (cmd.skip_initramfs) {
|
if (cmd.skip_initramfs) {
|
||||||
// Clear rootfs
|
// Clear rootfs
|
||||||
@ -378,7 +392,7 @@ int main(int argc, char *argv[]) {
|
|||||||
if (!cmd.skip_initramfs && access("/sbin/recovery", F_OK) == 0) {
|
if (!cmd.skip_initramfs && access("/sbin/recovery", F_OK) == 0) {
|
||||||
// Remove Magisk traces
|
// Remove Magisk traces
|
||||||
rm_rf("/.backup");
|
rm_rf("/.backup");
|
||||||
goto exec_init;
|
exec_init(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************
|
/* ************
|
||||||
@ -396,21 +410,21 @@ int main(int argc, char *argv[]) {
|
|||||||
int system_root = open("/system_root", O_RDONLY | O_CLOEXEC);
|
int system_root = open("/system_root", O_RDONLY | O_CLOEXEC);
|
||||||
|
|
||||||
// Clone rootfs except /system
|
// Clone rootfs except /system
|
||||||
const char *excl[] = { "overlay", ".backup", "proc", "sys", "init.bak", nullptr };
|
const char *excl[] = { "system", nullptr };
|
||||||
excl_list = excl;
|
excl_list = excl;
|
||||||
clone_dir(system_root, root);
|
clone_dir(system_root, root);
|
||||||
excl_list = nullptr;
|
|
||||||
close(system_root);
|
close(system_root);
|
||||||
|
excl_list = nullptr;
|
||||||
|
|
||||||
xmkdir("/system", 0755);
|
xmkdir("/system", 0755);
|
||||||
xmount("/system_root/system", "/system", nullptr, MS_BIND, nullptr);
|
xmount("/system_root/system", "/system", nullptr, MS_BIND, nullptr);
|
||||||
} else if (read_fstab_dt(&cmd, "system", partname) == 0) {
|
} else if (read_fstab_dt(&cmd, "system", partname)) {
|
||||||
setup_block(&dev, partname);
|
setup_block(&dev, partname);
|
||||||
xmount(dev.path, "/system", "ext4", MS_RDONLY, nullptr);
|
xmount(dev.path, "/system", "ext4", MS_RDONLY, nullptr);
|
||||||
mnt_system = true;
|
mnt_system = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_fstab_dt(&cmd, "vendor", partname) == 0) {
|
if (read_fstab_dt(&cmd, "vendor", partname)) {
|
||||||
setup_block(&dev, partname);
|
setup_block(&dev, partname);
|
||||||
xmount(dev.path, "/vendor", "ext4", MS_RDONLY, nullptr);
|
xmount(dev.path, "/vendor", "ext4", MS_RDONLY, nullptr);
|
||||||
mnt_vendor = true;
|
mnt_vendor = true;
|
||||||
@ -420,13 +434,8 @@ int main(int argc, char *argv[]) {
|
|||||||
* Ramdisk Patches
|
* Ramdisk Patches
|
||||||
* ****************/
|
* ****************/
|
||||||
|
|
||||||
int fd;
|
|
||||||
bool injected;
|
|
||||||
FILE *fp;
|
|
||||||
char tok[4096];
|
|
||||||
|
|
||||||
// Handle ramdisk overlays
|
// Handle ramdisk overlays
|
||||||
fd = open("/overlay", O_RDONLY | O_CLOEXEC);
|
int fd = open("/overlay", O_RDONLY | O_CLOEXEC);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
mv_dir(fd, root);
|
mv_dir(fd, root);
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -434,23 +443,23 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Patch init.rc to load magisk scripts
|
// Patch init.rc to load magisk scripts
|
||||||
|
bool injected = false;
|
||||||
injected = false;
|
char line[4096];
|
||||||
fp = xfopen("/init.rc", "r");
|
FILE *fp = xfopen("/init.rc", "r");
|
||||||
fd = creat("/init.rc.new", 0750);
|
fd = creat("/init.rc.new", 0750);
|
||||||
while(fgets(tok, sizeof(tok), fp)) {
|
while(fgets(line, sizeof(line), fp)) {
|
||||||
if (!injected && strncmp(tok, "import", 6) == 0) {
|
if (!injected && strncmp(line, "import", 6) == 0) {
|
||||||
if (strstr(tok, "init.magisk.rc")) {
|
if (strstr(line, "init.magisk.rc")) {
|
||||||
injected = true;
|
injected = true;
|
||||||
} else {
|
} else {
|
||||||
xwrite(fd, "import /init.magisk.rc\n", 23);
|
xwrite(fd, "import /init.magisk.rc\n", 23);
|
||||||
injected = true;
|
injected = true;
|
||||||
}
|
}
|
||||||
} else if (strstr(tok, "selinux.reload_policy")) {
|
} else if (strstr(line, "selinux.reload_policy")) {
|
||||||
// Do not allow sepolicy patch
|
// Do not allow sepolicy patch
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
xwrite(fd, tok, strlen(tok));
|
xwrite(fd, line, strlen(line));
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -465,15 +474,5 @@ int main(int argc, char *argv[]) {
|
|||||||
patch_socket_name("/sbin/magisk");
|
patch_socket_name("/sbin/magisk");
|
||||||
rename("/init.bak", "/sbin/magiskinit");
|
rename("/init.bak", "/sbin/magiskinit");
|
||||||
|
|
||||||
exec_init:
|
exec_init(argv);
|
||||||
// Clean up
|
|
||||||
close(root);
|
|
||||||
umount("/proc");
|
|
||||||
umount("/sys");
|
|
||||||
if (mnt_system)
|
|
||||||
umount("/system");
|
|
||||||
if (mnt_vendor)
|
|
||||||
umount("/vendor");
|
|
||||||
|
|
||||||
execv("/init", argv);
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user