Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for extended permission rules in conditional policies #432

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Prev Previous commit
Next Next commit
checkpolicy: add support for xperms in conditional policies
Add support for extended permission rules in conditional policies.

Signed-off-by: Christian Göttsche <[email protected]>
  • Loading branch information
cgzones committed Apr 5, 2024
commit 22fcfa76cd24f6dca0a53756514f482b6e1a4f6c
83 changes: 76 additions & 7 deletions checkpolicy/policy_define.c
Original file line number Diff line number Diff line change
Expand Up @@ -1859,6 +1859,8 @@ int define_bool_tunable(int is_tunable)

avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
{
avrule_t *last;

if (pass == 1) {
/* return something so we get through pass 1 */
return (avrule_t *) 1;
Expand All @@ -1869,8 +1871,12 @@ avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
return avlist;
}

/* prepend the new avlist to the pre-existing one */
sl->next = avlist;
/* prepend the new avlist to the pre-existing one
* An extended permission statement might consist of multiple av
* rules. */
for (last = sl; last->next; last = last->next)
;
last->next = avlist;
return sl;
}

Expand Down Expand Up @@ -2454,9 +2460,9 @@ static int avrule_cpy(avrule_t *dest, const avrule_t *src)
return 0;
}

static int define_te_avtab_ioctl(const avrule_t *avrule_template)
static int define_te_avtab_ioctl(const avrule_t *avrule_template, avrule_t **ret_avrules)
{
avrule_t *avrule;
avrule_t *avrule, *ret = NULL, **last = &ret;
struct av_ioctl_range_list *rangelist, *r;
av_extended_perms_t *complete_driver, *partial_driver, *xperms;
unsigned int i;
Expand All @@ -2478,7 +2484,12 @@ static int define_te_avtab_ioctl(const avrule_t *avrule_template)
if (avrule_cpy(avrule, avrule_template))
return -1;
avrule->xperms = complete_driver;
append_avrule(avrule);
if (ret_avrules) {
*last = avrule;
last = &(avrule->next);
} else {
append_avrule(avrule);
}
}

/* flag ioctl driver codes that are partially enabled */
Expand Down Expand Up @@ -2507,7 +2518,12 @@ static int define_te_avtab_ioctl(const avrule_t *avrule_template)
if (avrule_cpy(avrule, avrule_template))
return -1;
avrule->xperms = xperms;
append_avrule(avrule);
if (ret_avrules) {
*last = avrule;
last = &(avrule->next);
} else {
append_avrule(avrule);
}
}
}

Expand All @@ -2521,9 +2537,62 @@ static int define_te_avtab_ioctl(const avrule_t *avrule_template)
free(r);
}

if (ret_avrules)
*ret_avrules = ret;

return 0;
}

avrule_t *define_cond_te_avtab_extended_perms(int which)
{
char *id;
unsigned int i;
avrule_t *avrule_template, *rules = NULL;
int rc = 0;

if (policydbp->policy_type == POLICY_KERN && policydbp->policyvers < POLICYDB_VERSION_COND_XPERMS) {
yyerror2("extended permissions in conditional policies are only supported since policy version %d, found policy version %d",
POLICYDB_VERSION_COND_XPERMS, policydbp->policyvers);
return COND_ERR;
}
if (policydbp->policy_type != POLICY_KERN && policydbp->policyvers < MOD_POLICYDB_VERSION_COND_XPERMS) {
yyerror2("extended permissions in conditional policies are only supported since module policy version %d, found module policy version %d",
MOD_POLICYDB_VERSION_COND_XPERMS, policydbp->policyvers);
return COND_ERR;
}

if (pass == 1) {
for (i = 0; i < 4; i++) {
while ((id = queue_remove(id_queue)))
free(id);
}
return (avrule_t *) 1; /* any non-NULL value */
}

/* populate avrule template with source/target/tclass */
if (define_te_avtab_xperms_helper(which, &avrule_template))
return COND_ERR;

id = queue_remove(id_queue);
if (strcmp(id,"ioctl") == 0) {
rc = define_te_avtab_ioctl(avrule_template, &rules);
} else {
yyerror2("only ioctl extended permissions are supported, found %s", id);
rc = -1;
}

free(id);
avrule_destroy(avrule_template);
free(avrule_template);

if (rc) {
avrule_destroy(rules);
return NULL;
}

return rules;
}

