Skip to content

Commit 8fe65b0

Browse files
committed
libsepol/cil: add support for segregate attributes
Support the compile time constraint with the following syntax: (segregateattributes (attr1 attr2 [...])) and reports like: ... Qualifying Names Compile post process Building policy binary Checking Neverallows Checking Segregate Attributes Segregate Attributes violation, type test_type associated with attributes attr1 attr2 Checking User Bounds Checking Role Bounds Checking Type Bounds Failed to generate binary Failed to build policydb Signed-off-by: Christian Göttsche <[email protected]>
1 parent 9344fbe commit 8fe65b0

15 files changed

+346
-0
lines changed

libsepol/cil/src/cil.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ char *CIL_KEY_SRC_CIL;
225225
char *CIL_KEY_SRC_HLL_LMS;
226226
char *CIL_KEY_SRC_HLL_LMX;
227227
char *CIL_KEY_SRC_HLL_LME;
228+
char *CIL_KEY_SEGREGATEATTRIBUTES;
228229

229230
static void cil_init_keys(void)
230231
{
@@ -394,6 +395,7 @@ static void cil_init_keys(void)
394395
CIL_KEY_SRC_HLL_LMS = cil_strpool_add("lms");
395396
CIL_KEY_SRC_HLL_LMX = cil_strpool_add("lmx");
396397
CIL_KEY_SRC_HLL_LME = cil_strpool_add("lme");
398+
CIL_KEY_SEGREGATEATTRIBUTES = cil_strpool_add("segregateattributes");
397399
}
398400

399401
void cil_db_init(struct cil_db **db)
@@ -426,6 +428,7 @@ void cil_db_init(struct cil_db **db)
426428
cil_list_init(&(*db)->userprefixes, CIL_LIST_ITEM);
427429
cil_list_init(&(*db)->selinuxusers, CIL_LIST_ITEM);
428430
cil_list_init(&(*db)->names, CIL_LIST_ITEM);
431+
cil_list_init(&(*db)->segregateattributes, CIL_LIST_ITEM);
429432

430433
cil_type_init(&(*db)->selftype);
431434
(*db)->selftype->datum.name = CIL_KEY_SELF;
@@ -481,6 +484,7 @@ void cil_db_destroy(struct cil_db **db)
481484
cil_list_destroy(&(*db)->userprefixes, CIL_FALSE);
482485
cil_list_destroy(&(*db)->selinuxusers, CIL_FALSE);
483486
cil_list_destroy(&(*db)->names, CIL_TRUE);
487+
cil_list_destroy(&(*db)->segregateattributes, CIL_FALSE);
484488

485489
cil_destroy_type((*db)->selftype);
486490

@@ -1005,6 +1009,9 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
10051009
case CIL_SRC_INFO:
10061010
cil_destroy_src_info(*data);
10071011
break;
1012+
case CIL_SEGREGATEATTRIBUTES:
1013+
cil_destroy_segregateattributes(*data);
1014+
break;
10081015
case CIL_OP:
10091016
case CIL_CONS_OPERAND:
10101017
break;
@@ -1413,6 +1420,8 @@ const char * cil_node_to_string(struct cil_tree_node *node)
14131420
return CIL_KEY_CONS_H1;
14141421
case CIL_CONS_H2:
14151422
return CIL_KEY_CONS_H2;
1423+
case CIL_SEGREGATEATTRIBUTES:
1424+
return CIL_KEY_SEGREGATEATTRIBUTES;
14161425

14171426
default:
14181427
break;
@@ -2904,3 +2913,11 @@ void cil_src_info_init(struct cil_src_info **info)
29042913
(*info)->hll_line = 0;
29052914
(*info)->path = NULL;
29062915
}
2916+
2917+
void cil_segregateattributes_init(struct cil_segregateattributes **sattrs)
2918+
{
2919+
*sattrs = cil_malloc(sizeof(**sattrs));
2920+
2921+
(*sattrs)->str_expr = NULL;
2922+
(*sattrs)->datum_expr = NULL;
2923+
}

libsepol/cil/src/cil_binary.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3818,6 +3818,38 @@ static int cil_defaultrange_to_policydb(policydb_t *pdb, struct cil_defaultrange
38183818
return SEPOL_ERR;
38193819
}
38203820

