Skip to content
This repository has been archived by the owner on Nov 30, 2023. It is now read-only.

Commit

Permalink
Modernize magiskpolicy
Browse files Browse the repository at this point in the history
  • Loading branch information
topjohnwu committed May 21, 2020
1 parent e02e46d commit d4baae4
Show file tree
Hide file tree
Showing 9 changed files with 587 additions and 743 deletions.
87 changes: 52 additions & 35 deletions native/jni/include/magiskpolicy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,55 @@
#include <stdlib.h>
#include <selinux.hpp>

#define ALL NULL

// policydb functions
int load_policydb(const char *file);
int load_split_cil();
int compile_split_cil();
int dump_policydb(const char *file);
void destroy_policydb();

// Handy functions
int sepol_allow(const char *s, const char *t, const char *c, const char *p);
int sepol_deny(const char *s, const char *t, const char *c, const char *p);
int sepol_auditallow(const char *s, const char *t, const char *c, const char *p);
int sepol_dontaudit(const char *s, const char *t, const char *c, const char *p);
int sepol_typetrans(const char *s, const char *t, const char *c, const char *d);
int sepol_typechange(const char *s, const char *t, const char *c, const char *d);
int sepol_typemember(const char *s, const char *t, const char *c, const char *d);
int sepol_nametrans(const char *s, const char *t, const char *c, const char *d, const char *o);
int sepol_allowxperm(const char *s, const char *t, const char *c, const char *range);
int sepol_auditallowxperm(const char *s, const char *t, const char *c, const char *range);
int sepol_dontauditxperm(const char *s, const char *t, const char *c, const char *range);
int sepol_create(const char *s);
int sepol_permissive(const char *s);
int sepol_enforce(const char *s);
int sepol_attradd(const char *s, const char *a);
int sepol_genfscon(const char *name, const char *path, const char *context);
int sepol_exists(const char *source);

// Built in rules
void sepol_magisk_rules();

// Statement parsing
void parse_statement(const char *statement);
void load_rule_file(const char *file);
void statement_help();
#define ALL nullptr

struct policydb;

