mirror of
https://github.com/tiann/KernelSU.git
synced 2025-02-20 11:43:32 +08:00
kernel: support xperms for sepolicy
This commit is contained in:
parent
7b3f3d4965
commit
342910771b
@ -6,60 +6,69 @@
|
||||
|
||||
void apply_kernelsu_rules() {
|
||||
|
||||
struct selinux_policy *policy;
|
||||
struct policydb *db;
|
||||
struct selinux_policy *policy;
|
||||
struct policydb *db;
|
||||
|
||||
if (!getenforce()) {
|
||||
pr_info("SELinux permissive or disabled, don't apply rules.");
|
||||
return;
|
||||
}
|
||||
if (!getenforce()) {
|
||||
pr_info("SELinux permissive or disabled, don't apply rules.");
|
||||
return;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
policy = rcu_dereference(selinux_state.policy);
|
||||
db = &policy->policydb;
|
||||
rcu_read_lock();
|
||||
policy = rcu_dereference(selinux_state.policy);
|
||||
db = &policy->policydb;
|
||||
|
||||
permissive(db, KERNEL_SU_DOMAIN);
|
||||
typeattribute(db, KERNEL_SU_DOMAIN, "mlstrustedsubject");
|
||||
typeattribute(db, KERNEL_SU_DOMAIN, "netdomain");
|
||||
typeattribute(db, KERNEL_SU_DOMAIN, "bluetoothdomain");
|
||||
permissive(db, KERNEL_SU_DOMAIN);
|
||||
typeattribute(db, KERNEL_SU_DOMAIN, "mlstrustedsubject");
|
||||
typeattribute(db, KERNEL_SU_DOMAIN, "netdomain");
|
||||
typeattribute(db, KERNEL_SU_DOMAIN, "bluetoothdomain");
|
||||
|
||||
// allow all!
|
||||
allow(db, KERNEL_SU_DOMAIN, ALL, ALL, ALL);
|
||||
// allow all!
|
||||
allow(db, KERNEL_SU_DOMAIN, ALL, ALL, ALL);
|
||||
|
||||
// allow us do any ioctl
|
||||
if (db->policyvers >= POLICYDB_VERSION_XPERMS_IOCTL) {
|
||||
allowxperm(db, KERNEL_SU_DOMAIN, ALL, "blk_file", ALL);
|
||||
allowxperm(db, KERNEL_SU_DOMAIN, ALL, "fifo_file", ALL);
|
||||
allowxperm(db, KERNEL_SU_DOMAIN, ALL, "chr_file", ALL);
|
||||
}
|
||||
|
||||
// we need to save allowlist in /data/adb
|
||||
allow(db, "kernel", "adb_data_file", "dir", ALL);
|
||||
allow(db, "kernel", "adb_data_file", "file", ALL);
|
||||
// we may need to do mount on shell
|
||||
allow(db, "kernel", "shell_data_file", "file", ALL);
|
||||
|
||||
// we need to save allowlist in /data/adb
|
||||
allow(db, "kernel", "adb_data_file", "dir", ALL);
|
||||
allow(db, "kernel", "adb_data_file", "file", ALL);
|
||||
// copied from Magisk rules
|
||||
// suRights
|
||||
allow(db, "servicemanager", KERNEL_SU_DOMAIN, "dir", "search");
|
||||
allow(db, "servicemanager", KERNEL_SU_DOMAIN, "dir", "read");
|
||||
allow(db, "servicemanager", KERNEL_SU_DOMAIN, "file", "open");
|
||||
allow(db, "servicemanager", KERNEL_SU_DOMAIN, "file", "read");
|
||||
allow(db, "servicemanager", KERNEL_SU_DOMAIN, "process", "getattr");
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "process", "sigchld");
|
||||
|
||||
// copied from Magisk rules
|
||||
// suRights
|
||||
allow(db, "servicemanager", KERNEL_SU_DOMAIN, "dir", "search");
|
||||
allow(db, "servicemanager", KERNEL_SU_DOMAIN, "dir", "read");
|
||||
allow(db, "servicemanager", KERNEL_SU_DOMAIN, "file", "open");
|
||||
allow(db, "servicemanager", KERNEL_SU_DOMAIN, "file", "read");
|
||||
allow(db, "servicemanager", KERNEL_SU_DOMAIN, "process", "getattr");
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "process", "sigchld");
|
||||
// allowLog
|
||||
allow(db, "logd", KERNEL_SU_DOMAIN, "dir", "search");
|
||||
allow(db, "logd", KERNEL_SU_DOMAIN, "file", "read");
|
||||
allow(db, "logd", KERNEL_SU_DOMAIN, "file", "open");
|
||||
allow(db, "logd", KERNEL_SU_DOMAIN, "file", "getattr");
|
||||
|
||||
// allowLog
|
||||
allow(db, "logd", KERNEL_SU_DOMAIN, "dir", "search");
|
||||
allow(db, "logd", KERNEL_SU_DOMAIN, "file", "read");
|
||||
allow(db, "logd", KERNEL_SU_DOMAIN, "file", "open");
|
||||
allow(db, "logd", KERNEL_SU_DOMAIN, "file", "getattr");
|
||||
// dumpsys
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "fd", "use");
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "fifo_file", "write");
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "fifo_file", "read");
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "fifo_file", "open");
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "fifo_file", "getattr");
|
||||
|
||||
// dumpsys
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "fd", "use");
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "fifo_file", "write");
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "fifo_file", "read");
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "fifo_file", "open");
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "fifo_file", "getattr");
|
||||
// bootctl
|
||||
allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "dir", "search");
|
||||
allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "file", "read");
|
||||
allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "file", "open");
|
||||
allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "process", "getattr");
|
||||
|
||||
// bootctl
|
||||
allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "dir", "search");
|
||||
allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "file", "read");
|
||||
allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "file", "open");
|
||||
allow(db, "hwservicemanager", KERNEL_SU_DOMAIN, "process", "getattr");
|
||||
// Allow all binder transactions
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "binder", ALL);
|
||||
|
||||
// Allow all binder transactions
|
||||
allow(db, ALL, KERNEL_SU_DOMAIN, "binder", ALL);
|
||||
|
||||
rcu_read_unlock();
|
||||
rcu_read_unlock();
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
#include "sepolicy.h"
|
||||
#include "../klog.h"
|
||||
|
||||
// Invert is adding rules for auditdeny; in other cases, invert is removing rules
|
||||
#define strip_av(effect, invert) ((effect == AVTAB_AUDITDENY) == !invert)
|
||||
@ -52,7 +53,11 @@ struct avtab_node* get_avtab_node(struct policydb* db, struct avtab_key *key, st
|
||||
* AUDITDENY, aka DONTAUDIT, are &= assigned, versus |= for
|
||||
* others. Initialize the data accordingly.
|
||||
*/
|
||||
avdatum.u.data = key->specified == AVTAB_AUDITDENY ? ~0U : 0U;
|
||||
if (key->specified & AVTAB_XPERMS) {
|
||||
avdatum.u.xperms = xperms;
|
||||
} else {
|
||||
avdatum.u.data = key->specified == AVTAB_AUDITDENY ? ~0U : 0U;
|
||||
}
|
||||
/* this is used to get the node - insertion is actually unique */
|
||||
node = avtab_insert_nonunique(&db->te_avtab, key, &avdatum);
|
||||
|
||||
@ -174,11 +179,136 @@ void add_rule_raw(struct policydb* db, struct type_datum *src, struct type_datum
|
||||
}
|
||||
}
|
||||
|
||||
void add_xperm_rule_raw(struct type_datum *src, struct type_datum *tgt,
|
||||
struct class_datum *cls, uint16_t low, uint16_t high, int effect, bool invert) {
|
||||
#define ioctl_driver(x) (x>>8 & 0xFF)
|
||||
#define ioctl_func(x) (x & 0xFF)
|
||||
|
||||
#define xperm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f)))
|
||||
#define xperm_set(x, p) (p[x >> 5] |= (1 << (x & 0x1f)))
|
||||
#define xperm_clear(x, p) (p[x >> 5] &= ~(1 << (x & 0x1f)))
|
||||
|
||||
void add_xperm_rule_raw(struct policydb* db, struct type_datum *src, struct type_datum *tgt,
|
||||
struct class_datum *cls, uint16_t low, uint16_t high, int effect, bool invert) {
|
||||
|
||||
if (src == NULL) {
|
||||
struct hashtab_node* node;
|
||||
hashtab_for_each(db->p_types.table, node) {
|
||||
struct type_datum* type = (struct type_datum*)(node->datum);
|
||||
if (type->attribute) {
|
||||
add_xperm_rule_raw(db, type, tgt, cls, low, high, effect, invert);
|
||||
}
|
||||
};
|
||||
} else if (tgt == NULL) {
|
||||
struct hashtab_node* node;
|
||||
hashtab_for_each(db->p_types.table, node) {
|
||||
struct type_datum* type = (struct type_datum*)(node->datum);
|
||||
if (type->attribute) {
|
||||
add_xperm_rule_raw(db, src, type, cls, low, high, effect, invert);
|
||||
}
|
||||
};
|
||||
} else if (cls == NULL) {
|
||||
struct hashtab_node* node;
|
||||
hashtab_for_each(db->p_classes.table, node) {
|
||||
add_xperm_rule_raw(db, src, tgt, (struct class_datum*)(node->datum), low, high, effect, invert);
|
||||
};
|
||||
} else {
|
||||
struct avtab_key key;
|
||||
key.source_type = src->value;
|
||||
key.target_type = tgt->value;
|
||||
key.target_class = cls->value;
|
||||
key.specified = effect;
|
||||
|
||||
struct avtab_datum *datum;
|
||||
struct avtab_node *node;
|
||||
struct avtab_extended_perms xperms;
|
||||
|
||||
memset(&xperms, 0, sizeof(xperms));
|
||||
if (ioctl_driver(low) != ioctl_driver(high)) {
|
||||
xperms.specified = AVTAB_XPERMS_IOCTLDRIVER;
|
||||
xperms.driver = 0;
|
||||
} else {
|
||||
xperms.specified = AVTAB_XPERMS_IOCTLFUNCTION;
|
||||
xperms.driver = ioctl_driver(low);
|
||||
}
|
||||
|
||||
if (xperms.specified == AVTAB_XPERMS_IOCTLDRIVER) {
|
||||
for (int i = ioctl_driver(low); i <= ioctl_driver(high); ++i) {
|
||||
if (invert)
|
||||
xperm_clear(i, xperms.perms.p);
|
||||
else
|
||||
xperm_set(i, xperms.perms.p);
|
||||
}
|
||||
} else {
|
||||
for (int i = ioctl_func(low); i <= ioctl_func(high); ++i) {
|
||||
if (invert)
|
||||
xperm_clear(i, xperms.perms.p);
|
||||
else
|
||||
xperm_set(i, xperms.perms.p);
|
||||
}
|
||||
}
|
||||
|
||||
node = get_avtab_node(db, &key, &xperms);
|
||||
if (!node) {
|
||||
pr_warn("add_xperm_rule_raw cannot found node!\n");
|
||||
return;
|
||||
}
|
||||
datum = &node->datum;
|
||||
|
||||
if (datum->u.xperms == NULL) {
|
||||
datum->u.xperms = (struct avtab_extended_perms*)(kmalloc(sizeof(xperms), GFP_KERNEL));
|
||||
if (!datum->u.xperms) {
|
||||
pr_err("alloc xperms failed\n");
|
||||
return;
|
||||
}
|
||||
memcpy(datum->u.xperms, &xperms, sizeof(xperms));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
bool add_xperm_rule(const char *s, const char *t, const char *c, const char *range, int effect, bool invert) {
|
||||
return false;
|
||||
|
||||
bool add_xperm_rule(struct policydb* db, const char *s, const char *t, const char *c, const char *range, int effect, bool invert) {
|
||||
struct type_datum *src = NULL, *tgt = NULL;
|
||||
struct class_datum *cls = NULL;
|
||||
|
||||
if (s) {
|
||||
src = symtab_search(&db->p_types, s);
|
||||
if (src == NULL) {
|
||||
pr_info("source type %s does not exist\n", s);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (t) {
|
||||
tgt = symtab_search(&db->p_types, t);
|
||||
if (tgt == NULL) {
|
||||
pr_info("target type %s does not exist\n", t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (c) {
|
||||
cls = symtab_search(&db->p_classes, c);
|
||||
if (cls == NULL) {
|
||||
pr_info("class %s does not exist\n", c);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
u16 low, high;
|
||||
|
||||
if (range) {
|
||||
if (strchr(range, '-')){
|
||||
sscanf(range, "%hx-%hx", &low, &high);
|
||||
} else {
|
||||
sscanf(range, "%hx", &low);
|
||||
high = low;
|
||||
}
|
||||
} else {
|
||||
low = 0;
|
||||
high = 0xFFFF;
|
||||
}
|
||||
|
||||
add_xperm_rule_raw(db, src, tgt, cls, low, high, effect, invert);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool add_type_rule(struct policydb* db, const char *s, const char *t, const char *c, const char *d, int effect) {
|
||||
@ -338,15 +468,15 @@ bool dontaudit(struct policydb* db, const char* src, const char* tgt, const char
|
||||
|
||||
// Extended permissions access vector rules
|
||||
bool allowxperm(struct policydb* db, const char* src, const char* tgt, const char* cls, const char* range) {
|
||||
return add_xperm_rule(src, tgt, cls, range, AVTAB_XPERMS_ALLOWED, false);
|
||||
return add_xperm_rule(db, src, tgt, cls, range, AVTAB_XPERMS_ALLOWED, false);
|
||||
}
|
||||
|
||||
bool auditallowxperm(struct policydb* db, const char* src, const char* tgt, const char* cls, const char* range) {
|
||||
return add_xperm_rule(src, tgt, cls, range, AVTAB_XPERMS_AUDITALLOW, false);
|
||||
return add_xperm_rule(db, src, tgt, cls, range, AVTAB_XPERMS_AUDITALLOW, false);
|
||||
}
|
||||
|
||||
bool dontauditxperm(struct policydb* db, const char* src, const char* tgt, const char* cls, const char* range) {
|
||||
return add_xperm_rule(src, tgt, cls, range, AVTAB_XPERMS_DONTAUDIT, false);
|
||||
return add_xperm_rule(db, src, tgt, cls, range, AVTAB_XPERMS_DONTAUDIT, false);
|
||||
}
|
||||
|
||||
// Type rules
|
||||
|
@ -42,9 +42,9 @@ struct avtab_node* get_avtab_node(struct policydb* db, struct avtab_key *key, st
|
||||
bool add_rule(struct policydb* db, const char *s, const char *t, const char *c, const char *p, int effect, bool invert);
|
||||
void add_rule_raw(struct policydb* db, struct type_datum *src, struct type_datum *tgt, struct class_datum *cls, struct perm_datum *perm, int effect, bool invert);
|
||||
|
||||
void add_xperm_rule_raw(struct type_datum *src, struct type_datum *tgt,
|
||||
void add_xperm_rule_raw(struct policydb* db, struct type_datum *src, struct type_datum *tgt,
|
||||
struct class_datum *cls, uint16_t low, uint16_t high, int effect, bool invert);
|
||||
bool add_xperm_rule(const char *s, const char *t, const char *c, const char *range, int effect, bool invert);
|
||||
bool add_xperm_rule(struct policydb* db, const char *s, const char *t, const char *c, const char *range, int effect, bool invert);
|
||||
|
||||
bool add_type_rule(struct policydb* db, const char *s, const char *t, const char *c, const char *d, int effect);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user