checkpolicy: add support for xperms in conditional policies
Add support for extended permission rules in conditional policies. Signed-off-by: Christian Göttsche <cgzones@googlemail.com> Acked-by: James Carter <jwcart2@gmail.com>
This commit is contained in:
parent
438b16d177
commit
32c24c247e
|
@ -1882,6 +1882,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;
|
||||
|
@ -1892,8 +1894,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;
|
||||
}
|
||||
|
||||
|
@ -1995,7 +2001,7 @@ static int avrule_read_xperm_ranges(struct av_xperm_range_list **rangehead)
|
|||
id = queue_remove(id_queue);
|
||||
r->range.high = (uint16_t) strtoul(id,NULL,0);
|
||||
if (r->range.high < r->range.low) {
|
||||
yyerror2("Ioctl range %d-%d must be in ascending order.",
|
||||
yyerror2("extended permission range %#x-%#x must be in ascending order.",
|
||||
r->range.low, r->range.high);
|
||||
return -1;
|
||||
}
|
||||
|
@ -2477,9 +2483,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;
|
||||
|
@ -2501,7 +2507,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 */
|
||||
|
@ -2530,7 +2542,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2544,12 +2562,15 @@ done:
|
|||
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;
|
||||
|
@ -2584,7 +2605,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2598,9 +2625,64 @@ done:
|
|||
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 and nlmsg 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;
|
||||
|
@ -2622,11 +2704,11 @@ 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);
|
||||
yyerror2("only ioctl and nlmsg extended permissions are supported, found %s", id);
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
@ -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) ;
|
||||
|
@ -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 ';'
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
class CLASS1
|
||||
class CLASS2
|
||||
class CLASS3
|
||||
class CLASS4
|
||||
class dir
|
||||
class file
|
||||
class process
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
class CLASS1
|
||||
class CLASS2
|
||||
class CLASS3
|
||||
class CLASS4
|
||||
class dir
|
||||
class file
|
||||
class process
|
||||
|
@ -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;
|
||||
|
@ -17,6 +19,7 @@ policycap open_perms;
|
|||
attribute ATTR1;
|
||||
attribute ATTR2;
|
||||
bool BOOL1 true;
|
||||
bool BOOL2 false;
|
||||
type TYPE1;
|
||||
type TYPE2;
|
||||
type TYPE3;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
class CLASS1
|
||||
class CLASS2
|
||||
class CLASS3
|
||||
class CLASS4
|
||||
class dir
|
||||
class file
|
||||
class process
|
||||
|
@ -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;
|
||||
|
@ -17,6 +19,7 @@ policycap open_perms;
|
|||
attribute ATTR1;
|
||||
attribute ATTR2;
|
||||
bool BOOL1 true;
|
||||
bool BOOL2 false;
|
||||
type TYPE1;
|
||||
type TYPE2;
|
||||
type TYPE3;
|
||||
|
@ -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;
|
||||
|
@ -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 { 0x2 };
|
||||
}
|
||||
role ROLE1;
|
||||
role ROLE2;
|
||||
|
|
Loading…
Reference in New Issue