Skip to content

Commit

Permalink
checkpolicy: add support for xperms in conditional policies
Browse files Browse the repository at this point in the history
Add support for extended permission rules in conditional policies.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
  • Loading branch information
cgzones committed Oct 23, 2024
1 parent ef54806 commit 419a95d
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 13 deletions.
104 changes: 93 additions & 11 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_xperm_range_list *rangelist, *r;
av_extended_perms_t *complete_driver, *partial_driver, *xperms;
unsigned int i;
Expand All @@ -2478,7 +2484,13 @@ 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 +2519,13 @@ 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,12 +2539,15 @@ static int define_te_avtab_ioctl(const avrule_t *avrule_template)
free(r);
}

if (ret_avrules)
*ret_avrules = ret;

return 0;
}

static int define_te_avtab_netlink(const avrule_t *avrule_template)
static int define_te_avtab_netlink(const avrule_t *avrule_template, avrule_t **ret_avrules)
{
avrule_t *avrule;
avrule_t *avrule, *ret = NULL, **last = &ret;
struct av_xperm_range_list *rangelist, *r;
av_extended_perms_t *partial_driver, *xperms;
unsigned int i;
Expand Down Expand Up @@ -2561,7 +2582,13 @@ static int define_te_avtab_netlink(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 @@ -2575,9 +2602,64 @@ static int define_te_avtab_netlink(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 if (strcmp(id, "nlmsg") == 0) {
rc = define_te_avtab_netlink(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 @@ -2599,9 +2681,9 @@ 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 if (strcmp(id,"nlmsg") == 0) {
rc = define_te_avtab_netlink(avrule_template);
rc = define_te_avtab_netlink(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 @@ -432,6 +433,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 @@ -449,7 +456,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
7 changes: 6 additions & 1 deletion checkpolicy/tests/policy_allonce.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
class CLASS1
class CLASS2
class CLASS3
class CLASS4
class dir
class file
class process
Expand All @@ -10,6 +11,7 @@ common COMMON1 { CPERM1 }
class CLASS1 { PERM1 ioctl }
class CLASS2 inherits COMMON1
class CLASS3 inherits COMMON1 { PERM1 }
class CLASS4 { nlmsg }
default_user { CLASS1 } source;
default_role { CLASS2 } target;
default_type { CLASS3 } source;
Expand All @@ -26,6 +28,7 @@ typealias TYPE1 alias TYPEALIAS1;
typeattribute TYPE1 ATTR1;
typebounds TYPE4 TYPE3;
bool BOOL1 true;
bool BOOL2 false;
tunable TUNABLE1 false;
tunable TUNABLE2 true;
type_transition TYPE1 TYPE2 : CLASS1 TYPE3;
Expand All @@ -37,6 +40,7 @@ auditallow { TYPE1 TYPE2 } TYPE3 : CLASS1 { PERM1 };
dontaudit TYPE1 { TYPE2 TYPE3 } : CLASS3 { PERM1 CPERM1 };
neverallow TYPE1 TYPE2 : { CLASS2 CLASS3 } { CPERM1 };
allowxperm TYPE1 TYPE2 : CLASS1 ioctl { 0x456-0x5678 };
allowxperm TYPE2 TYPE1 : CLASS4 nlmsg { 0x1 0x12 };
auditallowxperm TYPE1 TYPE2 : CLASS1 ioctl 0x2;
dontauditxperm TYPE1 TYPE2 : CLASS1 ioctl 0x3;
neverallowxperm TYPE1 TYPE2 : CLASS1 ioctl 0x4;
Expand All @@ -50,7 +54,8 @@ 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 BOOL2 { allowxperm TYPE2 TYPE1:CLASS4 nlmsg { 0x1 0x2 }; }
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
10 changes: 10 additions & 0 deletions checkpolicy/tests/policy_allonce.expected.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
class CLASS1
class CLASS2
class CLASS3
class CLASS4
class dir
class file
class process
Expand All @@ -10,13 +11,15 @@ common COMMON1 { CPERM1 }
class CLASS1 { PERM1 ioctl }
class CLASS2 inherits COMMON1
class CLASS3 inherits COMMON1 { PERM1 }
class CLASS4 { nlmsg }
default_user { CLASS1 } source;
default_role { CLASS2 } target;
default_type { CLASS3 } source;
policycap open_perms;
attribute ATTR1;
attribute ATTR2;
bool BOOL1 true;
bool BOOL2 false;
type TYPE1;
type TYPE2;
type TYPE3;
Expand All @@ -37,6 +40,7 @@ dontaudit TYPE1 TYPE3:CLASS3 { CPERM1 PERM1 };
allowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x456-0x4ff };
allowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x500-0x55ff };
allowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x5600-0x5678 };
allowxperm TYPE2 TYPE1:CLASS4 nlmsg { 0x1 0x12 };
auditallowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x2 };
dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x3 };
type_transition TYPE1 TYPE2:CLASS1 TYPE3;
Expand All @@ -49,6 +53,12 @@ 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 };
}
if (BOOL2) {
allowxperm TYPE2 TYPE1:CLASS4 nlmsg { 0x1-0x2 };
}
role ROLE1;
role ROLE2;
Expand Down
10 changes: 10 additions & 0 deletions checkpolicy/tests/policy_allonce.expected_opt.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
class CLASS1
class CLASS2
class CLASS3
class CLASS4
class dir
class file
class process
Expand All @@ -10,13 +11,15 @@ common COMMON1 { CPERM1 }
class CLASS1 { PERM1 ioctl }
class CLASS2 inherits COMMON1
class CLASS3 inherits COMMON1 { PERM1 }
class CLASS4 { nlmsg }
default_user { CLASS1 } source;
default_role { CLASS2 } target;
default_type { CLASS3 } source;
policycap open_perms;
attribute ATTR1;
attribute ATTR2;
bool BOOL1 true;
bool BOOL2 false;
type TYPE1;
type TYPE2;
type TYPE3;
Expand All @@ -37,6 +40,7 @@ dontaudit TYPE1 TYPE3:CLASS3 { CPERM1 PERM1 };
allowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x456-0x4ff };
allowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x500-0x55ff };
allowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x5600-0x5678 };
allowxperm TYPE2 TYPE1:CLASS4 nlmsg { 0x1 0x12 };
auditallowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x2 };
dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x3 };
type_transition TYPE1 TYPE2:CLASS1 TYPE3;
Expand All @@ -49,6 +53,12 @@ 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 };
}
if (BOOL2) {
allowxperm TYPE2 TYPE1:CLASS4 nlmsg { 0x1-0x2 };
}
role ROLE1;
role ROLE2;
Expand Down

0 comments on commit 419a95d

Please sign in to comment.