Re: [PATCH] libsepol: cap max depth for __evaluate_classperms_list()
James Carter <[email protected]> Mon, 27 Jul 2026 12:52:55 -0400
| Newsgroups | org.kernel.vger.selinux |
|---|---|
| Message-ID | <CAP+JOzQ5nqo=ZuO0KogwH-+ez1UZpF4oOmPWYRmSPcOZpxwEGg@mail.gmail.com> |
On Mon, Jul 27, 2026 at 10:00 AM Stephen Smalley <[email protected]> wrote: > > __evaluate_classperms_list() is called recursively without > a depth limit, which can overflow the stack. Cap the depth > to avoid such overflows. > > Reported-by: oss-fuzz (issue 479899924) > Signed-off-by: Stephen Smalley <[email protected]> Acked-by: James Carter <[email protected]> > --- > libsepol/cil/src/cil_post.c | 21 +++++++++++++-------- > 1 file changed, 13 insertions(+), 8 deletions(-) > > diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c > index 8845faed..183b0d49 100644 > --- a/libsepol/cil/src/cil_post.c > +++ b/libsepol/cil/src/cil_post.c > @@ -2291,11 +2291,14 @@ exit: > } > > static int __evaluate_classperms_list(struct cil_list *classperms, > - struct cil_db *db) > + struct cil_db *db, int depth) > { > int rc = SEPOL_ERR; > struct cil_list_item *curr; > > + if (depth > 32) > + return SEPOL_ERR; > + > cil_list_for_each(curr, classperms) { > if (curr->flavor == CIL_CLASSPERMS) { > struct cil_classperms *cp = curr->data; > @@ -2313,7 +2316,7 @@ static int __evaluate_classperms_list(struct cil_list *classperms, > cil_list_for_each(i, cp->perms) { > struct cil_perm *cmp = i->data; > rc = __evaluate_classperms_list( > - cmp->classperms, db); > + cmp->classperms, db, depth + 1); > if (rc != SEPOL_OK) { > goto exit; > } > @@ -2322,7 +2325,8 @@ static int __evaluate_classperms_list(struct cil_list *classperms, > } else { /* SET */ > struct cil_classperms_set *cp_set = curr->data; > struct cil_classpermission *cp = cp_set->set; > - rc = __evaluate_classperms_list(cp->classperms, db); > + rc = __evaluate_classperms_list(cp->classperms, db, > + depth + 1); > if (rc != SEPOL_OK) { > goto exit; > } > @@ -2347,7 +2351,7 @@ __evaluate_map_perm_classperms(__attribute__((unused)) hashtab_key_t k, > struct class_map_args *map_args = args; > struct cil_perm *cmp = (struct cil_perm *)d; > > - int rc = __evaluate_classperms_list(cmp->classperms, map_args->db); > + int rc = __evaluate_classperms_list(cmp->classperms, map_args->db, 0); > > if (rc != SEPOL_OK) { > map_args->rc = rc; > @@ -2393,7 +2397,7 @@ static int __cil_post_db_classperms_helper(struct cil_tree_node *node, > } > case CIL_CLASSPERMISSION: { > struct cil_classpermission *cp = node->data; > - rc = __evaluate_classperms_list(cp->classperms, db); > + rc = __evaluate_classperms_list(cp->classperms, db, 0); > if (rc != SEPOL_OK) { > goto exit; > } > @@ -2401,7 +2405,8 @@ static int __cil_post_db_classperms_helper(struct cil_tree_node *node, > } > case CIL_AVRULE: { > struct cil_avrule *avrule = node->data; > - rc = __evaluate_classperms_list(avrule->perms.classperms, db); > + rc = __evaluate_classperms_list(avrule->perms.classperms, db, > + 0); > if (rc != SEPOL_OK) { > goto exit; > } > @@ -2409,7 +2414,7 @@ static int __cil_post_db_classperms_helper(struct cil_tree_node *node, > } > case CIL_DENY_RULE: { > struct cil_deny_rule *deny = node->data; > - rc = __evaluate_classperms_list(deny->classperms, db); > + rc = __evaluate_classperms_list(deny->classperms, db, 0); > if (rc != SEPOL_OK) { > goto exit; > } > @@ -2418,7 +2423,7 @@ static int __cil_post_db_classperms_helper(struct cil_tree_node *node, > case CIL_CONSTRAIN: > case CIL_MLSCONSTRAIN: { > struct cil_constrain *constrain = node->data; > - rc = __evaluate_classperms_list(constrain->classperms, db); > + rc = __evaluate_classperms_list(constrain->classperms, db, 0); > if (rc != SEPOL_OK) { > goto exit; > } > -- > 2.55.0 >