From 00728e12d4a7c67a2cf578e0c2905287c579e75b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Fri, 12 May 2023 11:23:10 +0200 Subject: [PATCH] checkpolicy: only set declared permission bits for wildcards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When setting permission bits from a wildcard or complement only set the bits for permissions actually declared for the associated class. This helps optimizing the policy later, since only rules are dropped with a complete empty permission bitset. Example policy: class CLASS1 sid kernel class CLASS1 { PERM1 } type TYPE1; bool BOOL1 true; allow TYPE1 self : CLASS1 { PERM1 }; role ROLE1; role ROLE1 types { TYPE1 }; if ! BOOL1 { allow TYPE1 self: CLASS1 *; } user USER1 roles ROLE1; sid kernel USER1:ROLE1:TYPE1 Also emit a warning if a rule will have an empty permission bitset due to an exhausting complement. Signed-off-by: Christian Göttsche Acked-by: James Carter --- checkpolicy/policy_define.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c index 95cd5c85..cef8f3c4 100644 --- a/checkpolicy/policy_define.c +++ b/checkpolicy/policy_define.c @@ -2511,6 +2511,8 @@ int define_te_avtab_extended_perms(int which) return rc; } +#define PERMISSION_MASK(nprim) ((nprim) == PERM_SYMTAB_SIZE ? (~UINT32_C(0)) : ((UINT32_C(1) << (nprim)) - 1)) + static int define_te_avtab_helper(int which, avrule_t ** rule) { char *id; @@ -2616,8 +2618,8 @@ static int define_te_avtab_helper(int which, avrule_t ** rule) cladatum = policydbp->class_val_to_struct[i]; if (strcmp(id, "*") == 0) { - /* set all permissions in the class */ - cur_perms->data = ~0U; + /* set all declared permissions in the class */ + cur_perms->data = PERMISSION_MASK(cladatum->permissions.nprim); goto next; } @@ -2625,7 +2627,16 @@ static int define_te_avtab_helper(int which, avrule_t ** rule) /* complement the set */ if (which == AVRULE_DONTAUDIT) yywarn("dontaudit rule with a ~?"); - cur_perms->data = ~cur_perms->data; + cur_perms->data = ~cur_perms->data & PERMISSION_MASK(cladatum->permissions.nprim); + if (cur_perms->data == 0) { + class_perm_node_t *tmp = cur_perms; + yywarn("omitting avrule with no permission set"); + if (perms == cur_perms) + perms = cur_perms->next; + cur_perms = cur_perms->next; + free(tmp); + continue; + } goto next; } @@ -3549,8 +3560,6 @@ static constraint_expr_t *constraint_expr_clone(const constraint_expr_t * expr) return NULL; } -#define PERMISSION_MASK(nprim) ((nprim) == PERM_SYMTAB_SIZE ? (~UINT32_C(0)) : ((UINT32_C(1) << (nprim)) - 1)) - int define_constraint(constraint_expr_t * expr) { struct constraint_node *node;