int define_te_avtab_extended_perms(int which)
{
char *id;
Expand All @@ -2545,7 +2614,7 @@ int define_te_avtab_extended_perms(int which)

id = queue_remove(id_queue);
if (strcmp(id,"ioctl") == 0) {
rc = define_te_avtab_ioctl(avrule_template);
rc = define_te_avtab_ioctl(avrule_template, NULL);
} else {
yyerror2("only ioctl extended permissions are supported, found %s", id);
rc = -1;
Expand Down
1 change: 1 addition & 0 deletions checkpolicy/policy_define.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
avrule_t *define_cond_compute_type(int which);
avrule_t *define_cond_pol_list(avrule_t *avlist, avrule_t *sl);
avrule_t *define_cond_te_avtab(int which);
avrule_t *define_cond_te_avtab_extended_perms(int which);
avrule_t *define_cond_filename_trans(void);
cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void* arg2);
int define_attrib(void);
Expand Down
20 changes: 19 additions & 1 deletion checkpolicy/policy_parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ typedef int (* require_func_t)(int pass);

%type <ptr> cond_expr cond_expr_prim cond_pol_list cond_else
%type <ptr> cond_allow_def cond_auditallow_def cond_auditdeny_def cond_dontaudit_def
%type <ptr> cond_xperm_allow_def cond_xperm_auditallow_def cond_xperm_dontaudit_def
%type <ptr> cond_transition_def cond_te_avtab_def cond_rule_def
%type <valptr> cexpr cexpr_prim op role_mls_op
%type <val> ipv4_addr_def number
Expand Down Expand Up @@ -430,6 +431,12 @@ cond_te_avtab_def : cond_allow_def
{ $$ = $1; }
| cond_dontaudit_def
{ $$ = $1; }
| cond_xperm_allow_def
{ $$ = $1; }
| cond_xperm_auditallow_def
{ $$ = $1; }
| cond_xperm_dontaudit_def
{ $$ = $1; }
;
cond_allow_def : ALLOW names names ':' names names ';'
{ $$ = define_cond_te_avtab(AVRULE_ALLOWED) ;
Expand All @@ -447,7 +454,18 @@ cond_dontaudit_def : DONTAUDIT names names ':' names names ';'
{ $$ = define_cond_te_avtab(AVRULE_DONTAUDIT);
if ($$ == COND_ERR) YYABORT; }
;
;
cond_xperm_allow_def : ALLOWXPERM names names ':' names identifier xperms ';'
{ $$ = define_cond_te_avtab_extended_perms(AVRULE_XPERMS_ALLOWED) ;
if ($$ == COND_ERR) YYABORT; }
;
cond_xperm_auditallow_def : AUDITALLOWXPERM names names ':' names identifier xperms ';'
{ $$ = define_cond_te_avtab_extended_perms(AVRULE_XPERMS_AUDITALLOW) ;
if ($$ == COND_ERR) YYABORT; }
;
cond_xperm_dontaudit_def : DONTAUDITXPERM names names ':' names identifier xperms ';'
{ $$ = define_cond_te_avtab_extended_perms(AVRULE_XPERMS_DONTAUDIT) ;
if ($$ == COND_ERR) YYABORT; }
;
transition_def : TYPE_TRANSITION names names ':' names identifier filename ';'
{if (define_filename_trans()) YYABORT; }
| TYPE_TRANSITION names names ':' names identifier ';'
Expand Down
2 changes: 1 addition & 1 deletion checkpolicy/tests/policy_allonce.conf
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ role_transition ROLE1 TYPE1 : CLASS1 ROLE2;
allow ROLE1 ROLE2;
roleattribute ROLE3 ROLE_ATTR1;
role ROLE1 types { TYPE1 };
if ! BOOL1 { allow TYPE1 self: CLASS1 *; }
if ! BOOL1 { allow TYPE1 self: CLASS1 *; dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x6789 - 0x9876 }; }
if TUNABLE1 xor TUNABLE2 { allow TYPE1 self: CLASS2 *; } else { allow TYPE1 self: CLASS3 *; }
optional { require { class CLASS2 { CPERM1 }; } allow TYPE1 self: CLASS2 *; }
user USER1 roles ROLE1;
Expand Down
3 changes: 3 additions & 0 deletions checkpolicy/tests/policy_allonce.expected.conf
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ type_transition TYPE2 TYPE4:CLASS1 TYPE1 "FILENAME";
if (BOOL1) {
} else {
allow TYPE1 self:CLASS1 { PERM1 ioctl };
dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x6789-0x67ff };
dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x6800-0x97ff };
dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x9800-0x9876 };
}
role ROLE1;
role ROLE2;
Expand Down
3 changes: 3 additions & 0 deletions checkpolicy/tests/policy_allonce.expected_opt.conf
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ type_transition TYPE2 TYPE4:CLASS1 TYPE1 "FILENAME";
if (BOOL1) {
} else {
allow TYPE1 self:CLASS1 { ioctl };
dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x6789-0x67ff };
dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x6800-0x97ff };
dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x9800-0x9876 };
}
role ROLE1;
role ROLE2;
Expand Down