mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-17 13:18:30 +00:00
Patch sepolicy at boot time
This commit is contained in:
parent
9a0b26e0b0
commit
a1a2c52409
@ -46,7 +46,6 @@ LOCAL_SRC_FILES := \
|
||||
magiskpolicy/magiskpolicy.c \
|
||||
magiskpolicy/rules.c \
|
||||
magiskpolicy/sepolicy.c \
|
||||
magiskpolicy/secilc.c \
|
||||
magiskpolicy/api.c \
|
||||
resetprop/resetprop.cpp \
|
||||
resetprop/system_properties.cpp \
|
||||
@ -93,11 +92,15 @@ include $(BUILD_EXECUTABLE)
|
||||
ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := magiskinit
|
||||
LOCAL_C_INCLUDES := jni/include
|
||||
LOCAL_STATIC_LIBRARIES := libsepol
|
||||
LOCAL_C_INCLUDES := jni/include $(LIBSEPOL)
|
||||
LOCAL_SRC_FILES := \
|
||||
magiskinit.c \
|
||||
magiskboot/boot_utils.c \
|
||||
utils/xwrap.c
|
||||
utils/xwrap.c \
|
||||
magiskpolicy/rules.c \
|
||||
magiskpolicy/sepolicy.c \
|
||||
magiskpolicy/api.c
|
||||
LOCAL_LDFLAGS := -static
|
||||
include $(BUILD_EXECUTABLE)
|
||||
endif
|
||||
|
@ -12,10 +12,10 @@
|
||||
char *argv0;
|
||||
|
||||
char *applet[] =
|
||||
{ "su", "resetprop", "magisksecilc", "magiskpolicy", "supolicy", "sepolicy-inject", "magiskhide", NULL };
|
||||
{ "su", "resetprop", "magiskpolicy", "supolicy", "sepolicy-inject", "magiskhide", NULL };
|
||||
|
||||
int (*applet_main[]) (int, char *[]) =
|
||||
{ su_client_main, resetprop_main, secilc_main, magiskpolicy_main, magiskpolicy_main, magiskpolicy_main, magiskhide_main, NULL };
|
||||
{ su_client_main, resetprop_main, magiskpolicy_main, magiskpolicy_main, magiskpolicy_main, magiskhide_main, NULL };
|
||||
|
||||
int create_links(const char *bin, const char *path) {
|
||||
char self[PATH_MAX], linkpath[PATH_MAX];
|
||||
|
@ -53,7 +53,6 @@ int create_links(const char *bin, const char *path);
|
||||
int magiskhide_main(int argc, char *argv[]);
|
||||
int magiskpolicy_main(int argc, char *argv[]);
|
||||
int su_client_main(int argc, char *argv[]);
|
||||
int secilc_main(int argc, char *argv[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
116
jni/magiskinit.c
116
jni/magiskinit.c
@ -5,7 +5,8 @@
|
||||
* Magiskinit will mount sysfs, parse through uevent files to make the system block device,
|
||||
* then it'll mount the system partition and clone rootfs except files under /system.
|
||||
* Folders placed in "overlay" will then be overlayed to the root.
|
||||
* Lastly before giving control back to the real init, it'll patch the root files to load Magisk.
|
||||
* Lastly, before giving control back to the real init, it'll patch the root files,
|
||||
* extract (or compile if needed) sepolicy and patch it to load Magisk.
|
||||
*/
|
||||
|
||||
|
||||
@ -22,6 +23,10 @@
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#include <cil/cil.h>
|
||||
|
||||
#include "magiskpolicy.h"
|
||||
|
||||
struct cmdline {
|
||||
int skip_initramfs;
|
||||
char slot[3];
|
||||
@ -35,6 +40,8 @@ struct device {
|
||||
char path[64];
|
||||
};
|
||||
|
||||
extern policydb_t *policydb;
|
||||
|
||||
extern void mmap_ro(const char *filename, void **buf, size_t *size);
|
||||
extern void mmap_rw(const char *filename, void **buf, size_t *size);
|
||||
extern void *patch_init_rc(char *data, uint32_t *size);
|
||||
@ -244,6 +251,107 @@ static void patch_ramdisk() {
|
||||
free(init_rc);
|
||||
}
|
||||
|
||||
static int strend(const char *s1, const char *s2) {
|
||||
int l1 = strlen(s1);
|
||||
int l2 = strlen(s2);
|
||||
return strcmp(s1 + l1 - l2, s2);
|
||||
}
|
||||
|
||||
static void patch_sepolicy() {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
char *sepolicy = NULL, path[128];
|
||||
if (access("/system_root/sepolicy", R_OK) == 0)
|
||||
sepolicy = "/system_root/sepolicy";
|
||||
if (sepolicy == NULL && access("/vendor/etc/selinux/precompiled_sepolicy", R_OK) == 0) {
|
||||
void *sys_sha = NULL, *ven_sha = NULL;
|
||||
size_t sys_size = 0, ven_size = 0;
|
||||
dir = opendir("/vendor/etc/selinux");
|
||||
while ((entry = readdir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
if (strend(entry->d_name, ".sha256") == 0) {
|
||||
snprintf(path, sizeof(path), "/vendor/etc/selinux/%s", entry->d_name);
|
||||
mmap_ro(path, &ven_sha, &ven_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
dir = opendir("/system/etc/selinux");
|
||||
while ((entry = readdir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
if (strend(entry->d_name, ".sha256") == 0) {
|
||||
snprintf(path, sizeof(path), "/system/etc/selinux/%s", entry->d_name);
|
||||
mmap_ro(path, &sys_sha, &sys_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
if (sys_size == ven_size && memcmp(sys_sha, ven_sha, sys_size) == 0)
|
||||
sepolicy = "/vendor/etc/selinux/precompiled_sepolicy";
|
||||
munmap(sys_sha, sys_size);
|
||||
munmap(ven_sha, ven_size);
|
||||
}
|
||||
|
||||
if (sepolicy) {
|
||||
load_policydb(sepolicy);
|
||||
} else {
|
||||
// Compile cil
|
||||
struct cil_db *db = NULL;
|
||||
sepol_policydb_t *pdb = NULL;
|
||||
void *addr;
|
||||
size_t size;
|
||||
|
||||
cil_db_init(&db);
|
||||
cil_set_mls(db, 1);
|
||||
cil_set_target_platform(db, SEPOL_TARGET_SELINUX);
|
||||
cil_set_policy_version(db, POLICYDB_VERSION_XPERMS_IOCTL);
|
||||
cil_set_attrs_expand_generated(db, 0);
|
||||
|
||||
mmap_ro("/system/etc/selinux/plat_sepolicy.cil", &addr, &size);
|
||||
cil_add_file(db, "/system/etc/selinux/plat_sepolicy.cil", addr, size);
|
||||
munmap(addr, size);
|
||||
|
||||
dir = opendir("/system/etc/selinux/mapping");
|
||||
while ((entry = readdir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
if (strend(entry->d_name, ".cil") == 0) {
|
||||
snprintf(path, sizeof(path), "/system/etc/selinux/mapping/%s", entry->d_name);
|
||||
mmap_ro(path, &addr, &size);
|
||||
cil_add_file(db, path, addr, size);
|
||||
munmap(addr, size);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
dir = opendir("/vendor/etc/selinux");
|
||||
while ((entry = readdir(dir))) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
if (strend(entry->d_name, ".cil") == 0) {
|
||||
snprintf(path, sizeof(path), "/vendor/etc/selinux/%s", entry->d_name);
|
||||
mmap_ro(path, &addr, &size);
|
||||
cil_add_file(db, path, addr, size);
|
||||
munmap(addr, size);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
cil_compile(db);
|
||||
cil_build_policydb(db, &pdb);
|
||||
cil_db_destroy(&db);
|
||||
|
||||
policydb = &pdb->p;
|
||||
}
|
||||
|
||||
// Magisk patches
|
||||
sepol_min_rules();
|
||||
dump_policydb("/sepolicy");
|
||||
destroy_policydb();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
umask(0);
|
||||
|
||||
@ -272,12 +380,18 @@ int main(int argc, char *argv[]) {
|
||||
if (overlay > 0)
|
||||
mv_dir(overlay, root);
|
||||
|
||||
snprintf(partname, sizeof(partname), "vendor%s", cmd.slot);
|
||||
setup_block(&dev, partname);
|
||||
mount(dev.path, "/vendor", "ext4", MS_RDONLY, NULL);
|
||||
|
||||
patch_ramdisk();
|
||||
patch_sepolicy();
|
||||
|
||||
close(root);
|
||||
close(system_root);
|
||||
close(overlay);
|
||||
rmdir("/overlay");
|
||||
umount("/vendor");
|
||||
} else {
|
||||
// Recovery mode
|
||||
// Revert original init binary
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 6600772dca2c02a2528429759aeb7856361bfcb4
|
||||
Subproject commit 3c6a170138cacb1f817c65181bd6e3ef15cfca9e
|
@ -213,26 +213,6 @@ if [ ! -z $SHA1 ]; then
|
||||
fi
|
||||
|
||||
if $SKIP_INITRAMFS; then
|
||||
# First check precompiled ones
|
||||
[ -f /system_root/sepolicy ] && cp /system_root/sepolicy sepolicy
|
||||
if [ ! -f sepolicy -a -f /vendor/etc/selinux/precompiled_sepolicy ]; then
|
||||
# Check SHA256
|
||||
SYSTEMSHA256=`find /system/etc/selinux -name '*.sha256' -exec cat {} \; 2>/dev/null`
|
||||
VENDORSHA256=`find /vendor/etc/selinux -name '*.sha256' -exec cat {} \; 2>/dev/null`
|
||||
[ "$SYSTEMSHA256" = "$VENDORSHA256" ] && cp /vendor/etc/selinux/precompiled_sepolicy sepolicy
|
||||
fi
|
||||
if [ ! -f sepolicy ]; then
|
||||
ui_print_wrap "- Compiling split cil policies"
|
||||
# Compile the split policies
|
||||
POLICY_VER=`cat /sys/fs/selinux/policyvers`
|
||||
PLAT_CIL=/system/etc/selinux/plat_sepolicy.cil
|
||||
NONPLAT_CIL=`find /vendor/etc/selinux -name '*.cil' 2>/dev/null`
|
||||
VENDOR_PLAT_VER=`cat /vendor/etc/selinux/plat_sepolicy_vers.txt`
|
||||
MAPPING_CIL=/system/etc/selinux/mapping/${VENDOR_PLAT_VER}.cil
|
||||
./magisk magisksecilc -M true -c $POLICY_VER -o sepolicy -f /dev/null $PLAT_CIL $NONPLAT_CIL $MAPPING_CIL
|
||||
fi
|
||||
[ -f sepolicy ] || abort_wrap "! Cannot get sepolicy"
|
||||
|
||||
cpio_add 750 init ./magiskinit
|
||||
cpio_mkdir 000 overlay
|
||||
cpio_add 750 overlay/init.magisk.rc init.magisk.rc
|
||||
@ -242,6 +222,9 @@ else
|
||||
./magiskboot --cpio-patch ramdisk.cpio $KEEPVERITY $KEEPFORCEENCRYPT
|
||||
|
||||
cpio_extract sepolicy sepolicy
|
||||
./magisk magiskpolicy --load sepolicy --save sepolicy --minimal
|
||||
cpio_add 644 sepolicy sepolicy
|
||||
rm -f sepolicy
|
||||
|
||||
cpio_add 750 init.magisk.rc init.magisk.rc
|
||||
cpio_add 755 sbin/magisk magisk
|
||||
@ -249,11 +232,6 @@ fi
|
||||
|
||||
mv init.magisk.rc.bak init.magisk.rc 2>/dev/null
|
||||
|
||||
# sepolicy patches
|
||||
./magisk magiskpolicy --load sepolicy --save sepolicy --minimal
|
||||
$SKIP_INITRAMFS && cpio_add 644 overlay/sepolicy sepolicy || cpio_add 644 sepolicy sepolicy
|
||||
rm -f sepolicy
|
||||
|
||||
# Create ramdisk backups
|
||||
./magiskboot --cpio-backup ramdisk.cpio ramdisk.cpio.orig
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user