3821+
static int cil_segregateattributes_to_policydb(policydb_t *pdb, const struct cil_segregateattributes *sattrs)
3822+
{
3823+
segregate_attributes_rule_t *sattr;
3824+
struct cil_list_item *curr;
3825+
type_datum_t *sepol_type;
3826+
int rc = SEPOL_ERR;
3827+
3828+
sattr = cil_malloc(sizeof(segregate_attributes_rule_t));
3829+
ebitmap_init(&sattr->attrs);
3830+
3831+
cil_list_for_each(curr, sattrs->datum_expr) {
3832+
rc = __cil_get_sepol_type_datum(pdb, DATUM(curr->data), &sepol_type);
3833+
if (rc != SEPOL_OK) goto exit;
3834+
3835+
if (ebitmap_set_bit(&sattr->attrs, sepol_type->s.value - 1, 1)) {
3836+
goto exit;
3837+
}
3838+
}
3839+
3840+
sattr->next = pdb->segregate_attributes;
3841+
pdb->segregate_attributes = sattr;
3842+
3843+
return SEPOL_OK;
3844+
3845+
exit:
3846+
if (sattr) {
3847+
ebitmap_destroy(&sattr->attrs);
3848+
free(sattr);
3849+
}
3850+
return rc;
3851+
}
3852+
38213853
static int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
38223854
{
38233855
int rc = SEPOL_OK;
@@ -3960,6 +3992,9 @@ static int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
39603992
case CIL_DEFAULTRANGE:
39613993
rc = cil_defaultrange_to_policydb(pdb, node->data);
39623994
break;
3995+
case CIL_SEGREGATEATTRIBUTES:
3996+
rc = cil_segregateattributes_to_policydb(pdb, node->data);
3997+
break;
39633998
default:
39643999
break;
39654000
}
@@ -4890,6 +4925,42 @@ static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struc
48904925
return rc;
48914926
}
48924927

4928+
static int cil_check_segregateattributes(const policydb_t *pdb, int *violation)
4929+
{
4930+
const segregate_attributes_rule_t *sattr;
4931+
4932+
for (sattr = pdb->segregate_attributes; sattr; sattr = sattr->next) {
4933+
ebitmap_node_t *first_node;
4934+
unsigned int first_bit;
4935+
4936+
ebitmap_for_each_positive_bit(&sattr->attrs, first_node, first_bit) {
4937+
ebitmap_node_t *second_node;
4938+
unsigned int second_bit;
4939+
4940+
ebitmap_for_each_positive_bit_after(&sattr->attrs, second_node, second_bit, first_node, first_bit) {
4941+
ebitmap_t attr_union;
4942+
ebitmap_node_t *type_node;
4943+
unsigned int type_bit;
4944+
4945+
if (ebitmap_and(&attr_union, &pdb->attr_type_map[first_bit], &pdb->attr_type_map[second_bit]))
4946+
return SEPOL_ERR;
4947+
4948+
ebitmap_for_each_positive_bit(&attr_union, type_node, type_bit) {
4949+
cil_log(CIL_ERR, "Segregate Attributes violation, type %s associated with attributes %s and %s\n",
4950+
pdb->p_type_val_to_name[type_bit],
4951+
pdb->p_type_val_to_name[first_bit],
4952+
pdb->p_type_val_to_name[second_bit]);
4953+
*violation = CIL_TRUE;
4954+
}
4955+
4956+
ebitmap_destroy(&attr_union);
4957+
}
4958+
}
4959+
}
4960+
4961+
return SEPOL_OK;
4962+
}
4963+
48934964
static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t class, uint32_t data, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
48944965
{
48954966
struct cil_classperms *cp;
@@ -5160,6 +5231,10 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
51605231
rc = cil_check_neverallows(db, pdb, neverallows, &violation);
51615232
if (rc != SEPOL_OK) goto exit;
51625233

5234+
cil_log(CIL_INFO, "Checking Segregate Attributes\n");
5235+
rc = cil_check_segregateattributes(pdb, &violation);
5236+
if (rc != SEPOL_OK) goto exit;
5237+
51635238
cil_log(CIL_INFO, "Checking User Bounds\n");
51645239
rc = bounds_check_users(NULL, pdb);
51655240
if (rc) {

libsepol/cil/src/cil_build_ast.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6164,6 +6164,62 @@ void cil_destroy_src_info(struct cil_src_info *info)
61646164
free(info);
61656165
}
61666166

6167+
int cil_gen_segregateattributes(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
6168+
{
6169+
enum cil_syntax syntax[] = {
6170+
CIL_SYN_STRING,
6171+
CIL_SYN_LIST,
6172+
CIL_SYN_END
6173+
};
6174+
size_t syntax_len = sizeof(syntax)/sizeof(*syntax);
6175+
struct cil_segregateattributes *sattrs = NULL;
6176+
int rc = SEPOL_ERR;
6177+
6178+
if (db == NULL || parse_current == NULL || ast_node == NULL) {
6179+
goto exit;
6180+
}
6181+
6182+
rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
6183+
if (rc != SEPOL_OK) {
6184+
goto exit;
6185+
}
6186+
6187+
cil_segregateattributes_init(&sattrs);
6188+
6189+
rc = cil_gen_expr(parse_current->next, CIL_TYPEATTRIBUTE, &sattrs->str_expr);
6190+
if (rc != SEPOL_OK) {
6191+
goto exit;
6192+
}
6193+
6194+
/* require at least two attributes */
6195+
if (sattrs->str_expr->head == sattrs->str_expr->tail) {
6196+
rc = SEPOL_ERR;
6197+
goto exit;
6198+
}
6199+
6200+
ast_node->data = sattrs;
6201+
ast_node->flavor = CIL_SEGREGATEATTRIBUTES;
6202+
6203+
return SEPOL_OK;
6204+
6205+
exit:
6206+
cil_tree_log(parse_current, CIL_ERR, "Bad segregate attributes declaration");
6207+
cil_destroy_segregateattributes(sattrs);
6208+
return rc;
6209+
}
6210+
6211+
void cil_destroy_segregateattributes(struct cil_segregateattributes *sattrs)
6212+
{
6213+
if (sattrs == NULL) {
6214+
return;
6215+
}
6216+
6217+
cil_list_destroy(&sattrs->str_expr, CIL_TRUE);
6218+
cil_list_destroy(&sattrs->datum_expr, CIL_FALSE);
6219+
6220+
free(sattrs);
6221+
}
6222+
61676223
static int check_for_illegal_statement(struct cil_tree_node *parse_current, struct cil_args_build *args)
61686224
{
61696225
if (args->tunif != NULL) {
@@ -6455,6 +6511,8 @@ static struct cil_tree_node * parse_statement(struct cil_db *db, struct cil_tree
64556511
rc = cil_gen_mls(parse_current, new_ast_node);
64566512
} else if (parse_current->data == CIL_KEY_SRC_INFO) {
64576513
rc = cil_gen_src_info(parse_current, new_ast_node);
6514+
} else if (parse_current->data == CIL_KEY_SEGREGATEATTRIBUTES) {
6515+
rc = cil_gen_segregateattributes(db, parse_current, new_ast_node);
64586516
} else {
64596517
cil_log(CIL_ERR, "Error: Unknown keyword %s\n", (char *)parse_current->data);
64606518
rc = SEPOL_ERR;

libsepol/cil/src/cil_build_ast.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no
225225
void cil_destroy_defaultrange(struct cil_defaultrange *def);
226226
int cil_gen_src_info(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
227227
void cil_destroy_src_info(struct cil_src_info *info);
228+
int cil_gen_segregateattributes(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
229+
void cil_destroy_segregateattributes(struct cil_segregateattributes *sattrs);
228230

229231
int cil_fill_cats(struct cil_tree_node *curr, struct cil_cats **cats);
230232
void cil_destroy_cats(struct cil_cats *cats);

libsepol/cil/src/cil_copy_ast.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,6 +1697,21 @@ static int cil_copy_src_info(__attribute__((unused)) struct cil_db *db, void *da
16971697
return SEPOL_OK;
16981698
}
16991699

1700+
static int cil_copy_segregateattributes(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
1701+
{
1702+
struct cil_segregateattributes *orig = data;
1703+
struct cil_segregateattributes *new = NULL;
1704+
1705+
cil_segregateattributes_init(&new);
1706+
1707+
cil_copy_expr(db, orig->str_expr, &new->str_expr);
1708+
cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
1709+
1710+
*copy = new;
1711+
1712+
return SEPOL_OK;
1713+
}
1714+
17001715
static int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished, void *extra_args)
17011716
{
17021717
int rc = SEPOL_ERR;
@@ -1990,6 +2005,9 @@ static int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished
19902005
case CIL_SRC_INFO:
19912006
copy_func = &cil_copy_src_info;
19922007
break;
2008+
case CIL_SEGREGATEATTRIBUTES:
2009+
copy_func = &cil_copy_segregateattributes;
2010+
break;
19932011
default:
19942012
goto exit;
19952013
}

libsepol/cil/src/cil_flavor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ enum cil_flavor {
115115
CIL_SRC_INFO,
116116
CIL_IBPKEYCON,
117117
CIL_IBENDPORTCON,
118+
CIL_SEGREGATEATTRIBUTES,
118119

119120
/*
120121
* boolean constraint set catset

libsepol/cil/src/cil_internal.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ extern char *CIL_KEY_SRC_CIL;
242242
extern char *CIL_KEY_SRC_HLL_LMS;
243243
extern char *CIL_KEY_SRC_HLL_LMX;
244244
extern char *CIL_KEY_SRC_HLL_LME;
245+
extern char *CIL_KEY_SEGREGATEATTRIBUTES;
245246

246247
/*
247248
Symbol Table Array Indices
@@ -309,6 +310,7 @@ struct cil_db {
309310
struct cil_list *userprefixes;
310311
struct cil_list *selinuxusers;
311312
struct cil_list *names;
313+
struct cil_list *segregateattributes;
312314
int num_types_and_attrs;
313315
int num_classes;
314316
int num_cats;
@@ -975,6 +977,11 @@ struct cil_src_info {
975977
char *path;
976978
};
977979

980+
struct cil_segregateattributes {
981+
struct cil_list *str_expr;
982+
struct cil_list *datum_expr;
983+
};
984+
978985
void cil_db_init(struct cil_db **db);
979986
void cil_db_destroy(struct cil_db **db);
980987

@@ -1085,5 +1092,6 @@ void cil_mls_init(struct cil_mls **mls);
10851092
void cil_src_info_init(struct cil_src_info **info);
10861093
void cil_userattribute_init(struct cil_userattribute **attribute);
10871094
void cil_userattributeset_init(struct cil_userattributeset **attrset);
1095+
void cil_segregateattributes_init(struct cil_segregateattributes **sattrs);
10881096

10891097
#endif

libsepol/cil/src/cil_policy.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ enum cil_statement_list {
6969
CIL_LIST_USER,
7070
CIL_LIST_CONSTRAINT,
7171
CIL_LIST_VALIDATETRANS,
72+
CIL_LIST_SEGREGATEATTRIBUTES,
7273
CIL_LIST_NUM_LISTS
7374
};
7475

@@ -168,6 +169,9 @@ static int __cil_gather_statements_helper(struct cil_tree_node *node, uint32_t *
168169
case CIL_VALIDATETRANS:
169170
kind = CIL_LIST_VALIDATETRANS;
170171
break;
172+
case CIL_SEGREGATEATTRIBUTES:
173+
kind = CIL_LIST_SEGREGATEATTRIBUTES;
174+
break;
171175
default:
172176
break;
173177
}
@@ -1911,6 +1915,27 @@ static void cil_devicetreecons_to_policy(FILE *out, struct cil_sort *devicetreec
19111915
}
19121916
}
19131917

1918+
static void cil_segregateattributes_to_policy(FILE *out, struct cil_list *sattrs_list)
1919+
{
1920+
struct cil_list_item *curr_sattrs, *curr_attr;
1921+
struct cil_segregateattributes *sattrs;
1922+
int first = 1;
1923+
1924+
cil_list_for_each(curr_sattrs, sattrs_list) {
1925+
sattrs = curr_sattrs->data;
1926+
fprintf(out, "segregate_attriutes ");
1927+
cil_list_for_each(curr_attr, sattrs->datum_expr) {
1928+
if (!first) {
1929+
first = 0;
1930+
} else {
1931+
fprintf(out, ", ");
1932+
}
1933+
fprintf(out, "%s", DATUM(curr_attr->data)->fqn);
1934+
}
1935+
fprintf(out, ";\n");
1936+
}
1937+
}
1938+
19141939
void cil_gen_policy(FILE *out, struct cil_db *db)
19151940
{
19161941
unsigned i;
@@ -1956,6 +1981,7 @@ void cil_gen_policy(FILE *out, struct cil_db *db)
19561981
cil_typebounds_to_policy(out, lists[CIL_LIST_TYPE]);
19571982
cil_typeattributes_to_policy(out, lists[CIL_LIST_TYPE], lists[CIL_LIST_TYPEATTRIBUTE]);
19581983
cil_te_rules_to_policy(out, head, db->mls);
1984+
cil_segregateattributes_to_policy(out, db->segregateattributes);
19591985

19601986
cil_roles_to_policy(out, lists[CIL_LIST_ROLE]);
19611987
cil_role_types_to_policy(out, lists[CIL_LIST_ROLE], lists[CIL_LIST_TYPE]);

libsepol/cil/src/cil_reset_ast.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,11 @@ static void cil_reset_booleanif(struct cil_booleanif *bif)
475475
cil_list_destroy(&bif->datum_expr, CIL_FALSE);
476476
}
477477

478+
static void cil_reset_segregateattributes(struct cil_segregateattributes *sattrs)
479+
{
480+
cil_list_destroy(&sattrs->datum_expr, CIL_FALSE);
481+
}
482+
478483
static int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, __attribute__((unused)) void *extra_args)
479484
{
480485
switch (node->flavor) {
@@ -630,6 +635,9 @@ static int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused))
630635
case CIL_BOOLEANIF:
631636
cil_reset_booleanif(node->data);
632637
break;
638+
case CIL_SEGREGATEATTRIBUTES:
639+
cil_reset_segregateattributes(node->data);
640+
break;
633641
case CIL_TUNABLEIF:
634642
case CIL_CALL:
635643
break; /* Not effected by optional block disabling */

0 commit comments

Comments
 (0)