kernel: selinux support add new type and add builtin unconstrained file type

This commit is contained in:
weishu
2023-01-24 19:48:41 +07:00
parent fbd7d0f90d
commit e5044b4b6f
2 changed files with 155 additions and 44 deletions

View File

@@ -11,6 +11,7 @@
#endif
#define KERNEL_SU_DOMAIN "su"
#define KERNEL_SU_FILE "ksu_file"
#define ALL NULL
void apply_kernelsu_rules()
@@ -36,6 +37,11 @@ void apply_kernelsu_rules()
ksu_typeattribute(db, KERNEL_SU_DOMAIN, "netdomain");
ksu_typeattribute(db, KERNEL_SU_DOMAIN, "bluetoothdomain");
// Create unconstrained file type
ksu_type(db, KERNEL_SU_FILE, "file_type");
ksu_typeattribute(db, KERNEL_SU_FILE, "mlstrustedobject");
ksu_allow(db, ALL, KERNEL_SU_FILE, ALL, ALL);
// allow all!
ksu_allow(db, KERNEL_SU_DOMAIN, ALL, ALL, ALL);

View File

@@ -1,34 +1,57 @@
#include <linux/gfp.h>
#include <linux/version.h>
#include <linux/printk.h>
#include <linux/slab.h>
#include "sepolicy.h"
#include "../klog.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
// TODO: backport to lower kernel
#define KSU_SUPPORT_ADD_TYPE
#endif
//////////////////////////////////////////////////////
// Declaration
//////////////////////////////////////////////////////
static struct avtab_node* get_avtab_node(struct policydb* db, struct avtab_key *key, struct avtab_extended_perms *xperms);
static struct avtab_node *get_avtab_node(struct policydb *db,
struct avtab_key *key,
struct avtab_extended_perms *xperms);
static bool add_rule(struct policydb* db, const char *s, const char *t, const char *c, const char *p, int effect, bool invert);
static bool add_rule(struct policydb *db, const char *s, const char *t,
const char *c, const char *p, int effect, bool invert);
static 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);
static 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);
static 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);
static bool add_xperm_rule(struct policydb* db, const char *s, const char *t, const char *c, const char *range, int effect, bool invert);
static 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);
static bool add_xperm_rule(struct policydb *db, const char *s, const char *t,
const char *c, const char *range, int effect,
bool invert);
static bool add_type_rule(struct policydb* db, const char *s, const char *t, const char *c, const char *d, int effect);
static bool add_type_rule(struct policydb *db, const char *s, const char *t,
const char *c, const char *d, int effect);
static bool add_filename_trans(const char *s, const char *t, const char *c, const char *d, const char *o);
static bool add_filename_trans(const char *s, const char *t, const char *c,
const char *d, const char *o);
static bool add_genfscon(const char *fs_name, const char *path, const char *context);
static bool add_genfscon(const char *fs_name, const char *path,
const char *context);
static bool add_type(struct policydb* db, const char *type_name, bool attr);
static bool add_type(struct policydb *db, const char *type_name, bool attr);
static bool set_type_state(struct policydb* db, const char *type_name, bool permissive);
static bool set_type_state(struct policydb *db, const char *type_name,
bool permissive);
static void add_typeattribute_raw(struct policydb* db, struct type_datum *type, struct type_datum *attr);
static void add_typeattribute_raw(struct policydb *db, struct type_datum *type,
struct type_datum *attr);
static bool add_typeattribute(struct policydb* db, const char *type, const char *attr);
static bool add_typeattribute(struct policydb *db, const char *type,
const char *attr);
//////////////////////////////////////////////////////
// Implementation
@@ -42,12 +65,12 @@ static bool add_typeattribute(struct policydb* db, const char *type, const char
for (i = 0; i < n_slot; ++i) \
for (cur = node_ptr[i]; cur; cur = cur->next)
// htable is a struct instead of pointer above 5.8.0: https://elixir.bootlin.com/linux/v5.8-rc1/source/security/selinux/ss/symtab.h
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
#define hashtab_for_each(htab, cur) hash_for_each (htab.htable, htab.size, cur)
#else
#define hashtab_for_each(htab, cur) hash_for_each (htab->htable, htab->size, cur)
#define hashtab_for_each(htab, cur) \
hash_for_each (htab->htable, htab->size, cur)
#endif
// symtab_search is introduced on 5.9.0: https://elixir.bootlin.com/linux/v5.9-rc1/source/security/selinux/ss/symtab.h
@@ -59,8 +82,9 @@ static bool add_typeattribute(struct policydb* db, const char *type, const char
hash_for_each (avtab.htable, avtab.nslot, cur) \
;
static struct avtab_node *get_avtab_node(struct policydb *db, struct avtab_key *key,
struct avtab_extended_perms *xperms)
static struct avtab_node *get_avtab_node(struct policydb *db,
struct avtab_key *key,
struct avtab_extended_perms *xperms)
{
struct avtab_node *node;
@@ -113,8 +137,8 @@ static struct avtab_node *get_avtab_node(struct policydb *db, struct avtab_key *
return node;
}
static bool add_rule(struct policydb *db, const char *s, const char *t, const char *c,
const char *p, int effect, bool invert)
static bool add_rule(struct policydb *db, const char *s, const char *t,
const char *c, const char *p, int effect, bool invert)
{
struct type_datum *src = NULL, *tgt = NULL;
struct class_datum *cls = NULL;
@@ -165,8 +189,8 @@ static bool add_rule(struct policydb *db, const char *s, const char *t, const ch
}
static 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)
struct type_datum *tgt, struct class_datum *cls,
struct perm_datum *perm, int effect, bool invert)
{
if (src == NULL) {
struct hashtab_node *node;
@@ -247,8 +271,9 @@ static void add_rule_raw(struct policydb *db, struct type_datum *src,
#define xperm_clear(x, p) (p[x >> 5] &= ~(1 << (x & 0x1f)))
static 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)
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;
@@ -309,8 +334,7 @@ static void add_xperm_rule_raw(struct policydb *db, struct type_datum *src,
xperm_set(i, xperms.perms.p);
}
} else {
for (i = ioctl_func(low); i <= ioctl_func(high);
++i) {
for (i = ioctl_func(low); i <= ioctl_func(high); ++i) {
if (invert)
xperm_clear(i, xperms.perms.p);
else
@@ -339,7 +363,8 @@ static void add_xperm_rule_raw(struct policydb *db, struct type_datum *src,
}
static bool add_xperm_rule(struct policydb *db, const char *s, const char *t,
const char *c, const char *range, int effect, bool invert)
const char *c, const char *range, int effect,
bool invert)
{
struct type_datum *src = NULL, *tgt = NULL;
struct class_datum *cls = NULL;
@@ -387,7 +412,7 @@ static bool add_xperm_rule(struct policydb *db, const char *s, const char *t,
}
static bool add_type_rule(struct policydb *db, const char *s, const char *t,
const char *c, const char *d, int effect)
const char *c, const char *d, int effect)
{
struct type_datum *src, *tgt, *def;
struct class_datum *cls;
@@ -426,22 +451,100 @@ static bool add_type_rule(struct policydb *db, const char *s, const char *t,
}
static bool add_filename_trans(const char *s, const char *t, const char *c,
const char *d, const char *o)
const char *d, const char *o)
{
return false;
}
static bool add_genfscon(const char *fs_name, const char *path, const char *context)
static bool add_genfscon(const char *fs_name, const char *path,
const char *context)
{
return false;
}
static bool add_type(struct policydb *db, const char *type_name, bool attr)
{
#ifdef KSU_SUPPORT_ADD_TYPE
struct type_datum *type = symtab_search(&db->p_types, type_name);
if (type) {
pr_warn("Type %s already exists\n", type_name);
return true;
}
u32 value = ++db->p_types.nprim;
type = (struct type_datum *)kmalloc(sizeof(struct type_datum),
GFP_ATOMIC);
if (!type) {
pr_err("add_type: alloc type_datum failed.\n");
return false;
}
type->primary = 1;
type->value = value;
char *key = kstrdup(type_name, GFP_ATOMIC);
if (!key) {
pr_err("add_type: alloc key failed.\n");
return false;
}
if (symtab_insert(&db->p_types, key, type)) {
pr_err("add_type: insert symtab failed.\n");
return false;
}
size_t new_size = sizeof(struct ebitmap) * db->p_types.nprim;
struct ebitmap *new_type_attr_map_array =
(krealloc(db->type_attr_map_array, new_size, GFP_ATOMIC));
struct type_datum **new_type_val_to_struct =
krealloc(db->type_val_to_struct,
sizeof(*db->type_val_to_struct) * db->p_types.nprim,
GFP_ATOMIC);
if (!new_type_attr_map_array) {
pr_err("add_type: alloc type_attr_map_array failed\n");
return false;
}
if (!new_type_val_to_struct) {
pr_err("add_type: alloc type_val_to_struct failed\n");
return false;
}
char **new_val_to_name_types =
krealloc(db->sym_val_to_name[SYM_TYPES],
sizeof(char *) * db->symtab[SYM_TYPES].nprim,
GFP_KERNEL);
if (!new_val_to_name_types) {
pr_err("add_type: alloc val_to_name failed\n");
return false;
}
db->type_attr_map_array = new_type_attr_map_array;
ebitmap_init(&db->type_attr_map_array[value - 1]);
ebitmap_set_bit(&db->type_attr_map_array[value - 1], value - 1, 1);
db->type_val_to_struct = new_type_val_to_struct;
db->type_val_to_struct[value - 1] = type;
db->sym_val_to_name[SYM_TYPES] = new_val_to_name_types;
db->sym_val_to_name[SYM_TYPES][value - 1] = key;
int i;
for (i = 0; i < db->p_roles.nprim; ++i) {
ebitmap_set_bit(&db->role_val_to_struct[i]->types, value - 1,
0);
}
return true;
#else
return false;
#endif
}
static bool set_type_state(struct policydb *db, const char *type_name, bool permissive)
static bool set_type_state(struct policydb *db, const char *type_name,
bool permissive)
{
struct type_datum *type;
if (type_name == NULL) {
@@ -470,12 +573,13 @@ static bool set_type_state(struct policydb *db, const char *type_name, bool perm
}
static void add_typeattribute_raw(struct policydb *db, struct type_datum *type,
struct type_datum *attr)
struct type_datum *attr)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
struct ebitmap *sattr = &db->type_attr_map_array[type->value - 1];
#else
struct ebitmap *sattr = flex_array_get(db->type_attr_map_array, type->value -1);
struct ebitmap *sattr =
flex_array_get(db->type_attr_map_array, type->value - 1);
#endif
ebitmap_set_bit(sattr, attr->value - 1, 1);
@@ -498,7 +602,8 @@ static void add_typeattribute_raw(struct policydb *db, struct type_datum *type,
};
}
static bool add_typeattribute(struct policydb *db, const char *type, const char *attr)
static bool add_typeattribute(struct policydb *db, const char *type,
const char *attr)
{
struct type_datum *type_d = symtab_search(&db->p_types, type);
if (type_d == NULL) {
@@ -557,45 +662,45 @@ bool ksu_exists(struct policydb *db, const char *type)
// Access vector rules
bool ksu_allow(struct policydb *db, const char *src, const char *tgt,
const char *cls, const char *perm)
const char *cls, const char *perm)
{
return add_rule(db, src, tgt, cls, perm, AVTAB_ALLOWED, false);
}
bool ksu_deny(struct policydb *db, const char *src, const char *tgt,
const char *cls, const char *perm)
const char *cls, const char *perm)
{
return add_rule(db, src, tgt, cls, perm, AVTAB_ALLOWED, true);
}
bool ksu_auditallow(struct policydb *db, const char *src, const char *tgt,
const char *cls, const char *perm)
const char *cls, const char *perm)
{
return add_rule(db, src, tgt, cls, perm, AVTAB_AUDITALLOW, false);
}
bool ksu_dontaudit(struct policydb *db, const char *src, const char *tgt,
const char *cls, const char *perm)
const char *cls, const char *perm)
{
return add_rule(db, src, tgt, cls, perm, AVTAB_AUDITDENY, true);
}
// Extended permissions access vector rules
bool ksu_allowxperm(struct policydb *db, const char *src, const char *tgt,
const char *cls, const char *range)
const char *cls, const char *range)
{
return add_xperm_rule(db, src, tgt, cls, range, AVTAB_XPERMS_ALLOWED,
false);
}
bool ksu_auditallowxperm(struct policydb *db, const char *src, const char *tgt,
const char *cls, const char *range)
const char *cls, const char *range)
{
return add_xperm_rule(db, src, tgt, cls, range, AVTAB_XPERMS_AUDITALLOW,
false);
}
bool ksu_dontauditxperm(struct policydb *db, const char *src, const char *tgt,
const char *cls, const char *range)
const char *cls, const char *range)
{
return add_xperm_rule(db, src, tgt, cls, range, AVTAB_XPERMS_DONTAUDIT,
false);
@@ -603,25 +708,25 @@ bool ksu_dontauditxperm(struct policydb *db, const char *src, const char *tgt,
// Type rules
bool ksu_type_transition(struct policydb *db, const char *src, const char *tgt,
const char *cls, const char *def, const char *obj)
const char *cls, const char *def, const char *obj)
{
return false;
}
bool ksu_type_change(struct policydb *db, const char *src, const char *tgt,
const char *cls, const char *def)
const char *cls, const char *def)
{
return false;
}
bool ksu_type_member(struct policydb *db, const char *src, const char *tgt,
const char *cls, const char *def)
const char *cls, const char *def)
{
return false;
}
// File system labeling
bool ksu_genfscon(struct policydb *db, const char *fs_name, const char *path,
const char *ctx)
const char *ctx)
{
return false;
}