5ea3e823bf
* dis* fixed signed vs unsigned errors * dismod: fix unused parameter errors * test: Makefile: include -W and -Werror * allow ~ in filename transition rules Allow policy to specify the source of target for generating the default user,role or mls label for a new target.
376 lines
10 KiB
Diff
376 lines
10 KiB
Diff
diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
|
|
index 1bf669c..a86c6b3 100644
|
|
--- a/checkpolicy/policy_define.c
|
|
+++ b/checkpolicy/policy_define.c
|
|
@@ -327,6 +327,126 @@ int define_initial_sid(void)
|
|
return -1;
|
|
}
|
|
|
|
+static int read_classes(ebitmap_t *e_classes)
|
|
+{
|
|
+ char *id;
|
|
+ class_datum_t *cladatum;
|
|
+
|
|
+ while ((id = queue_remove(id_queue))) {
|
|
+ if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
+ yyerror2("class %s is not within scope", id);
|
|
+ return -1;
|
|
+ }
|
|
+ cladatum = hashtab_search(policydbp->p_classes.table, id);
|
|
+ if (!cladatum) {
|
|
+ yyerror2("unknown class %s", id);
|
|
+ return -1;
|
|
+ }
|
|
+ if (ebitmap_set_bit(e_classes, cladatum->s.value - 1, TRUE)) {
|
|
+ yyerror("Out of memory");
|
|
+ return -1;
|
|
+ }
|
|
+ free(id);
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int define_default_user(int which)
|
|
+{
|
|
+ char *id;
|
|
+ class_datum_t *cladatum;
|
|
+
|
|
+ if (pass == 1) {
|
|
+ while ((id = queue_remove(id_queue)))
|
|
+ free(id);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ while ((id = queue_remove(id_queue))) {
|
|
+ if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
+ yyerror2("class %s is not within scope", id);
|
|
+ return -1;
|
|
+ }
|
|
+ cladatum = hashtab_search(policydbp->p_classes.table, id);
|
|
+ if (!cladatum) {
|
|
+ yyerror2("unknown class %s", id);
|
|
+ return -1;
|
|
+ }
|
|
+ if (cladatum->default_user && cladatum->default_user != which) {
|
|
+ yyerror2("conflicting default user information for class %s", id);
|
|
+ return -1;
|
|
+ }
|
|
+ cladatum->default_user = which;
|
|
+ free(id);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int define_default_role(int which)
|
|
+{
|
|
+ char *id;
|
|
+ class_datum_t *cladatum;
|
|
+
|
|
+ if (pass == 1) {
|
|
+ while ((id = queue_remove(id_queue)))
|
|
+ free(id);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ while ((id = queue_remove(id_queue))) {
|
|
+ if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
+ yyerror2("class %s is not within scope", id);
|
|
+ return -1;
|
|
+ }
|
|
+ cladatum = hashtab_search(policydbp->p_classes.table, id);
|
|
+ if (!cladatum) {
|
|
+ yyerror2("unknown class %s", id);
|
|
+ return -1;
|
|
+ }
|
|
+ if (cladatum->default_role && cladatum->default_role != which) {
|
|
+ yyerror2("conflicting default role information for class %s", id);
|
|
+ return -1;
|
|
+ }
|
|
+ cladatum->default_role = which;
|
|
+ free(id);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int define_default_range(int which)
|
|
+{
|
|
+ char *id;
|
|
+ class_datum_t *cladatum;
|
|
+
|
|
+ if (pass == 1) {
|
|
+ while ((id = queue_remove(id_queue)))
|
|
+ free(id);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ while ((id = queue_remove(id_queue))) {
|
|
+ if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
+ yyerror2("class %s is not within scope", id);
|
|
+ return -1;
|
|
+ }
|
|
+ cladatum = hashtab_search(policydbp->p_classes.table, id);
|
|
+ if (!cladatum) {
|
|
+ yyerror2("unknown class %s", id);
|
|
+ return -1;
|
|
+ }
|
|
+ if (cladatum->default_range && cladatum->default_range != which) {
|
|
+ yyerror2("conflicting default range information for class %s", id);
|
|
+ return -1;
|
|
+ }
|
|
+ cladatum->default_range = which;
|
|
+ free(id);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int define_common_perms(void)
|
|
{
|
|
char *id = 0, *perm = 0;
|
|
@@ -1360,7 +1480,6 @@ int define_compute_type_helper(int which, avrule_t ** rule)
|
|
{
|
|
char *id;
|
|
type_datum_t *datum;
|
|
- class_datum_t *cladatum;
|
|
ebitmap_t tclasses;
|
|
ebitmap_node_t *node;
|
|
avrule_t *avrule;
|
|
@@ -1387,23 +1506,8 @@ int define_compute_type_helper(int which, avrule_t ** rule)
|
|
}
|
|
|
|
ebitmap_init(&tclasses);
|
|
- while ((id = queue_remove(id_queue))) {
|
|
- if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
- yyerror2("class %s is not within scope", id);
|
|
- free(id);
|
|
- goto bad;
|
|
- }
|
|
- cladatum = hashtab_search(policydbp->p_classes.table, id);
|
|
- if (!cladatum) {
|
|
- yyerror2("unknown class %s", id);
|
|
- goto bad;
|
|
- }
|
|
- if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) {
|
|
- yyerror("Out of memory");
|
|
- goto bad;
|
|
- }
|
|
- free(id);
|
|
- }
|
|
+ if (read_classes(&tclasses))
|
|
+ goto bad;
|
|
|
|
id = (char *)queue_remove(id_queue);
|
|
if (!id) {
|
|
@@ -1628,25 +1732,9 @@ int define_te_avtab_helper(int which, avrule_t ** rule)
|
|
}
|
|
|
|
ebitmap_init(&tclasses);
|
|
- while ((id = queue_remove(id_queue))) {
|
|
- if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
- yyerror2("class %s is not within scope", id);
|
|
- ret = -1;
|
|
- goto out;
|
|
- }
|
|
- cladatum = hashtab_search(policydbp->p_classes.table, id);
|
|
- if (!cladatum) {
|
|
- yyerror2("unknown class %s used in rule", id);
|
|
- ret = -1;
|
|
- goto out;
|
|
- }
|
|
- if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) {
|
|
- yyerror("Out of memory");
|
|
- ret = -1;
|
|
- goto out;
|
|
- }
|
|
- free(id);
|
|
- }
|
|
+ ret = read_classes(&tclasses);
|
|
+ if (ret)
|
|
+ goto out;
|
|
|
|
perms = NULL;
|
|
ebitmap_for_each_bit(&tclasses, node, i) {
|
|
@@ -2242,22 +2330,8 @@ int define_role_trans(int class_specified)
|
|
}
|
|
|
|
if (class_specified) {
|
|
- while ((id = queue_remove(id_queue))) {
|
|
- if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
- yyerror2("class %s is not within scope", id);
|
|
- free(id);
|
|
- return -1;
|
|
- }
|
|
- cladatum = hashtab_search(policydbp->p_classes.table,
|
|
- id);
|
|
- if (!cladatum) {
|
|
- yyerror2("unknow class %s", id);
|
|
- return -1;
|
|
- }
|
|
-
|
|
- ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE);
|
|
- free(id);
|
|
- }
|
|
+ if (read_classes(&e_classes))
|
|
+ return -1;
|
|
} else {
|
|
cladatum = hashtab_search(policydbp->p_classes.table,
|
|
"process");
|
|
@@ -2410,7 +2484,6 @@ int define_filename_trans(void)
|
|
ebitmap_node_t *snode, *tnode, *cnode;
|
|
filename_trans_t *ft;
|
|
filename_trans_rule_t *ftr;
|
|
- class_datum_t *cladatum;
|
|
type_datum_t *typdatum;
|
|
uint32_t otype;
|
|
unsigned int c, s, t;
|
|
@@ -2451,23 +2524,8 @@ int define_filename_trans(void)
|
|
}
|
|
|
|
ebitmap_init(&e_tclasses);
|
|
- while ((id = queue_remove(id_queue))) {
|
|
- if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
- yyerror2("class %s is not within scope", id);
|
|
- free(id);
|
|
- goto bad;
|
|
- }
|
|
- cladatum = hashtab_search(policydbp->p_classes.table, id);
|
|
- if (!cladatum) {
|
|
- yyerror2("unknown class %s", id);
|
|
- goto bad;
|
|
- }
|
|
- if (ebitmap_set_bit(&e_tclasses, cladatum->s.value - 1, TRUE)) {
|
|
- yyerror("Out of memory");
|
|
- goto bad;
|
|
- }
|
|
- free(id);
|
|
- }
|
|
+ if (read_classes(&e_tclasses))
|
|
+ goto bad;
|
|
|
|
id = (char *)queue_remove(id_queue);
|
|
if (!id) {
|
|
@@ -4549,23 +4607,8 @@ int define_range_trans(int class_specified)
|
|
}
|
|
|
|
if (class_specified) {
|
|
- while ((id = queue_remove(id_queue))) {
|
|
- if (!is_id_in_scope(SYM_CLASSES, id)) {
|
|
- yyerror2("class %s is not within scope", id);
|
|
- free(id);
|
|
- goto out;
|
|
- }
|
|
- cladatum = hashtab_search(policydbp->p_classes.table,
|
|
- id);
|
|
- if (!cladatum) {
|
|
- yyerror2("unknown class %s", id);
|
|
- goto out;
|
|
- }
|
|
-
|
|
- ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1,
|
|
- TRUE);
|
|
- free(id);
|
|
- }
|
|
+ if (read_classes(&rule->tclasses))
|
|
+ goto out;
|
|
} else {
|
|
cladatum = hashtab_search(policydbp->p_classes.table,
|
|
"process");
|
|
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
|
|
index 92a9be7..ccbe56f 100644
|
|
--- a/checkpolicy/policy_define.h
|
|
+++ b/checkpolicy/policy_define.h
|
|
@@ -24,6 +24,9 @@ int define_av_perms(int inherits);
|
|
int define_bool_tunable(int is_tunable);
|
|
int define_category(void);
|
|
int define_class(void);
|
|
+int define_default_user(int which);
|
|
+int define_default_role(int which);
|
|
+int define_default_range(int which);
|
|
int define_common_perms(void);
|
|
int define_compute_type(int which);
|
|
int define_conditional(cond_expr_t *expr, avrule_t *t_list, avrule_t *f_list );
|
|
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
|
|
index d808111..3b7357f 100644
|
|
--- a/checkpolicy/policy_parse.y
|
|
+++ b/checkpolicy/policy_parse.y
|
|
@@ -143,6 +143,8 @@ typedef int (* require_func_t)();
|
|
%token POLICYCAP
|
|
%token PERMISSIVE
|
|
%token FILESYSTEM
|
|
+%token DEFAULT_USER DEFAULT_ROLE DEFAULT_RANGE
|
|
+%token LOW_HIGH LOW HIGH
|
|
|
|
%left OR
|
|
%left XOR
|
|
@@ -157,7 +159,7 @@ base_policy : { if (define_policy(pass, 0) == -1) return -1; }
|
|
classes initial_sids access_vectors
|
|
{ if (pass == 1) { if (policydb_index_classes(policydbp)) return -1; }
|
|
else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1; }}
|
|
- opt_mls te_rbac users opt_constraints
|
|
+ default_rules opt_mls te_rbac users opt_constraints
|
|
{ if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;}
|
|
else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1;}}
|
|
initial_sid_contexts opt_fs_contexts opt_fs_uses opt_genfs_contexts net_contexts opt_dev_contexts
|
|
@@ -195,6 +197,36 @@ av_perms_def : CLASS identifier '{' identifier_list '}'
|
|
| CLASS identifier INHERITS identifier '{' identifier_list '}'
|
|
{if (define_av_perms(TRUE)) return -1;}
|
|
;
|
|
+default_rules : default_user_def
|
|
+ | default_role_def
|
|
+ | default_range_def
|
|
+ | default_rules default_user_def
|
|
+ | default_rules default_role_def
|
|
+ | default_rules default_range_def
|
|
+ ;
|
|
+default_user_def : DEFAULT_USER names SOURCE ';'
|
|
+ {if (define_default_user(DEFAULT_SOURCE)) return -1; }
|
|
+ | DEFAULT_USER names TARGET ';'
|
|
+ {if (define_default_user(DEFAULT_TARGET)) return -1; }
|
|
+ ;
|
|
+default_role_def : DEFAULT_ROLE names SOURCE ';'
|
|
+ {if (define_default_role(DEFAULT_SOURCE)) return -1; }
|
|
+ | DEFAULT_ROLE names TARGET ';'
|
|
+ {if (define_default_role(DEFAULT_TARGET)) return -1; }
|
|
+ ;
|
|
+default_range_def : DEFAULT_RANGE names SOURCE LOW ';'
|
|
+ {if (define_default_range(DEFAULT_SOURCE_LOW)) return -1; }
|
|
+ | DEFAULT_RANGE names SOURCE HIGH ';'
|
|
+ {if (define_default_range(DEFAULT_SOURCE_HIGH)) return -1; }
|
|
+ | DEFAULT_RANGE names SOURCE LOW_HIGH ';'
|
|
+ {if (define_default_range(DEFAULT_SOURCE_LOW_HIGH)) return -1; }
|
|
+ | DEFAULT_RANGE names TARGET LOW ';'
|
|
+ {if (define_default_range(DEFAULT_TARGET_LOW)) return -1; }
|
|
+ | DEFAULT_RANGE names TARGET HIGH ';'
|
|
+ {if (define_default_range(DEFAULT_TARGET_HIGH)) return -1; }
|
|
+ | DEFAULT_RANGE names TARGET LOW_HIGH ';'
|
|
+ {if (define_default_range(DEFAULT_TARGET_LOW_HIGH)) return -1; }
|
|
+ ;
|
|
opt_mls : mls
|
|
|
|
|
;
|
|
diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
|
|
index 9b24db5..e767b5f 100644
|
|
--- a/checkpolicy/policy_scan.l
|
|
+++ b/checkpolicy/policy_scan.l
|
|
@@ -221,6 +221,18 @@ policycap |
|
|
POLICYCAP { return(POLICYCAP); }
|
|
permissive |
|
|
PERMISSIVE { return(PERMISSIVE); }
|
|
+default_user |
|
|
+DEFAULT_USER { return(DEFAULT_USER); }
|
|
+default_role |
|
|
+DEFAULT_ROLE { return(DEFAULT_ROLE); }
|
|
+default_range |
|
|
+DEFAULT_RANGE { return(DEFAULT_RANGE); }
|
|
+low-high |
|
|
+LOW-HIGH { return(LOW_HIGH); }
|
|
+high |
|
|
+HIGH { return(HIGH); }
|
|
+low |
|
|
+LOW { return(LOW); }
|
|
"/"({alnum}|[_\.\-/])* { return(PATH); }
|
|
\"({alnum}|[_\.\-\~])+\" { return(FILENAME); }
|
|
{letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))* { return(IDENTIFIER); }
|