checkpolicy: only set declared permission bits for wildcards

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 <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
This commit is contained in:
Christian Göttsche 2023-05-12 11:23:10 +02:00 committed by James Carter
parent c646f3904d
commit 00728e12d4
1 changed files with 14 additions and 5 deletions

View File

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