[PATCH] libsepol/cil: Handle operations in a class mapping when verifying

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
---
 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 5502c4d5..dc29ea66 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;
-- 
2.31.1




[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux