mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 10:35:26 +00:00
ec3705f2ed
Introduce new domain `magisk_client` and new file type `magisk_exec`. Connection to magiskd's always-on socket is restricted to magisk_client only. Whitelisted process domains can transit to magisk_client through executing files labelled magisk_exec. The main magisk binary shall be the only file labelled as magisk_exec throughout the whole system. All processes thus are no longer allowed to connect to magiskd directly without going through the proper magisk binary. Connection failures are silenced from audit logs with dontaudit rules, so crazy processes which traverse through all unix domain sockets to try connection can no longer check logcat to know the actual reason behind EACCES, leaking the denied process policy (which is u:r:magisk:s0). This also allows us to remove many rules that open up holes in untrusted_app domains that were used to make remote shell work properly. Since all processes establishing the remote shell are now restricted to the magisk_client domain, all these rules are moved to magisk_client. This makes Magisk require fewer compromises in Android's security model. Note: as of this commit, requesting new root access via Magisk Manager will stop working as Magisk Manager can no longer communicate with magiskd directly. This will be addressed in a future commit that involves changes in both native and application side.
182 lines
6.8 KiB
C++
182 lines
6.8 KiB
C++
#include <logging.hpp>
|
|
#include <magiskpolicy.hpp>
|
|
|
|
#include "sepolicy.hpp"
|
|
|
|
void sepolicy::magisk_rules() {
|
|
// Temp suppress warnings
|
|
auto bak = log_cb.w;
|
|
log_cb.w = nop_log;
|
|
|
|
// 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");
|
|
typeattribute(SEPOL_FILE_TYPE, "mlstrustedobject");
|
|
|
|
// Make our root domain unconstrained
|
|
allow(SEPOL_PROC_DOMAIN, ALL, ALL, ALL);
|
|
// Allow us to do any ioctl on all block devices
|
|
if (db->policyvers >= POLICYDB_VERSION_XPERMS_IOCTL)
|
|
allowxperm(SEPOL_PROC_DOMAIN, ALL, "blk_file", ALL);
|
|
|
|
// Create unconstrained file type
|
|
allow(ALL, SEPOL_FILE_TYPE, "file", ALL);
|
|
allow(ALL, SEPOL_FILE_TYPE, "dir", ALL);
|
|
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");
|
|
|
|
// 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)
|
|
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);
|
|
|
|
// Let everyone access tmpfs files (for SAR sbin overlay)
|
|
allow(ALL, "tmpfs", "file", ALL);
|
|
|
|
// For relabelling files
|
|
allow("rootfs", "labeledfs", "filesystem", "associate");
|
|
allow(SEPOL_FILE_TYPE, "pipefs", "filesystem", "associate");
|
|
allow(SEPOL_FILE_TYPE, "devpts", "filesystem", "associate");
|
|
|
|
// Let init transit to SEPOL_PROC_DOMAIN
|
|
allow("kernel", "kernel", "process", "setcurrent");
|
|
allow("kernel", SEPOL_PROC_DOMAIN, "process", "dyntransition");
|
|
|
|
// Let init run stuffs
|
|
allow("kernel", SEPOL_PROC_DOMAIN, "fd", "use");
|
|
allow("init", SEPOL_PROC_DOMAIN, "process", ALL);
|
|
allow("init", "tmpfs", "file", "getattr");
|
|
allow("init", "tmpfs", "file", "execute");
|
|
|
|
// suRights
|
|
allow("servicemanager", SEPOL_PROC_DOMAIN, "dir", "search");
|
|
allow("servicemanager", SEPOL_PROC_DOMAIN, "dir", "read");
|
|
allow("servicemanager", SEPOL_PROC_DOMAIN, "file", "open");
|
|
allow("servicemanager", SEPOL_PROC_DOMAIN, "file", "read");
|
|
allow("servicemanager", SEPOL_PROC_DOMAIN, "process", "getattr");
|
|
allow("servicemanager", SEPOL_PROC_DOMAIN, "binder", "transfer");
|
|
allow(ALL, SEPOL_PROC_DOMAIN, "process", "sigchld");
|
|
|
|
// allowLog
|
|
allow("logd", SEPOL_PROC_DOMAIN, "dir", "search");
|
|
allow("logd", SEPOL_PROC_DOMAIN, "file", "read");
|
|
allow("logd", SEPOL_PROC_DOMAIN, "file", "open");
|
|
allow("logd", SEPOL_PROC_DOMAIN, "file", "getattr");
|
|
|
|
// suBackL6
|
|
allow("surfaceflinger", "app_data_file", "dir", ALL);
|
|
allow("surfaceflinger", "app_data_file", "file", ALL);
|
|
allow("surfaceflinger", "app_data_file", "lnk_file", ALL);
|
|
typeattribute("surfaceflinger", "mlstrustedsubject");
|
|
|
|
// suMiscL6
|
|
allow("audioserver", "audioserver", "process", "execmem");
|
|
|
|
// Liveboot
|
|
allow("surfaceflinger", SEPOL_PROC_DOMAIN, "process", "ptrace");
|
|
allow("surfaceflinger", SEPOL_PROC_DOMAIN, "binder", "transfer");
|
|
allow("surfaceflinger", SEPOL_PROC_DOMAIN, "binder", "call");
|
|
allow("surfaceflinger", SEPOL_PROC_DOMAIN, "fd", "use");
|
|
allow("debuggerd", SEPOL_PROC_DOMAIN, "process", "ptrace");
|
|
|
|
// dumpsys
|
|
allow(ALL, SEPOL_PROC_DOMAIN, "fd", "use");
|
|
allow(ALL, SEPOL_PROC_DOMAIN, "fifo_file", "write");
|
|
allow(ALL, SEPOL_PROC_DOMAIN, "fifo_file", "read");
|
|
allow(ALL, SEPOL_PROC_DOMAIN, "fifo_file", "open");
|
|
allow(ALL, SEPOL_PROC_DOMAIN, "fifo_file", "getattr");
|
|
|
|
// bootctl
|
|
allow("hwservicemanager", SEPOL_PROC_DOMAIN, "dir", "search");
|
|
allow("hwservicemanager", SEPOL_PROC_DOMAIN, "file", "read");
|
|
allow("hwservicemanager", SEPOL_PROC_DOMAIN, "file", "open");
|
|
allow("hwservicemanager", SEPOL_PROC_DOMAIN, "process", "getattr");
|
|
allow("hwservicemanager", SEPOL_PROC_DOMAIN, "binder", "transfer");
|
|
|
|
// For mounting loop devices, mirrors, tmpfs
|
|
allow("kernel", ALL, "file", "read");
|
|
allow("kernel", ALL, "file", "write");
|
|
|
|
// Allow all binder transactions
|
|
allow(ALL, SEPOL_PROC_DOMAIN, "binder", ALL);
|
|
|
|
// For changing file context
|
|
allow("rootfs", "tmpfs", "filesystem", "associate");
|
|
|
|
// Xposed
|
|
allow("untrusted_app", "untrusted_app", "capability", "setgid");
|
|
allow("system_server", "dex2oat_exec", "file", ALL);
|
|
|
|
// Support deodexed ROM on Oreo
|
|
allow("zygote", "dalvikcache_data_file", "file", "execute");
|
|
|
|
// Support deodexed ROM on Pie (Samsung)
|
|
allow("system_server", "dalvikcache_data_file", "file", "write");
|
|
allow("system_server", "dalvikcache_data_file", "file", "execute");
|
|
|
|
// Allow update_engine/addon.d-v2 to run permissive on all ROMs
|
|
permissive("update_engine");
|
|
|
|
#if 0
|
|
// Remove all dontaudit in debug mode
|
|
impl->strip_dontaudit();
|
|
#endif
|
|
|
|
log_cb.w = bak;
|
|
}
|