class sepolicy {
public:
typedef const char * c_str;
~sepolicy();

// Public static factory functions
static sepolicy *from_file(c_str file);
static sepolicy *from_split();
static sepolicy *compile_split();

// External APIs
int to_file(c_str file);
void parse_statement(c_str stmt);
void load_rule_file(c_str file);

// Operation on types
int create(c_str type);
int permissive(c_str type);
int enforce(c_str type);
int typeattribute(c_str type, c_str attr);
int exists(c_str type);

// Access vector rules
int allow(c_str src, c_str tgt, c_str cls, c_str perm);
int deny(c_str src, c_str tgt, c_str cls, c_str perm);
int auditallow(c_str src, c_str tgt, c_str cls, c_str perm);
int dontaudit(c_str src, c_str tgt, c_str cls, c_str perm);

// Extended permissions access vector rules
int allowxperm(c_str src, c_str tgt, c_str cls, c_str range);
int auditallowxperm(c_str src, c_str tgt, c_str cls, c_str range);
int dontauditxperm(c_str src, c_str tgt, c_str cls, c_str range);

// Type rules
int type_transition(c_str src, c_str tgt, c_str cls, c_str def, c_str obj = nullptr);
int type_change(c_str src, c_str tgt, c_str cls, c_str def);
int type_member(c_str src, c_str tgt, c_str cls, c_str def);

// File system labeling
int genfscon(c_str fs_name, c_str path, c_str ctx);

// Magisk
void magisk_rules();
void allow_su_client(c_str type);

private:
policydb *db;
};
15 changes: 8 additions & 7 deletions native/jni/init/rootdir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,14 @@ void RootFSInit::setup_rootfs() {

bool MagiskInit::patch_sepolicy(const char *file) {
bool patch_init = false;
sepolicy *sepol = nullptr;

if (access(SPLIT_PLAT_CIL, R_OK) == 0) {
LOGD("sepol: split policy\n");
patch_init = true;
} else if (access("/sepolicy", R_OK) == 0) {
LOGD("sepol: monolithic policy\n");
load_policydb("/sepolicy");
sepol = sepolicy::from_file("/sepolicy");
} else {
LOGD("sepol: no selinux\n");
return false;
Expand All @@ -148,24 +149,24 @@ bool MagiskInit::patch_sepolicy(const char *file) {
}

if (patch_init)
load_split_cil();
sepol = sepolicy::from_split();

sepol_magisk_rules();
sepol_allow(SEPOL_PROC_DOMAIN, ALL, ALL, ALL);
sepol->magisk_rules();
sepol->allow(SEPOL_PROC_DOMAIN, ALL, ALL, ALL);

// Custom rules
if (auto dir = open_dir(persist_dir.data()); dir) {
for (dirent *entry; (entry = xreaddir(dir.get()));) {
auto rule = persist_dir + "/" + entry->d_name + "/sepolicy.rule";
if (access(rule.data(), R_OK) == 0) {
LOGD("Loading custom sepolicy patch: %s\n", rule.data());
load_rule_file(rule.data());
sepol->load_rule_file(rule.data());
}
}
}

dump_policydb(file);
destroy_policydb();
sepol->to_file(file);
delete sepol;

// Remove OnePlus stupid debug sepolicy and use our own
if (access("/sepolicy_debug", F_OK) == 0) {
Expand Down
80 changes: 40 additions & 40 deletions native/jni/magiskpolicy/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,86 +5,86 @@
//#define vprint(fmt, ...) printf(fmt, __VA_ARGS__)
#define vprint(...)

int sepol_allow(const char *s, const char *t, const char *c, const char *p) {
int sepolicy::allow(const char *s, const char *t, const char *c, const char *p) {
vprint("allow %s %s %s %s\n", s, t, c, p);
return add_rule(s, t, c, p, AVTAB_ALLOWED, 0);
return add_rule(db, s, t, c, p, AVTAB_ALLOWED, 0);
}

int sepol_deny(const char *s, const char *t, const char *c, const char *p) {
int sepolicy::deny(const char *s, const char *t, const char *c, const char *p) {
vprint("deny %s %s %s %s\n", s, t, c, p);
return add_rule(s, t, c, p, AVTAB_ALLOWED, 1);
return add_rule(db, s, t, c, p, AVTAB_ALLOWED, 1);
}

int sepol_auditallow(const char *s, const char *t, const char *c, const char *p) {
int sepolicy::auditallow(const char *s, const char *t, const char *c, const char *p) {
vprint("auditallow %s %s %s %s\n", s, t, c, p);
return add_rule(s, t, c, p, AVTAB_AUDITALLOW, 0);
return add_rule(db, s, t, c, p, AVTAB_AUDITALLOW, 0);
}

int sepol_dontaudit(const char *s, const char *t, const char *c, const char *p) {
int sepolicy::dontaudit(const char *s, const char *t, const char *c, const char *p) {
vprint("dontaudit %s %s %s %s\n", s, t, c, p);
return add_rule(s, t, c, p, AVTAB_AUDITDENY, 1);
return add_rule(db, s, t, c, p, AVTAB_AUDITDENY, 1);
}

int sepol_allowxperm(const char *s, const char *t, const char *c, const char *range) {
int sepolicy::allowxperm(const char *s, const char *t, const char *c, const char *range) {
vprint("allowxperm %s %s %s %s\n", s, t, c, range);
return add_xperm_rule(s, t, c, range, AVTAB_XPERMS_ALLOWED, 0);
return add_xperm_rule(db, s, t, c, range, AVTAB_XPERMS_ALLOWED, 0);
}

int sepol_auditallowxperm(const char *s, const char *t, const char *c, const char *range) {
int sepolicy::auditallowxperm(const char *s, const char *t, const char *c, const char *range) {
vprint("auditallowxperm %s %s %s %s\n", s, t, c, range);
return add_xperm_rule(s, t, c, range, AVTAB_XPERMS_AUDITALLOW, 0);
return add_xperm_rule(db, s, t, c, range, AVTAB_XPERMS_AUDITALLOW, 0);
}

int sepol_dontauditxperm(const char *s, const char *t, const char *c, const char *range) {
int sepolicy::dontauditxperm(const char *s, const char *t, const char *c, const char *range) {
vprint("dontauditxperm %s %s %s %s\n", s, t, c, range);
return add_xperm_rule(s, t, c, range, AVTAB_XPERMS_DONTAUDIT, 0);
return add_xperm_rule(db, s, t, c, range, AVTAB_XPERMS_DONTAUDIT, 0);
}

int sepol_typetrans(const char *s, const char *t, const char *c, const char *d) {
vprint("type_transition %s %s %s %s\n", s, t, c, d);
return add_type_rule(s, t, c, d, AVTAB_TRANSITION);
}

int sepol_typechange(const char *s, const char *t, const char *c, const char *d) {
int sepolicy::type_change(const char *s, const char *t, const char *c, const char *d) {
vprint("type_change %s %s %s %s\n", s, t, c, d);
return add_type_rule(s, t, c, d, AVTAB_CHANGE);
return add_type_rule(db, s, t, c, d, AVTAB_CHANGE);
}

int sepol_typemember(const char *s, const char *t, const char *c, const char *d) {
int sepolicy::type_member(const char *s, const char *t, const char *c, const char *d) {
vprint("type_member %s %s %s %s\n", s, t, c, d);
return add_type_rule(s, t, c, d, AVTAB_MEMBER);
return add_type_rule(db, s, t, c, d, AVTAB_MEMBER);
}

int sepol_nametrans(const char *s, const char *t, const char *c, const char *d, const char *o) {
vprint("name_trans %s %s %s %s %s\n", s, t, c, d, o);
return add_filename_trans(s, t, c, d, o);
int sepolicy::type_transition(const char *src, const char *tgt, const char *cls, const char *def, const char *obj) {
if (obj) {
vprint("type_transition %s %s %s %s\n", src, tgt, cls, def);
return add_type_rule(db, src, tgt, cls, def, AVTAB_TRANSITION);
} else {
vprint("type_transition %s %s %s %s %s\n", src, tgt, cls, def, obj);
return add_filename_trans(db, src, tgt, cls, def, obj);
}
}

int sepol_permissive(const char *s) {
int sepolicy::permissive(const char *s) {
vprint("permissive %s\n", s);
return set_domain_state(s, 1);
return set_domain_state(db, s, 1);
}

int sepol_enforce(const char *s) {
int sepolicy::enforce(const char *s) {
vprint("enforce %s\n", s);
return set_domain_state(s, 0);
return set_domain_state(db, s, 0);
}

int sepol_create(const char *s) {
int sepolicy::create(const char *s) {
vprint("create %s\n", s);
return create_domain(s);
return create_domain(db, s);
}

int sepol_attradd(const char *s, const char *a) {
vprint("attradd %s %s\n", s, a);
return add_typeattribute(s, a);
int sepolicy::typeattribute(const char *type, const char *attr) {
vprint("typeattribute %s %s\n", type, attr);
return add_typeattribute(db, type, attr);
}

int sepol_genfscon(const char *name, const char *path, const char *context) {
vprint("genfscon %s %s %s\n", name, path, context);
return add_genfscon(name, path, context);
int sepolicy::genfscon(const char *fs_name, const char *path, const char *ctx) {
vprint("genfscon %s %s %s\n", fs_name, path, ctx);
return add_genfscon(db, fs_name, path, ctx);
}

int sepol_exists(const char *source) {
return hashtab_search(magisk_policydb->p_types.table, source) != nullptr;
int sepolicy::exists(const char *source) {
return hashtab_search(db->p_types.table, source) != nullptr;
}
24 changes: 14 additions & 10 deletions native/jni/magiskpolicy/magiskpolicy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ int magiskpolicy_main(int argc, char *argv[]) {
cmdline_logging();
const char *out_file = nullptr;
const char *rule_file = nullptr;
sepolicy *sepol = nullptr;
bool magisk = false;
bool live = false;

Expand All @@ -56,18 +57,21 @@ int magiskpolicy_main(int argc, char *argv[]) {
else if (option == "load"sv) {
if (argv[i + 1] == nullptr)
usage(argv[0]);
if (load_policydb(argv[i + 1])) {
sepol = sepolicy::from_file(argv[i + 1]);
if (!sepol) {
fprintf(stderr, "Cannot load policy from %s\n", argv[i + 1]);
return 1;
}
++i;
} else if (option == "load-split"sv) {
if (load_split_cil()) {
sepol = sepolicy::from_split();
if (!sepol) {
fprintf(stderr, "Cannot load split cil\n");
return 1;
}
} else if (option == "compile-split"sv) {
if (compile_split_cil()) {
sepol = sepolicy::compile_split();
if (!sepol) {
fprintf(stderr, "Cannot compile split cil\n");
return 1;
}
Expand All @@ -92,30 +96,30 @@ int magiskpolicy_main(int argc, char *argv[]) {
}

// Use current policy if nothing is loaded
if (magisk_policydb == nullptr && load_policydb(SELINUX_POLICY)) {
if (sepol == nullptr && !(sepol = sepolicy::from_file(SELINUX_POLICY))) {
fprintf(stderr, "Cannot load policy from " SELINUX_POLICY "\n");
return 1;
}

if (magisk)
sepol_magisk_rules();
sepol->magisk_rules();

if (rule_file)
load_rule_file(rule_file);
sepol->load_rule_file(rule_file);

for (; i < argc; ++i)
parse_statement(argv[i]);
sepol->parse_statement(argv[i]);

if (live && dump_policydb(SELINUX_LOAD)) {
if (live && sepol->to_file(SELINUX_LOAD)) {
fprintf(stderr, "Cannot apply policy\n");
return 1;
}

if (out_file && dump_policydb(out_file)) {
if (out_file && sepol->to_file(out_file)) {
fprintf(stderr, "Cannot dump policy to %s\n", out_file);
return 1;
}

destroy_policydb();
delete sepol;
return 0;
}
Loading

0 comments on commit d4baae4

Please sign in to comment.