diff --git a/magiskpolicy.c b/magiskpolicy.c index 858588be9..f5fdbd761 100644 --- a/magiskpolicy.c +++ b/magiskpolicy.c @@ -58,14 +58,15 @@ static void statements() { static void usage(char *arg0) { fprintf(stderr, - "MagiskPolicy v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu & phh) - sepolicy Modification Tool\n\n" + "MagiskPolicy v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu)\n\n" "Usage: %s [--options...] [policystatements...]\n\n" "Options:\n" - " --live directly load patched policy to device\n" - " --minimal minimal patches, used for boot image patches\n" - " --load load policies from \n" - " (load from live policies if not specified)\n" - " --save save policies to \n\n" + " --live directly apply patched policy live\n" + " --magisk built-in rules for a Magisk selinux environment\n" + " --load FILE load policies from \n" + " --save FILE save policies to \n\n" + "If no input file is specified, it will load from current policies\n" + "If neither --live nor --save is specified, nothing will happen\n\n" , arg0); statements(); exit(1); @@ -381,7 +382,7 @@ static void syntax_error_msg() { int magiskpolicy_main(int argc, char *argv[]) { char *infile = NULL, *outfile = NULL, *tok, *saveptr; - int live = 0, minimal = 0; + int live = 0, magisk = 0; struct vector rules; vec_init(&rules); @@ -391,8 +392,8 @@ int magiskpolicy_main(int argc, char *argv[]) { if (argv[i][0] == '-' && argv[i][1] == '-') { if (strcmp(argv[i], "--live") == 0) live = 1; - else if (strcmp(argv[i], "--minimal") == 0) - minimal = 1; + else if (strcmp(argv[i], "--magisk") == 0) + magisk = 1; else if (strcmp(argv[i], "--load") == 0) { if (i + 1 >= argc) usage(argv[0]); infile = argv[i + 1]; @@ -403,8 +404,9 @@ int magiskpolicy_main(int argc, char *argv[]) { i += 1; } else usage(argv[0]); - } else + } else { vec_push_back(&rules, argv[i]); + } } // Use current policy if not specified @@ -416,8 +418,8 @@ int magiskpolicy_main(int argc, char *argv[]) { return 1; } - if (minimal) - sepol_min_rules(); + if (magisk) + sepol_magisk_rules(); for (int i = 0; i < rules.size; ++i) { // Since strtok will modify the origin string, copy the policy for error messages @@ -472,11 +474,10 @@ int magiskpolicy_main(int argc, char *argv[]) { if (live) outfile = SELINUX_LOAD; - if (outfile) - if (dump_policydb(outfile)) { - fprintf(stderr, "Cannot dump policy to %s\n", outfile); - return 1; - } + if (outfile && dump_policydb(outfile)) { + fprintf(stderr, "Cannot dump policy to %s\n", outfile); + return 1; + } destroy_policydb(); return 0; diff --git a/magiskpolicy.h b/magiskpolicy.h new file mode 100644 index 000000000..5d88a86b7 --- /dev/null +++ b/magiskpolicy.h @@ -0,0 +1,34 @@ +/* magiskpolicy.h - Public API for policy patching + */ + +#ifndef _MAGISKPOLICY_H +#define _MAGISKPOLICY_H + +#include + +#define ALL NULL + +// policydb functions +int load_policydb(const char *filename); +int dump_policydb(const char *filename); +void destroy_policydb(); + +// Handy functions +int sepol_allow(char *s, char *t, char *c, char *p); +int sepol_deny(char *s, char *t, char *c, char *p); +int sepol_auditallow(char *s, char *t, char *c, char *p); +int sepol_auditdeny(char *s, char *t, char *c, char *p); +int sepol_typetrans(char *s, char *t, char *c, char *d, char *o); +int sepol_allowxperm(char *s, char *t, char *c, char *range); +int sepol_auditallowxperm(char *s, char *t, char *c, char *range); +int sepol_dontauditxperm(char *s, char *t, char *c, char *range); +int sepol_create(char *s); +int sepol_permissive(char *s); +int sepol_enforce(char *s); +int sepol_attradd(char *s, char *a); +int sepol_exists(char *source); + +// Built in rules +void sepol_magisk_rules(); + +#endif diff --git a/rules.c b/rules.c index 8683e6904..5a4e1934b 100644 --- a/rules.c +++ b/rules.c @@ -1,70 +1,6 @@ #include "magiskpolicy.h" #include "sepolicy.h" -void samsung() { - sepol_deny("init", "kernel", "security", "load_policy"); - sepol_deny("policyloader_app", "security_spota_file", "dir", "read"); - sepol_deny("policyloader_app", "security_spota_file", "dir", "write"); - sepol_deny("policyloader_app", "security_spota_file", "file", "read"); - sepol_deny("policyloader_app", "security_spota_file", "file", "write"); - sepol_deny("system_server", "security_spota_file", "dir", "read"); - sepol_deny("system_server", "security_spota_file", "dir", "write"); - sepol_deny("system_server", "security_spota_file", "file", "read"); - sepol_deny("system_server", "security_spota_file", "file", "write"); - sepol_deny("system_app", "security_spota_file", "dir", "read"); - sepol_deny("system_app", "security_spota_file", "dir", "write"); - sepol_deny("system_app", "security_spota_file", "file", "read"); - sepol_deny("system_app", "security_spota_file", "file", "write"); - sepol_deny("installd", "security_spota_file", "dir", "read"); - sepol_deny("installd", "security_spota_file", "dir", "write"); - sepol_deny("installd", "security_spota_file", "file", "read"); - sepol_deny("installd", "security_spota_file", "file", "write"); - sepol_deny("init", "security_spota_file", "dir", "read"); - sepol_deny("init", "security_spota_file", "dir", "write"); - sepol_deny("init", "security_spota_file", "file", "read"); - sepol_deny("init", "security_spota_file", "file", "write"); - sepol_deny("ueventd", "security_spota_file", "dir", "read"); - sepol_deny("ueventd", "security_spota_file", "dir", "write"); - sepol_deny("ueventd", "security_spota_file", "file", "read"); - sepol_deny("ueventd", "security_spota_file", "file", "write"); - sepol_deny("runas", "security_spota_file", "dir", "read"); - sepol_deny("runas", "security_spota_file", "dir", "write"); - sepol_deny("runas", "security_spota_file", "file", "read"); - sepol_deny("runas", "security_spota_file", "file", "write"); - sepol_deny("drsd", "security_spota_file", "dir", "read"); - sepol_deny("drsd", "security_spota_file", "dir", "write"); - sepol_deny("drsd", "security_spota_file", "file", "read"); - sepol_deny("drsd", "security_spota_file", "file", "write"); - sepol_deny("debuggerd", "security_spota_file", "dir", "read"); - sepol_deny("debuggerd", "security_spota_file", "dir", "write"); - sepol_deny("debuggerd", "security_spota_file", "file", "read"); - sepol_deny("debuggerd", "security_spota_file", "file", "write"); - sepol_deny("vold", "security_spota_file", "dir", "read"); - sepol_deny("vold", "security_spota_file", "dir", "write"); - sepol_deny("vold", "security_spota_file", "file", "read"); - sepol_deny("vold", "security_spota_file", "file", "write"); - sepol_deny("zygote", "security_spota_file", "dir", "read"); - sepol_deny("zygote", "security_spota_file", "dir", "write"); - sepol_deny("zygote", "security_spota_file", "file", "read"); - sepol_deny("zygote", "security_spota_file", "file", "write"); - sepol_deny("auditd", "security_spota_file", "dir", "read"); - sepol_deny("auditd", "security_spota_file", "dir", "write"); - sepol_deny("auditd", "security_spota_file", "file", "read"); - sepol_deny("auditd", "security_spota_file", "file", "write"); - sepol_deny("servicemanager", "security_spota_file", "dir", "read"); - sepol_deny("servicemanager", "security_spota_file", "dir", "write"); - sepol_deny("servicemanager", "security_spota_file", "file", "read"); - sepol_deny("servicemanager", "security_spota_file", "file", "write"); - sepol_deny("itsonbs", "security_spota_file", "dir", "read"); - sepol_deny("itsonbs", "security_spota_file", "dir", "write"); - sepol_deny("itsonbs", "security_spota_file", "file", "read"); - sepol_deny("itsonbs", "security_spota_file", "file", "write"); - sepol_deny("commonplatformappdomain", "security_spota_file", "dir", "read"); - sepol_deny("commonplatformappdomain", "security_spota_file", "dir", "write"); - sepol_deny("commonplatformappdomain", "security_spota_file", "file", "read"); - sepol_deny("commonplatformappdomain", "security_spota_file", "file", "write"); -} - void allowSuClient(char *target) { sepol_allow(target, "rootfs", "file", ALL); sepol_allow(target, "rootfs", "lnk_file", ALL); @@ -149,10 +85,19 @@ void otherToSU() { sepol_allow("surfaceflinger", "su", "binder", "call"); sepol_allow("surfaceflinger", "su", "fd", "use"); sepol_allow("debuggerd", "su", "process", "ptrace"); + + // dumpsys + sepol_allow(ALL, "su", "fd", "use"); + sepol_allow(ALL, "su", "fifo_file", "write"); + sepol_allow(ALL, "su", "fifo_file", "read"); + sepol_allow(ALL, "su", "fifo_file", "open"); + sepol_allow(ALL, "su", "fifo_file", "getattr"); } -// Minimal boot image patch, Samsung requires these patches -void sepol_min_rules() { +void sepol_magisk_rules() { + // First prevent anything to change sepolicy except ourselves + sepol_deny(ALL, "kernel", "security", "load_policy"); + if (!sepol_exists("su")) sepol_create("su"); if (!sepol_exists("su_device")) @@ -163,7 +108,7 @@ void sepol_min_rules() { sepol_attradd("su", "mlstrustedsubject"); sepol_attradd("su_device", "mlstrustedobject"); - // Let magiskinit daemon monitor and transit to su + // Allow magiskinit daemon to run and run in su context sepol_allow("kernel", "device", "dir", ALL); sepol_allow("kernel", "device", "file", ALL); sepol_allow("kernel", "su", "unix_stream_socket", "connectto"); @@ -177,11 +122,6 @@ void sepol_min_rules() { sepol_allow("init", "system_file", "lnk_file", ALL); sepol_allow("init", "system_file", "file", ALL); - // Samsung specific - // Prevent system from loading policy - if(sepol_exists("knox_system_app")) - samsung(); - // Shell, prop management, simple su rights, logs sepol_allow("su", "property_socket", "sock_file", "write"); sepol_allow("su", "properties_device", "file", "write"); @@ -228,12 +168,34 @@ void sepol_min_rules() { sepol_allow("su", "selinuxfs", "file", "open"); sepol_allow("su", "selinuxfs", "file", "write"); + // Allow these client to access su + allowSuClient("shell"); + allowSuClient("untrusted_app"); + allowSuClient("system_app"); + allowSuClient("platform_app"); + if (sepol_exists("priv_app")) + allowSuClient("priv_app"); + if (sepol_exists("ssd_tool")) + allowSuClient("ssd_tool"); + if (sepol_exists("untrusted_app_25")) + allowSuClient("untrusted_app_25"); + + // Some superuser stuffs + suRights(); + otherToSU(); + // For mounting loop devices and mirrors sepol_allow("su", "kernel", "process", "setsched"); sepol_allow("su", "labeledfs", "filesystem", "mount"); sepol_allow("su", "labeledfs", "filesystem", "unmount"); sepol_allow("kernel", ALL, "file", "read"); + // Allow su to do anything to any files/dir/links + sepol_allow("su", ALL, "file", ALL); + sepol_allow("su", ALL, "dir", ALL); + sepol_allow("su", ALL, "lnk_file", ALL); + sepol_allow("su", ALL, "blk_file", ALL); + // For changing attributes sepol_allow("rootfs", "tmpfs", "filesystem", "associate"); @@ -248,33 +210,3 @@ void sepol_min_rules() { } } -void sepol_med_rules() { - sepol_min_rules(); - - // Allow su to do anything to any files/dir/links - sepol_allow("su", ALL, "file", ALL); - sepol_allow("su", ALL, "dir", ALL); - sepol_allow("su", ALL, "lnk_file", ALL); - sepol_allow("su", ALL, "blk_file", ALL); - - // Allow these client to access su - allowSuClient("shell"); - allowSuClient("untrusted_app"); - allowSuClient("system_app"); - allowSuClient("platform_app"); - if (sepol_exists("priv_app")) - allowSuClient("priv_app"); - if (sepol_exists("ssd_tool")) - allowSuClient("ssd_tool"); - if (sepol_exists("untrusted_app_25")) - allowSuClient("untrusted_app_25"); - - suRights(); - otherToSU(); -} - -void sepol_full_rules() { - // Patch su to everything - sepol_allow("su", ALL, ALL, ALL); -} - diff --git a/sepolicy.c b/sepolicy.c index 691686246..cda8fac33 100644 --- a/sepolicy.c +++ b/sepolicy.c @@ -255,7 +255,7 @@ int dump_policydb(const char *filename) { return 1; } - fd = open(filename, O_RDWR | O_CREAT, 0644); + fd = creat(filename, 0644); if (fd < 0) { fprintf(stderr, "Can't open '%s': %s\n", filename, strerror(errno));