@@ -3896,6 +3896,38 @@ static int cil_defaultrange_to_policydb(policydb_t *pdb, struct cil_defaultrange
38963896 return SEPOL_ERR ;
38973897}
38983898
3899+ static int cil_disjointattributes_to_policydb (policydb_t * pdb , const struct cil_disjointattributes * dattrs )
3900+ {
3901+ disjoint_attributes_rule_t * dattr ;
3902+ struct cil_list_item * curr ;
3903+ type_datum_t * sepol_type ;
3904+ int rc = SEPOL_ERR ;
3905+
3906+ dattr = cil_malloc (sizeof (disjoint_attributes_rule_t ));
3907+ ebitmap_init (& dattr -> attrs );
3908+
3909+ cil_list_for_each (curr , dattrs -> datum_expr ) {
3910+ rc = __cil_get_sepol_type_datum (pdb , DATUM (curr -> data ), & sepol_type );
3911+ if (rc != SEPOL_OK ) goto exit ;
3912+
3913+ if (ebitmap_set_bit (& dattr -> attrs , sepol_type -> s .value - 1 , 1 )) {
3914+ goto exit ;
3915+ }
3916+ }
3917+
3918+ dattr -> next = pdb -> disjoint_attributes ;
3919+ pdb -> disjoint_attributes = dattr ;
3920+
3921+ return SEPOL_OK ;
3922+
3923+ exit :
3924+ if (dattr ) {
3925+ ebitmap_destroy (& dattr -> attrs );
3926+ free (dattr );
3927+ }
3928+ return rc ;
3929+ }
3930+
38993931static int __cil_node_to_policydb (struct cil_tree_node * node , void * extra_args )
39003932{
39013933 int rc = SEPOL_OK ;
@@ -4038,6 +4070,9 @@ static int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
40384070 case CIL_DEFAULTRANGE :
40394071 rc = cil_defaultrange_to_policydb (pdb , node -> data );
40404072 break ;
4073+ case CIL_DISJOINTATTRIBUTES :
4074+ rc = cil_disjointattributes_to_policydb (pdb , node -> data );
4075+ break ;
40414076 default :
40424077 break ;
40434078 }
@@ -4976,6 +5011,42 @@ static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struc
49765011 return rc ;
49775012}
49785013
5014+ static int cil_check_disjointattributes (const policydb_t * pdb , int * violation )
5015+ {
5016+ const disjoint_attributes_rule_t * dattr ;
5017+
5018+ for (dattr = pdb -> disjoint_attributes ; dattr ; dattr = dattr -> next ) {
5019+ ebitmap_node_t * first_node ;
5020+ unsigned int first_bit ;
5021+
5022+ ebitmap_for_each_positive_bit (& dattr -> attrs , first_node , first_bit ) {
5023+ ebitmap_node_t * second_node ;
5024+ unsigned int second_bit ;
5025+
5026+ ebitmap_for_each_positive_bit_after (& dattr -> attrs , second_node , second_bit , first_node , first_bit ) {
5027+ ebitmap_t attr_union ;
5028+ ebitmap_node_t * type_node ;
5029+ unsigned int type_bit ;
5030+
5031+ if (ebitmap_and (& attr_union , & pdb -> attr_type_map [first_bit ], & pdb -> attr_type_map [second_bit ]))
5032+ return SEPOL_ERR ;
5033+
5034+ ebitmap_for_each_positive_bit (& attr_union , type_node , type_bit ) {
5035+ cil_log (CIL_ERR , "Disjoint Attributes Rule violation, type %s associated with attributes %s and %s\n" ,
5036+ pdb -> p_type_val_to_name [type_bit ],
5037+ pdb -> p_type_val_to_name [first_bit ],
5038+ pdb -> p_type_val_to_name [second_bit ]);
5039+ * violation = CIL_TRUE ;
5040+ }
5041+
5042+ ebitmap_destroy (& attr_union );
5043+ }
5044+ }
5045+ }
5046+
5047+ return SEPOL_OK ;
5048+ }
5049+
49795050static 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 [])
49805051{
49815052 struct cil_classperms * cp ;
@@ -5246,6 +5317,10 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
52465317 rc = cil_check_neverallows (db , pdb , neverallows , & violation );
52475318 if (rc != SEPOL_OK ) goto exit ;
52485319
5320+ cil_log (CIL_INFO , "Checking Disjoint Attributes Rules\n" );
5321+ rc = cil_check_disjointattributes (pdb , & violation );
5322+ if (rc != SEPOL_OK ) goto exit ;
5323+
52495324 cil_log (CIL_INFO , "Checking User Bounds\n" );
52505325 rc = bounds_check_users (NULL , pdb );
52515326 if (rc ) {
0 commit comments