From 97b72a5941828b13839495d29c0d9138931a6598 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Mon, 6 Jul 2020 01:13:50 -0700 Subject: [PATCH] Revert to old SElinux rules on pre 8.0 devices Fix #2910 --- native/jni/core/daemon.cpp | 28 +++---- native/jni/core/restorecon.cpp | 3 +- native/jni/magiskpolicy/rules.cpp | 130 ++++++++++++++++++------------ scripts/emulator.sh | 5 +- 4 files changed, 96 insertions(+), 70 deletions(-) diff --git a/native/jni/core/daemon.cpp b/native/jni/core/daemon.cpp index 80329a39e..4e1e1350f 100644 --- a/native/jni/core/daemon.cpp +++ b/native/jni/core/daemon.cpp @@ -156,6 +156,8 @@ static void daemon_entry(int ppid) { setsid(); setcon("u:r:" SEPOL_PROC_DOMAIN ":s0"); + LOGI(NAME_WITH_VER(Magisk) " daemon started\n"); + // Make sure ppid is not in acct char src[64], dest[64]; sprintf(src, "/acct/uid_0/pid_%d", ppid); @@ -167,20 +169,6 @@ static void daemon_entry(int ppid) { MAGISKTMP = dirname(src); xstat("/proc/self/exe", &self_st); - restore_tmpcon(); - - // SAR cleanups - auto mount_list = MAGISKTMP + "/" ROOTMNT; - if (access(mount_list.data(), F_OK) == 0) { - file_readline(true, mount_list.data(), [](string_view line) -> bool { - umount2(line.data(), MNT_DETACH); - return true; - }); - } - unlink("/dev/.se"); - - LOGI(NAME_WITH_VER(Magisk) " daemon started\n"); - // Get API level parse_prop_file("/system/build.prop", [](auto key, auto val) -> bool { if (key == "ro.build.version.sdk") { @@ -198,6 +186,18 @@ static void daemon_entry(int ppid) { } LOGI("* Device API level: %d\n", SDK_INT); + restore_tmpcon(); + + // SAR cleanups + auto mount_list = MAGISKTMP + "/" ROOTMNT; + if (access(mount_list.data(), F_OK) == 0) { + file_readline(true, mount_list.data(), [](string_view line) -> bool { + umount2(line.data(), MNT_DETACH); + return true; + }); + } + unlink("/dev/.se"); + // Load config status auto config = MAGISKTMP + "/" INTLROOT "/config"; parse_prop_file(config.data(), [](auto key, auto val) -> bool { diff --git a/native/jni/core/restorecon.cpp b/native/jni/core/restorecon.cpp index 502e79d03..88a95e8da 100644 --- a/native/jni/core/restorecon.cpp +++ b/native/jni/core/restorecon.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -87,7 +88,7 @@ void restore_tmpcon() { int dfd = dirfd(dir.get()); for (dirent *entry; (entry = xreaddir(dir.get()));) { - if (entry->d_name == "magisk"sv) + if (SDK_INT >= 26 && entry->d_name == "magisk"sv) setfilecon_at(dfd, entry->d_name, EXEC_CON); else setfilecon_at(dfd, entry->d_name, SYSTEM_CON); diff --git a/native/jni/magiskpolicy/rules.cpp b/native/jni/magiskpolicy/rules.cpp index c790693ce..623a689cf 100644 --- a/native/jni/magiskpolicy/rules.cpp +++ b/native/jni/magiskpolicy/rules.cpp @@ -8,17 +8,18 @@ void sepolicy::magisk_rules() { auto bak = log_cb.w; log_cb.w = nop_log; + // This indicates API 26+ + bool new_rules = exists("untrusted_app_25"); + // Prevent anything to change sepolicy except ourselves deny(ALL, "kernel", "security", "load_policy"); type(SEPOL_PROC_DOMAIN, "domain"); - type(SEPOL_CLIENT_DOMAIN, "domain"); - type(SEPOL_FILE_TYPE, "file_type"); - type(SEPOL_EXEC_TYPE, "file_type"); permissive(SEPOL_PROC_DOMAIN); /* Just in case something is missing */ typeattribute(SEPOL_PROC_DOMAIN, "mlstrustedsubject"); typeattribute(SEPOL_PROC_DOMAIN, "netdomain"); typeattribute(SEPOL_PROC_DOMAIN, "bluetoothdomain"); + type(SEPOL_FILE_TYPE, "file_type"); typeattribute(SEPOL_FILE_TYPE, "mlstrustedobject"); // Make our root domain unconstrained @@ -33,58 +34,85 @@ void sepolicy::magisk_rules() { allow(ALL, SEPOL_FILE_TYPE, "fifo_file", ALL); allow(ALL, SEPOL_FILE_TYPE, "chr_file", ALL); - // Basic su client needs - allow(SEPOL_CLIENT_DOMAIN, ALL, "fd", "use"); - allow(SEPOL_CLIENT_DOMAIN, SEPOL_CLIENT_DOMAIN, ALL, ALL); - allow(SEPOL_CLIENT_DOMAIN, SEPOL_EXEC_TYPE, "file", ALL); - allow(SEPOL_CLIENT_DOMAIN, SEPOL_PROC_DOMAIN, "unix_stream_socket", "connectto"); - allow(SEPOL_CLIENT_DOMAIN, SEPOL_PROC_DOMAIN, "unix_stream_socket", "getopt"); + if (new_rules) { + type(SEPOL_CLIENT_DOMAIN, "domain"); + type(SEPOL_EXEC_TYPE, "file_type"); - // Allow su client to manipulate pts - const char *pts[] { - "devpts", "untrusted_app_devpts", "untrusted_app_25_devpts", "untrusted_app_all_devpts" }; - for (auto type : pts) { - allow(SEPOL_CLIENT_DOMAIN, type, "chr_file", "read"); - allow(SEPOL_CLIENT_DOMAIN, type, "chr_file", "write"); - allow(SEPOL_CLIENT_DOMAIN, type, "chr_file", "getattr"); - allow(SEPOL_CLIENT_DOMAIN, type, "chr_file", "ioctl"); - if (db->policyvers >= POLICYDB_VERSION_XPERMS_IOCTL) + // Basic su client needs + allow(SEPOL_CLIENT_DOMAIN, ALL, "fd", "use"); + allow(SEPOL_CLIENT_DOMAIN, SEPOL_CLIENT_DOMAIN, ALL, ALL); + allow(SEPOL_CLIENT_DOMAIN, SEPOL_EXEC_TYPE, "file", ALL); + allow(SEPOL_CLIENT_DOMAIN, SEPOL_PROC_DOMAIN, "unix_stream_socket", "connectto"); + allow(SEPOL_CLIENT_DOMAIN, SEPOL_PROC_DOMAIN, "unix_stream_socket", "getopt"); + + // Allow su client termios ioctl + const char *pts[] { + "devpts", "untrusted_app_devpts", + "untrusted_app_25_devpts", "untrusted_app_all_devpts" }; + for (auto type : pts) { + if (!exists(type)) + continue; + allow(SEPOL_CLIENT_DOMAIN, type, "chr_file", "read"); + allow(SEPOL_CLIENT_DOMAIN, type, "chr_file", "write"); + allow(SEPOL_CLIENT_DOMAIN, type, "chr_file", "getattr"); + allow(SEPOL_CLIENT_DOMAIN, type, "chr_file", "ioctl"); allowxperm(SEPOL_CLIENT_DOMAIN, type, "chr_file", "0x5400-0x54FF"); + } + + // Allow these processes to access MagiskSU + const char *clients[] { + "init", "shell", "system_app", "priv_app", "platform_app", "untrusted_app", + "untrusted_app_25", "untrusted_app_27", "untrusted_app_29", "update_engine" }; + for (auto type : clients) { + if (!exists(type)) + continue; + // exec magisk + allow(type, SEPOL_EXEC_TYPE, "file", "read"); + allow(type, SEPOL_EXEC_TYPE, "file", "open"); + allow(type, SEPOL_EXEC_TYPE, "file", "getattr"); + allow(type, SEPOL_EXEC_TYPE, "file", "execute"); + + // Auto transit to client domain + type_transition(type, SEPOL_EXEC_TYPE, "process", SEPOL_CLIENT_DOMAIN); + allow(type, SEPOL_CLIENT_DOMAIN, "process", "transition"); + dontaudit(type, SEPOL_CLIENT_DOMAIN, "process", "siginh"); + dontaudit(type, SEPOL_CLIENT_DOMAIN, "process", "rlimitinh"); + dontaudit(type, SEPOL_CLIENT_DOMAIN, "process", "noatsecure"); + + allow(SEPOL_CLIENT_DOMAIN, type, "process", "sigchld"); + allow(SEPOL_CLIENT_DOMAIN, type, "fifo_file", "read"); + allow(SEPOL_CLIENT_DOMAIN, type, "fifo_file", "write"); + allow(SEPOL_CLIENT_DOMAIN, type, "fifo_file", "ioctl"); + } + + // Allow system_server to manage magisk_client + allow("system_server", SEPOL_CLIENT_DOMAIN, "process", "getpgid"); + allow("system_server", SEPOL_CLIENT_DOMAIN, "process", "sigkill"); + + // Don't allow pesky processes to monitor audit deny logs when poking magisk daemon sockets + dontaudit(ALL, SEPOL_PROC_DOMAIN, "unix_stream_socket", ALL); + } else { + // Fallback to poking holes in sandbox as Android 4.3 to 7.1 set PR_SET_NO_NEW_PRIVS + + // Allow these processes to access MagiskSU + const char *clients[] { + "init", "shell", "system_app", "priv_app", "platform_app", "untrusted_app" }; + for (auto type : clients) { + if (!exists(type)) + continue; + allow(type, SEPOL_PROC_DOMAIN, "unix_stream_socket", "connectto"); + allow(type, SEPOL_PROC_DOMAIN, "unix_stream_socket", "getopt"); + + // Allow termios ioctl + const char *pts[] { "devpts", "untrusted_app_devpts" }; + for (auto pts_type : pts) { + allow(type, pts_type, "chr_file", "ioctl"); + if (db->policyvers >= POLICYDB_VERSION_XPERMS_IOCTL) + allowxperm(type, pts_type, "chr_file", "0x5400-0x54FF"); + } + } } - // Allow these processes to access MagiskSU - const char *clients[] { - "init", "shell", "system_app", "priv_app", "platform_app", "untrusted_app", - "untrusted_app_25", "untrusted_app_27", "untrusted_app_29", "update_engine" }; - for (auto type : clients) { - if (!exists(type)) - continue; - // exec magisk - allow(type, SEPOL_EXEC_TYPE, "file", "read"); - allow(type, SEPOL_EXEC_TYPE, "file", "open"); - allow(type, SEPOL_EXEC_TYPE, "file", "getattr"); - allow(type, SEPOL_EXEC_TYPE, "file", "execute"); - - // Auto transit to client domain - type_transition(type, SEPOL_EXEC_TYPE, "process", SEPOL_CLIENT_DOMAIN); - allow(type, SEPOL_CLIENT_DOMAIN, "process", "transition"); - dontaudit(type, SEPOL_CLIENT_DOMAIN, "process", "siginh"); - dontaudit(type, SEPOL_CLIENT_DOMAIN, "process", "rlimitinh"); - dontaudit(type, SEPOL_CLIENT_DOMAIN, "process", "noatsecure"); - - allow(SEPOL_CLIENT_DOMAIN, type, "process", "sigchld"); - allow(SEPOL_CLIENT_DOMAIN, type, "fifo_file", "read"); - allow(SEPOL_CLIENT_DOMAIN, type, "fifo_file", "write"); - allow(SEPOL_CLIENT_DOMAIN, type, "fifo_file", "ioctl"); - } - - // Allow system_server to manage magisk_client - allow("system_server", SEPOL_CLIENT_DOMAIN, "process", "getpgid"); - allow("system_server", SEPOL_CLIENT_DOMAIN, "process", "sigkill"); - - // Don't allow pesky processes to monitor audit deny logs when poking magisk daemon sockets - dontaudit(ALL, SEPOL_PROC_DOMAIN, "unix_stream_socket", ALL); - // Let everyone access tmpfs files (for SAR sbin overlay) allow(ALL, "tmpfs", "file", ALL); diff --git a/scripts/emulator.sh b/scripts/emulator.sh index 53fa6d1f0..e91476da2 100755 --- a/scripts/emulator.sh +++ b/scripts/emulator.sh @@ -57,7 +57,7 @@ pgrep magiskd >/dev/null && pkill -9 magiskd [ -e /sys/fs/selinux ] && SELINUX=true || SELINUX=false if $SELINUX; then ln -sf ./magiskinit magiskpolicy - ./magiskpolicy --live --magisk 'allow magisk * * *' + ./magiskpolicy --live --magisk fi # Setup sbin overlay @@ -94,9 +94,6 @@ chmod 755 /sbin/magisk ln -s ./magisk /sbin/su ln -s ./magisk /sbin/resetprop ln -s ./magisk /sbin/magiskhide -mkdir -p /sbin/.magisk/busybox -cp -af ./busybox /sbin/.magisk/busybox/busybox -/sbin/.magisk/busybox/busybox --install -s /sbin/.magisk/busybox mkdir -p /data/adb/modules 2>/dev/null mkdir /data/adb/post-fs-data.d 2>/dev/null mkdir /data/adb/services.d 2>/dev/null