96 lines
3.4 KiB
Diff
96 lines
3.4 KiB
Diff
From 18f8747b28f1620903c7a3aa8a6616c199c173a6 Mon Sep 17 00:00:00 2001
|
|
From: James Carter <jwcart2@gmail.com>
|
|
Date: Thu, 16 Sep 2021 16:29:00 -0400
|
|
Subject: [PATCH] libsepol/cil: Handle operations in a class mapping when
|
|
verifying
|
|
|
|
When checking for circular class permission declarations and a class
|
|
mapping is encountered, the class permissions for each map permission
|
|
must be checked. An assumption was made that there were no operators
|
|
in the class permissions. An operator in the class permissions would
|
|
cause a segfault.
|
|
|
|
Example causing segault:
|
|
(classmap cm1 (mp1))
|
|
(classmapping cm1 mp1 (CLASS (PERM)))
|
|
(classpermission cp1)
|
|
(classpermissionset cp1 (cm1 (all)))
|
|
|
|
For map class permissions, check each item in the permission list to
|
|
see if it is an operator. If it is not, then verify the class
|
|
permissions associated with the map permission. If it is an operator
|
|
and the operator is "all", then create a list of all permissions for
|
|
that map class and verify the class permissions associated with each
|
|
map permission. If it is a different operator, then it can be skipped.
|
|
|
|
This bug was found by the secilc-fuzzer.
|
|
|
|
Signed-off-by: James Carter <jwcart2@gmail.com>
|
|
---
|
|
libsepol/cil/src/cil_verify.c | 40 +++++++++++++++++++++++++++++++++++-----
|
|
1 file changed, 35 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
|
|
index 5502c4d..dc29ea6 100644
|
|
--- a/libsepol/cil/src/cil_verify.c
|
|
+++ b/libsepol/cil/src/cil_verify.c
|
|
@@ -1689,6 +1689,15 @@ exit:
|
|
return rc;
|
|
}
|
|
|
|
+static int __add_perm_to_list(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
|
|
+{
|
|
+ struct cil_list *perm_list = (struct cil_list *)args;
|
|
+
|
|
+ cil_list_append(perm_list, CIL_DATUM, d);
|
|
+
|
|
+ return SEPOL_OK;
|
|
+}
|
|
+
|
|
static int __cil_verify_classperms(struct cil_list *classperms,
|
|
struct cil_symtab_datum *orig,
|
|
struct cil_symtab_datum *parent,
|
|
@@ -1730,13 +1739,34 @@ static int __cil_verify_classperms(struct cil_list *classperms,
|
|
if (FLAVOR(cp->class) != CIL_CLASS) { /* MAP */
|
|
struct cil_list_item *i = NULL;
|
|
cil_list_for_each(i, cp->perms) {
|
|
- struct cil_perm *cmp = i->data;
|
|
- rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit);
|
|
- if (rc != SEPOL_OK) {
|
|
- goto exit;
|
|
+ if (i->flavor != CIL_OP) {
|
|
+ struct cil_perm *cmp = i->data;
|
|
+ rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit);
|
|
+ if (rc != SEPOL_OK) {
|
|
+ goto exit;
|
|
+ }
|
|
+ } else {
|
|
+ enum cil_flavor op = (enum cil_flavor)i->data;
|
|
+ if (op == CIL_ALL) {
|
|
+ struct cil_class *mc = cp->class;
|
|
+ struct cil_list *perm_list;
|
|
+ struct cil_list_item *j = NULL;
|
|
+
|
|
+ cil_list_init(&perm_list, CIL_MAP_PERM);
|
|
+ cil_symtab_map(&mc->perms, __add_perm_to_list, perm_list);
|
|
+ cil_list_for_each(j, perm_list) {
|
|
+ struct cil_perm *cmp = j->data;
|
|
+ rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit);
|
|
+ if (rc != SEPOL_OK) {
|
|
+ cil_list_destroy(&perm_list, CIL_FALSE);
|
|
+ goto exit;
|
|
+ }
|
|
+ }
|
|
+ cil_list_destroy(&perm_list, CIL_FALSE);
|
|
+ }
|
|
}
|
|
}
|
|
- }
|
|
+ }
|
|
} else { /* SET */
|
|
struct cil_classperms_set *cp_set = curr->data;
|
|
struct cil_classpermission *cp = cp_set->set;
|
|
--
|
|
1.8.3.1
|
|
|