All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] libsepol/cil: Handle operations in a class mapping when verifying
@ 2021-09-16 20:29 James Carter
  2021-09-22 10:27 ` Petr Lautrbach
  0 siblings, 1 reply; 2+ messages in thread
From: James Carter @ 2021-09-16 20:29 UTC (permalink / raw)
  To: selinux; +Cc: James Carter

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 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


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] libsepol/cil: Handle operations in a class mapping when verifying
  2021-09-16 20:29 [PATCH] libsepol/cil: Handle operations in a class mapping when verifying James Carter
@ 2021-09-22 10:27 ` Petr Lautrbach
  0 siblings, 0 replies; 2+ messages in thread
From: Petr Lautrbach @ 2021-09-22 10:27 UTC (permalink / raw)
  To: James Carter, selinux

James Carter <jwcart2@gmail.com> writes:

> 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>

Acked-by: Petr Lautrbach <plautrba@redhat.com>

Thanks!


> ---
>  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


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-09-22 10:27 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-16 20:29 [PATCH] libsepol/cil: Handle operations in a class mapping when verifying James Carter
2021-09-22 10:27 ` Petr Lautrbach

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.