mirror of
https://github.com/SELinuxProject/selinux
synced 2025-05-07 10:08:07 +00:00
libsepol: Support nlmsg extended permissions
Add support for AVTAB_XPERMS_NLMSG as extended permissions for netlink sockets. The behaviour is similar to the existing AVTAB_XPERMS_IOCTLFUNCTION. Signed-off-by: Thiébaud Weksteen <tweek@google.com> Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
This commit is contained in:
parent
5421320d3a
commit
ba7945a250
checkpolicy
libsepol
@ -2342,8 +2342,8 @@ static int avrule_ioctl_completedriver(struct av_xperm_range_list *rangelist,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int avrule_ioctl_func(struct av_xperm_range_list *rangelist,
|
||||
av_extended_perms_t **extended_perms, unsigned int driver)
|
||||
static int avrule_xperm_func(struct av_xperm_range_list *rangelist,
|
||||
av_extended_perms_t **extended_perms, unsigned int driver, uint8_t specified)
|
||||
{
|
||||
struct av_xperm_range_list *r;
|
||||
av_extended_perms_t *xperms;
|
||||
@ -2379,7 +2379,7 @@ static int avrule_ioctl_func(struct av_xperm_range_list *rangelist,
|
||||
high = IOC_FUNC(high);
|
||||
avrule_xperm_setrangebits(low, high, xperms);
|
||||
xperms->driver = driver;
|
||||
xperms->specified = AVRULE_XPERMS_IOCTLFUNCTION;
|
||||
xperms->specified = specified;
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
@ -2495,7 +2495,61 @@ static int define_te_avtab_ioctl(const avrule_t *avrule_template)
|
||||
*/
|
||||
i = 0;
|
||||
while (xperms_for_each_bit(&i, partial_driver)) {
|
||||
if (avrule_ioctl_func(rangelist, &xperms, i))
|
||||
if (avrule_xperm_func(rangelist, &xperms, i, AVRULE_XPERMS_IOCTLFUNCTION))
|
||||
return -1;
|
||||
|
||||
if (xperms) {
|
||||
avrule = (avrule_t *) calloc(1, sizeof(avrule_t));
|
||||
if (!avrule) {
|
||||
yyerror("out of memory");
|
||||
return -1;
|
||||
}
|
||||
if (avrule_cpy(avrule, avrule_template))
|
||||
return -1;
|
||||
avrule->xperms = xperms;
|
||||
append_avrule(avrule);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (partial_driver)
|
||||
free(partial_driver);
|
||||
|
||||
while (rangelist != NULL) {
|
||||
r = rangelist;
|
||||
rangelist = rangelist->next;
|
||||
free(r);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int define_te_avtab_netlink(const avrule_t *avrule_template)
|
||||
{
|
||||
avrule_t *avrule;
|
||||
struct av_xperm_range_list *rangelist, *r;
|
||||
av_extended_perms_t *partial_driver, *xperms;
|
||||
unsigned int i;
|
||||
|
||||
/* organize ranges */
|
||||
if (avrule_xperm_ranges(&rangelist))
|
||||
return -1;
|
||||
|
||||
/* flag driver codes that are partially enabled */
|
||||
if (avrule_xperm_partialdriver(rangelist, NULL, &partial_driver))
|
||||
return -1;
|
||||
|
||||
if (!partial_driver || !avrule_xperms_used(partial_driver))
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* create rule for each partially used driver codes
|
||||
* "partially used" meaning that the code number e.g. socket 0x89
|
||||
* has some permission bits set and others not set.
|
||||
*/
|
||||
i = 0;
|
||||
while (xperms_for_each_bit(&i, partial_driver)) {
|
||||
if (avrule_xperm_func(rangelist, &xperms, i, AVRULE_XPERMS_NLMSG))
|
||||
return -1;
|
||||
|
||||
if (xperms) {
|
||||
@ -2546,6 +2600,8 @@ int define_te_avtab_extended_perms(int which)
|
||||
id = queue_remove(id_queue);
|
||||
if (strcmp(id,"ioctl") == 0) {
|
||||
rc = define_te_avtab_ioctl(avrule_template);
|
||||
} else if (strcmp(id,"nlmsg") == 0) {
|
||||
rc = define_te_avtab_netlink(avrule_template);
|
||||
} else {
|
||||
yyerror2("only ioctl extended permissions are supported, found %s", id);
|
||||
rc = -1;
|
||||
|
@ -353,6 +353,8 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
|
||||
xperms.specified = AVTAB_XPERMS_IOCTLFUNCTION;
|
||||
else if (avrule->xperms->specified == AVRULE_XPERMS_IOCTLDRIVER)
|
||||
xperms.specified = AVTAB_XPERMS_IOCTLDRIVER;
|
||||
else if (avrule->xperms->specified == AVRULE_XPERMS_NLMSG)
|
||||
xperms.specified = AVTAB_XPERMS_NLMSG;
|
||||
else {
|
||||
fprintf(fp, " ERROR: no valid xperms specified\n");
|
||||
return -1;
|
||||
|
@ -221,6 +221,7 @@ char *CIL_KEY_DONTAUDITX;
|
||||
char *CIL_KEY_NEVERALLOWX;
|
||||
char *CIL_KEY_PERMISSIONX;
|
||||
char *CIL_KEY_IOCTL;
|
||||
char *CIL_KEY_NLMSG;
|
||||
char *CIL_KEY_UNORDERED;
|
||||
char *CIL_KEY_SRC_INFO;
|
||||
char *CIL_KEY_SRC_CIL;
|
||||
@ -393,6 +394,7 @@ static void cil_init_keys(void)
|
||||
CIL_KEY_NEVERALLOWX = cil_strpool_add("neverallowx");
|
||||
CIL_KEY_PERMISSIONX = cil_strpool_add("permissionx");
|
||||
CIL_KEY_IOCTL = cil_strpool_add("ioctl");
|
||||
CIL_KEY_NLMSG = cil_strpool_add("nlmsg");
|
||||
CIL_KEY_UNORDERED = cil_strpool_add("unordered");
|
||||
CIL_KEY_SRC_INFO = cil_strpool_add("<src_info>");
|
||||
CIL_KEY_SRC_CIL = cil_strpool_add("cil");
|
||||
|
@ -66,6 +66,7 @@ struct cil_args_binary {
|
||||
int pass;
|
||||
hashtab_t role_trans_table;
|
||||
hashtab_t avrulex_ioctl_table;
|
||||
hashtab_t avrulex_nlmsg_table;
|
||||
void **type_value_to_cil;
|
||||
};
|
||||
|
||||
@ -1671,11 +1672,22 @@ static void __avrule_xperm_setrangebits(uint16_t low, uint16_t high, struct avta
|
||||
}
|
||||
}
|
||||
|
||||
static char* __cil_xperm_kind_to_str(uint32_t xperm_kind)
|
||||
{
|
||||
switch (xperm_kind) {
|
||||
case CIL_PERMX_KIND_IOCTL:
|
||||
return CIL_KEY_IOCTL;
|
||||
case CIL_PERMX_KIND_NLMSG:
|
||||
return CIL_KEY_NLMSG;
|
||||
default:
|
||||
return (char *) "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
#define IOC_DRIV(x) (x >> 8)
|
||||
#define IOC_FUNC(x) (x & 0xff)
|
||||
|
||||
static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil_list **xperms_list)
|
||||
static int __cil_permx_bitmap_to_sepol_xperms_list(uint32_t kind, ebitmap_t *xperms, struct cil_list **xperms_list)
|
||||
{
|
||||
ebitmap_node_t *node;
|
||||
unsigned int i;
|
||||
@ -1705,7 +1717,7 @@ static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil
|
||||
high = i;
|
||||
start_new_range = 1;
|
||||
|
||||
if (IOC_FUNC(low) == 0x00 && IOC_FUNC(high) == 0xff) {
|
||||
if (kind == CIL_PERMX_KIND_IOCTL && IOC_FUNC(low) == 0x00 && IOC_FUNC(high) == 0xff) {
|
||||
if (!complete) {
|
||||
complete = cil_calloc(1, sizeof(*complete));
|
||||
complete->driver = 0x0;
|
||||
@ -1722,7 +1734,14 @@ static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil
|
||||
if (!partial) {
|
||||
partial = cil_calloc(1, sizeof(*partial));
|
||||
partial->driver = IOC_DRIV(low);
|
||||
partial->specified = AVTAB_XPERMS_IOCTLFUNCTION;
|
||||
switch (kind) {
|
||||
case CIL_PERMX_KIND_IOCTL:
|
||||
partial->specified = AVTAB_XPERMS_IOCTLFUNCTION;
|
||||
break;
|
||||
case CIL_PERMX_KIND_NLMSG:
|
||||
partial->specified = AVTAB_XPERMS_NLMSG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__avrule_xperm_setrangebits(IOC_FUNC(low), IOC_FUNC(high), partial);
|
||||
@ -1740,7 +1759,7 @@ static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil
|
||||
return SEPOL_OK;
|
||||
}
|
||||
|
||||
static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args)
|
||||
static int __cil_avrulex_xperm_to_policydb(hashtab_key_t k, hashtab_datum_t datum, uint32_t xperm_kind, void *args)
|
||||
{
|
||||
int rc = SEPOL_OK;
|
||||
struct policydb *pdb;
|
||||
@ -1750,6 +1769,7 @@ static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datu
|
||||
struct cil_list_item *item;
|
||||
class_datum_t *sepol_obj;
|
||||
uint32_t data = 0;
|
||||
char *kind = NULL;
|
||||
|
||||
avtab_key = (avtab_key_t *)k;
|
||||
pdb = args;
|
||||
@ -1759,13 +1779,14 @@ static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datu
|
||||
// setting the data for an extended avtab isn't really necessary because
|
||||
// it is ignored by the kernel. However, neverallow checking requires that
|
||||
// the data value be set, so set it for that to work.
|
||||
rc = __perm_str_to_datum(CIL_KEY_IOCTL, sepol_obj, &data);
|
||||
kind = __cil_xperm_kind_to_str(xperm_kind);
|
||||
rc = __perm_str_to_datum(kind, sepol_obj, &data);
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
}
|
||||
avtab_datum.data = data;
|
||||
|
||||
rc = __cil_permx_bitmap_to_sepol_xperms_list(datum, &xperms_list);
|
||||
rc = __cil_permx_bitmap_to_sepol_xperms_list(xperm_kind, datum, &xperms_list);
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
}
|
||||
@ -1790,7 +1811,15 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __cil_avrulex_ioctl_to_hashtable(hashtab_t h, uint16_t kind, uint32_t src, uint32_t tgt, uint32_t obj, ebitmap_t *xperms)
|
||||
static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args) {
|
||||
return __cil_avrulex_xperm_to_policydb(k, datum, CIL_PERMX_KIND_IOCTL, args);
|
||||
}
|
||||
|
||||
static int __cil_avrulex_nlmsg_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args) {
|
||||
return __cil_avrulex_xperm_to_policydb(k, datum, CIL_PERMX_KIND_NLMSG, args);
|
||||
}
|
||||
|
||||
static int __cil_avrulex_xperm_to_hashtable(hashtab_t h, uint16_t kind, uint32_t src, uint32_t tgt, uint32_t obj, ebitmap_t *xperms)
|
||||
{
|
||||
uint16_t specified;
|
||||
avtab_key_t *avtab_key;
|
||||
@ -1870,7 +1899,11 @@ static int __cil_avrulex_to_hashtable_helper(policydb_t *pdb, uint16_t kind, str
|
||||
|
||||
switch (permx->kind) {
|
||||
case CIL_PERMX_KIND_IOCTL:
|
||||
rc = __cil_avrulex_ioctl_to_hashtable(args->avrulex_ioctl_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms);
|
||||
rc = __cil_avrulex_xperm_to_hashtable(args->avrulex_ioctl_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms);
|
||||
if (rc != SEPOL_OK) goto exit;
|
||||
break;
|
||||
case CIL_PERMX_KIND_NLMSG:
|
||||
rc = __cil_avrulex_xperm_to_hashtable(args->avrulex_nlmsg_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms);
|
||||
if (rc != SEPOL_OK) goto exit;
|
||||
break;
|
||||
default:
|
||||
@ -2037,7 +2070,7 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __cil_avrulex_ioctl_destroy(hashtab_key_t k, hashtab_datum_t datum, __attribute__((unused)) void *args)
|
||||
static int __cil_avrulex_xperm_destroy(hashtab_key_t k, hashtab_datum_t datum, __attribute__((unused)) void *args)
|
||||
{
|
||||
free(k);
|
||||
ebitmap_destroy(datum);
|
||||
@ -4630,6 +4663,9 @@ static int __cil_permx_to_sepol_class_perms(policydb_t *pdb, struct cil_permissi
|
||||
case CIL_PERMX_KIND_IOCTL:
|
||||
perm_str = CIL_KEY_IOCTL;
|
||||
break;
|
||||
case CIL_PERMX_KIND_NLMSG:
|
||||
perm_str = CIL_KEY_NLMSG;
|
||||
break;
|
||||
default:
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
@ -4769,17 +4805,10 @@ static void __cil_print_classperm(struct cil_list *cp_list)
|
||||
|
||||
static void __cil_print_permissionx(struct cil_permissionx *px)
|
||||
{
|
||||
const char *kind_str = "";
|
||||
const char *kind_str = NULL;
|
||||
char *expr_str;
|
||||
|
||||
switch (px->kind) {
|
||||
case CIL_PERMX_KIND_IOCTL:
|
||||
kind_str = CIL_KEY_IOCTL;
|
||||
break;
|
||||
default:
|
||||
kind_str = "unknown";
|
||||
break;
|
||||
}
|
||||
kind_str = __cil_xperm_kind_to_str(px->kind);
|
||||
|
||||
__cil_expr_to_string(px->expr_str, CIL_PERMISSIONX, &expr_str);
|
||||
|
||||
@ -4928,7 +4957,7 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = __cil_permx_bitmap_to_sepol_xperms_list(cil_rule->perms.x.permx->perms, &xperms);
|
||||
rc = __cil_permx_bitmap_to_sepol_xperms_list(cil_rule->perms.x.permx->kind, cil_rule->perms.x.permx->perms, &xperms);
|
||||
if (rc != SEPOL_OK) {
|
||||
goto exit;
|
||||
}
|
||||
@ -5137,6 +5166,7 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
|
||||
struct cil_list *neverallows = NULL;
|
||||
hashtab_t role_trans_table = NULL;
|
||||
hashtab_t avrulex_ioctl_table = NULL;
|
||||
hashtab_t avrulex_nlmsg_table = NULL;
|
||||
void **type_value_to_cil = NULL;
|
||||
struct cil_class **class_value_to_cil = NULL;
|
||||
struct cil_perm ***perm_value_to_cil = NULL;
|
||||
@ -5184,6 +5214,12 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
|
||||
goto exit;
|
||||
}
|
||||
|
||||
avrulex_nlmsg_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE);
|
||||
if (!avrulex_nlmsg_table) {
|
||||
cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
cil_list_init(&neverallows, CIL_LIST_ITEM);
|
||||
|
||||
extra_args.db = db;
|
||||
@ -5191,6 +5227,7 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
|
||||
extra_args.neverallows = neverallows;
|
||||
extra_args.role_trans_table = role_trans_table;
|
||||
extra_args.avrulex_ioctl_table = avrulex_ioctl_table;
|
||||
extra_args.avrulex_nlmsg_table = avrulex_nlmsg_table;
|
||||
extra_args.type_value_to_cil = type_value_to_cil;
|
||||
|
||||
for (i = 1; i <= 3; i++) {
|
||||
@ -5216,6 +5253,11 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
|
||||
cil_log(CIL_INFO, "Failure creating avrulex rules\n");
|
||||
goto exit;
|
||||
}
|
||||
rc = hashtab_map(avrulex_nlmsg_table, __cil_avrulex_nlmsg_to_policydb, pdb);
|
||||
if (rc != SEPOL_OK) {
|
||||
cil_log(CIL_INFO, "Failure creating avrulex rules\n");
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5287,8 +5329,10 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
|
||||
|
||||
exit:
|
||||
hashtab_destroy(role_trans_table);
|
||||
hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_destroy, NULL);
|
||||
hashtab_map(avrulex_ioctl_table, __cil_avrulex_xperm_destroy, NULL);
|
||||
hashtab_destroy(avrulex_ioctl_table);
|
||||
hashtab_map(avrulex_nlmsg_table, __cil_avrulex_xperm_destroy, NULL);
|
||||
hashtab_destroy(avrulex_nlmsg_table);
|
||||
free(type_value_to_cil);
|
||||
free(class_value_to_cil);
|
||||
if (perm_value_to_cil != NULL) {
|
||||
|
@ -2153,8 +2153,10 @@ static int cil_fill_permissionx(struct cil_tree_node *parse_current, struct cil_
|
||||
|
||||
if (parse_current->data == CIL_KEY_IOCTL) {
|
||||
permx->kind = CIL_PERMX_KIND_IOCTL;
|
||||
} else if (parse_current->data == CIL_KEY_NLMSG) {
|
||||
permx->kind = CIL_PERMX_KIND_NLMSG;
|
||||
} else {
|
||||
cil_log(CIL_ERR, "Unknown permissionx kind, %s. Must be \"ioctl\"\n", (char *)parse_current->data);
|
||||
cil_log(CIL_ERR, "Unknown permissionx kind, %s. Must be \"ioctl\" or \"nlmsg\"\n", (char *)parse_current->data);
|
||||
rc = SEPOL_ERR;
|
||||
goto exit;
|
||||
}
|
||||
|
@ -238,6 +238,7 @@ extern char *CIL_KEY_DONTAUDITX;
|
||||
extern char *CIL_KEY_NEVERALLOWX;
|
||||
extern char *CIL_KEY_PERMISSIONX;
|
||||
extern char *CIL_KEY_IOCTL;
|
||||
extern char *CIL_KEY_NLMSG;
|
||||
extern char *CIL_KEY_UNORDERED;
|
||||
extern char *CIL_KEY_SRC_INFO;
|
||||
extern char *CIL_KEY_SRC_CIL;
|
||||
@ -636,6 +637,7 @@ struct cil_avrule {
|
||||
};
|
||||
|
||||
#define CIL_PERMX_KIND_IOCTL 1
|
||||
#define CIL_PERMX_KIND_NLMSG 2
|
||||
struct cil_permissionx {
|
||||
struct cil_symtab_datum datum;
|
||||
uint32_t kind;
|
||||
|
@ -1112,6 +1112,8 @@ static void cil_xperms_to_policy(FILE *out, struct cil_permissionx *permx)
|
||||
|
||||
if (permx->kind == CIL_PERMX_KIND_IOCTL) {
|
||||
kind = "ioctl";
|
||||
} else if (permx->kind == CIL_PERMX_KIND_NLMSG) {
|
||||
kind = "nlmsg";
|
||||
} else {
|
||||
kind = "???";
|
||||
}
|
||||
|
@ -1513,6 +1513,9 @@ static int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tr
|
||||
case CIL_PERMX_KIND_IOCTL:
|
||||
kind_str = CIL_KEY_IOCTL;
|
||||
break;
|
||||
case CIL_PERMX_KIND_NLMSG:
|
||||
kind_str = CIL_KEY_NLMSG;
|
||||
break;
|
||||
default:
|
||||
cil_tree_log(node, CIL_ERR, "Invalid permissionx kind (%d)", permx->kind);
|
||||
rc = SEPOL_ERR;
|
||||
|
@ -303,7 +303,13 @@ static void write_permx(FILE *out, struct cil_permissionx *permx)
|
||||
fprintf(out, "%s", datum_to_str(DATUM(permx)));
|
||||
} else {
|
||||
fprintf(out, "(");
|
||||
fprintf(out, "%s ", permx->kind == CIL_PERMX_KIND_IOCTL ? "ioctl" : "<?KIND>");
|
||||
if (permx->kind == CIL_PERMX_KIND_IOCTL) {
|
||||
fprintf(out, "ioctl ");
|
||||
} else if (permx->kind == CIL_PERMX_KIND_NLMSG) {
|
||||
fprintf(out, "nlmsg ");
|
||||
} else {
|
||||
fprintf(out, "<?KIND> ");
|
||||
}
|
||||
fprintf(out, "%s ", datum_or_str(DATUM(permx->obj), permx->obj_str));
|
||||
write_expr(out, permx->expr_str);
|
||||
fprintf(out, ")");
|
||||
@ -823,7 +829,13 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
|
||||
case CIL_PERMISSIONX: {
|
||||
struct cil_permissionx *permx = node->data;
|
||||
fprintf(out, "(permissionx %s (", datum_to_str(DATUM(permx)));
|
||||
fprintf(out, "%s ", permx->kind == CIL_PERMX_KIND_IOCTL ? "ioctl" : "<?KIND>");
|
||||
if (permx->kind == CIL_PERMX_KIND_IOCTL) {
|
||||
fprintf(out, "ioctl ");
|
||||
} else if (permx->kind == CIL_PERMX_KIND_NLMSG) {
|
||||
fprintf(out, "nlmsg ");
|
||||
} else {
|
||||
fprintf(out, "<?KIND> ");
|
||||
}
|
||||
fprintf(out, "%s ", datum_or_str(DATUM(permx->obj), permx->obj_str));
|
||||
write_expr(out, permx->expr_str);
|
||||
fprintf(out, "))\n");
|
||||
|
@ -74,6 +74,7 @@ typedef struct avtab_extended_perms {
|
||||
|
||||
#define AVTAB_XPERMS_IOCTLFUNCTION 0x01
|
||||
#define AVTAB_XPERMS_IOCTLDRIVER 0x02
|
||||
#define AVTAB_XPERMS_NLMSG 0x03
|
||||
/* extension of the avtab_key specified */
|
||||
uint8_t specified;
|
||||
uint8_t driver;
|
||||
|
@ -259,6 +259,7 @@ typedef struct class_perm_node {
|
||||
typedef struct av_extended_perms {
|
||||
#define AVRULE_XPERMS_IOCTLFUNCTION 0x01
|
||||
#define AVRULE_XPERMS_IOCTLDRIVER 0x02
|
||||
#define AVRULE_XPERMS_NLMSG 0x03
|
||||
uint8_t specified;
|
||||
uint8_t driver;
|
||||
/* 256 bits of permissions */
|
||||
|
@ -1821,6 +1821,9 @@ static int allocate_xperms(sepol_handle_t * handle, avtab_datum_t * avdatump,
|
||||
case AVRULE_XPERMS_IOCTLDRIVER:
|
||||
xperms->specified = AVTAB_XPERMS_IOCTLDRIVER;
|
||||
break;
|
||||
case AVRULE_XPERMS_NLMSG:
|
||||
xperms->specified = AVTAB_XPERMS_NLMSG;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -1651,7 +1651,8 @@ static char *xperms_to_str(const avtab_extended_perms_t *xperms)
|
||||
size_t remaining, size = 128;
|
||||
|
||||
if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
|
||||
&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) {
|
||||
&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
|
||||
&& (xperms->specified != AVTAB_XPERMS_NLMSG)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1681,7 +1682,8 @@ retry:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) {
|
||||
if ((xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION)
|
||||
|| (xperms->specified == AVTAB_XPERMS_NLMSG)) {
|
||||
value = xperms->driver<<8 | bit;
|
||||
if (in_range) {
|
||||
low_value = xperms->driver<<8 | low_bit;
|
||||
@ -1690,7 +1692,7 @@ retry:
|
||||
} else {
|
||||
len = snprintf(p, remaining, " 0x%hx", value);
|
||||
}
|
||||
} else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) {
|
||||
} else if (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
|
||||
value = bit << 8;
|
||||
if (in_range) {
|
||||
low_value = low_bit << 8;
|
||||
@ -1728,7 +1730,7 @@ static char *avtab_node_to_str(struct policydb *pdb, avtab_key_t *key, avtab_dat
|
||||
uint32_t data = datum->data;
|
||||
type_datum_t *type;
|
||||
const char *flavor, *tgt;
|
||||
char *src, *class, *perms, *new;
|
||||
char *src, *class, *perms, *new, *xperm;
|
||||
char *rule = NULL;
|
||||
|
||||
switch (0xFFF & key->specified) {
|
||||
@ -1795,9 +1797,16 @@ static char *avtab_node_to_str(struct policydb *pdb, avtab_key_t *key, avtab_dat
|
||||
ERR(NULL, "Failed to generate extended permission string");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (datum->xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION || datum->xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
|
||||
xperm = (char *) "ioctl";
|
||||
} else if (datum->xperms->specified == AVTAB_XPERMS_NLMSG) {
|
||||
xperm = (char *) "nlmsg";
|
||||
} else {
|
||||
ERR(NULL, "Unknown extended permssion");
|
||||
goto exit;
|
||||
}
|
||||
rule = create_str("(%s %s %s (%s %s (%s)))",
|
||||
flavor, src, tgt, "ioctl", class, perms);
|
||||
flavor, src, tgt, xperm, class, perms);
|
||||
free(perms);
|
||||
} else {
|
||||
new = pdb->p_type_val_to_name[data - 1];
|
||||
|
@ -630,7 +630,8 @@ static int xperms_to_cil(const av_extended_perms_t *xperms)
|
||||
int first = 1;
|
||||
|
||||
if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
|
||||
&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
|
||||
&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
|
||||
&& (xperms->specified != AVTAB_XPERMS_NLMSG))
|
||||
return -1;
|
||||
|
||||
for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) {
|
||||
@ -652,7 +653,8 @@ static int xperms_to_cil(const av_extended_perms_t *xperms)
|
||||
else
|
||||
first = 0;
|
||||
|
||||
if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) {
|
||||
if ((xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION)
|
||||
|| (xperms->specified == AVTAB_XPERMS_NLMSG)) {
|
||||
value = xperms->driver<<8 | bit;
|
||||
if (in_range) {
|
||||
low_value = xperms->driver<<8 | low_bit;
|
||||
@ -661,7 +663,7 @@ static int xperms_to_cil(const av_extended_perms_t *xperms)
|
||||
} else {
|
||||
cil_printf("0x%hx", value);
|
||||
}
|
||||
} else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) {
|
||||
} else if (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
|
||||
value = bit << 8;
|
||||
if (in_range) {
|
||||
low_value = low_bit << 8;
|
||||
@ -680,6 +682,7 @@ static int avrulex_to_cil(int indent, struct policydb *pdb, uint32_t type, const
|
||||
{
|
||||
int rc = -1;
|
||||
const char *rule;
|
||||
const char *xperm;
|
||||
const struct class_perm_node *classperm;
|
||||
|
||||
switch (type) {
|
||||
@ -701,10 +704,19 @@ static int avrulex_to_cil(int indent, struct policydb *pdb, uint32_t type, const
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION || xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
|
||||
xperm = "ioctl";
|
||||
} else if (xperms->specified == AVTAB_XPERMS_NLMSG) {
|
||||
xperm = "nlmsg";
|
||||
} else {
|
||||
ERR(NULL, "Unkown avrule xperms->specified: %i", xperms->specified);
|
||||
rc = -1;
|
||||
goto exit;
|
||||
}
|
||||
for (classperm = classperms; classperm != NULL; classperm = classperm->next) {
|
||||
cil_indent(indent);
|
||||
cil_printf("(%s %s %s (%s %s (", rule, src, tgt,
|
||||
"ioctl", pdb->p_class_val_to_name[classperm->tclass - 1]);
|
||||
xperm, pdb->p_class_val_to_name[classperm->tclass - 1]);
|
||||
xperms_to_cil(xperms);
|
||||
cil_printf(")))\n");
|
||||
}
|
||||
|
@ -921,6 +921,7 @@ static int validate_xperms(const avtab_extended_perms_t *xperms)
|
||||
switch (xperms->specified) {
|
||||
case AVTAB_XPERMS_IOCTLDRIVER:
|
||||
case AVTAB_XPERMS_IOCTLFUNCTION:
|
||||
case AVTAB_XPERMS_NLMSG:
|
||||
break;
|
||||
default:
|
||||
goto bad;
|
||||
@ -1067,6 +1068,7 @@ static int validate_avrules(sepol_handle_t *handle, const avrule_t *avrule, int
|
||||
switch (avrule->xperms->specified) {
|
||||
case AVRULE_XPERMS_IOCTLFUNCTION:
|
||||
case AVRULE_XPERMS_IOCTLDRIVER:
|
||||
case AVRULE_XPERMS_NLMSG:
|
||||
break;
|
||||
default:
|
||||
goto bad;
|
||||
|
@ -146,7 +146,8 @@ char *sepol_extended_perms_to_string(const avtab_extended_perms_t *xperms)
|
||||
size_t remaining, size = 128;
|
||||
|
||||
if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
|
||||
&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
|
||||
&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
|
||||
&& (xperms->specified != AVTAB_XPERMS_NLMSG))
|
||||
return NULL;
|
||||
|
||||
retry:
|
||||
@ -158,7 +159,12 @@ retry:
|
||||
buffer = p;
|
||||
remaining = size;
|
||||
|
||||
len = snprintf(p, remaining, "ioctl { ");
|
||||
if ((xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION)
|
||||
|| (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
|
||||
len = snprintf(p, remaining, "ioctl { ");
|
||||
} else {
|
||||
len = snprintf(p, remaining, "nlmsg { ");
|
||||
}
|
||||
if (len < 0 || (size_t)len >= remaining)
|
||||
goto err;
|
||||
p += len;
|
||||
@ -179,7 +185,7 @@ retry:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) {
|
||||
if (xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION || xperms->specified == AVTAB_XPERMS_NLMSG) {
|
||||
value = xperms->driver<<8 | bit;
|
||||
if (in_range) {
|
||||
low_value = xperms->driver<<8 | low_bit;
|
||||
@ -187,7 +193,7 @@ retry:
|
||||
} else {
|
||||
len = snprintf(p, remaining, "0x%hx ", value);
|
||||
}
|
||||
} else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) {
|
||||
} else if (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
|
||||
value = bit << 8;
|
||||
if (in_range) {
|
||||
low_value = low_bit << 8;
|
||||
|
Loading…
Reference in New Issue
Block a user