Yes, we are generating CIL from policy.conf files.
On Fri, May 5, 2017 at 1:28 PM James Carter <[email protected]> wrote:
> On 05/04/2017 05:36 PM, Jeff Vander Stoep wrote:
> > This commit adds attribute expansion statements to the policy
> > language allowing compiler defaults to be overridden.
> >
> > Always expands an attribute example:
> > expandattribute { foo } true;
> > CIL example:
> > (expandtypeattribute (foo) true)
> >
> > Never expand an attribute example:
> > expandattribute { bar } false;
> > CIL example:
> > (expandtypeattribute (bar) false)
> >
>
> It works for secilc and for checkpolicy -C (which outputs CIL), but the
> expandattribute rules are ignored when building the kernel policy from a
> policy.conf. Are you generating CIL from policy.conf files? If not, then it
> might make sense to only have this feature in CIL.
>
> Jim
>
> > Adding the annotations directly to policy was chosen over other
> > methods as it is consistent with how targeted runtime optimizations
> > are specified in other languages. For example, in C the "inline"
> > command.
> >
> > Motivation
> >
> > expandattribute true:
> > Android has been moving away from a monolithic policy binary to
> > a two part split policy representing the Android platform and the
> > underlying vendor-provided hardware interface. The goal is a stable
> > API allowing these two parts to be updated independently of each
> > other. Attributes provide an important mechanism for compatibility.
> > For example, when the vendor provides a HAL for the platform,
> > permissions needed by clients of the HAL can be granted to an
> > attribute. Clients need only be assigned the attribute and do not
> > need to be aware of the underlying types and permissions being
> > granted.
> >
> > Inheriting permissions via attribute creates a convenient mechanism
> > for independence between vendor and platform policy, but results
> > in the creation of many attributes, and the potential for performance
> > issues when processes are clients of many HALs. [1] Annotating these
> > attributes for expansion at compile time allows us to retain the
> > compatibility benefits of using attributes without the performance
> > costs. [2]
> >
> > expandattribute false:
> > Commit 0be23c3f15fd added the capability to aggresively remove unused
> > attributes. This is generally useful as too many attributes assigned
> > to a type results in lengthy policy look up times when there is a
> > cache miss. However, removing attributes can also result in loss of
> > information used in external tests. On Android, we're considering
> > stripping neverallow rules from on-device policy. This is consistent
> > with the kernel policy binary which also did not contain neverallows.
> > Removing neverallow rules results in a 5-10% decrease in on-device
> > policy build and load and a policy size decrease of ~250k. Neverallow
> > rules are still asserted at build time and during device
> > certification (CTS). If neverallow rules are absent when secilc is
> > run, some attributes are being stripped from policy and neverallow
> > tests in CTS may be violated. [3] This change retains the aggressive
> > attribute stripping behavior but adds an override mechanism to
> > preserve attributes marked as necessary.
> >
> > [1] https://github.com/SELinuxProject/cil/issues/9
> > [2] Annotating all HAL client attributes for expansion resulted in
> > system_server's dropping from 19 attributes to 8. Because these
> > attributes were not widely applied to other types, the final
> > policy size change was negligible.
> > [3] data_file_type and service_manager_type are stripped from AOSP
> > policy when using secilc's -G option. This impacts 11 neverallow
> > tests in CTS.
> >
> > Test: Build and boot Marlin with all hal_*_client attributes marked
> > for expansion. Verify (using seinfo and sesearch) that permissions
> > are correctly expanded from attributes to types.
> > Test: Mark types being stripped by secilc with "preserve" and verify
> > that they are retained in policy and applied to the same types.
> >
> > Signed-off-by: Jeff Vander Stoep <[email protected]>
> > ---
> > checkpolicy/policy_define.c | 82
> ++++++++++++++++++++++++++++++
> > checkpolicy/policy_define.h | 1 +
> > checkpolicy/policy_parse.y | 5 ++
> > checkpolicy/policy_scan.l | 2 +
> > libsepol/cil/src/cil.c | 15 ++++++
> > libsepol/cil/src/cil_build_ast.c | 72
> ++++++++++++++++++++++++++
> > libsepol/cil/src/cil_build_ast.h | 2 +
> > libsepol/cil/src/cil_copy_ast.c | 26 ++++++++++
> > libsepol/cil/src/cil_flavor.h | 1 +
> > libsepol/cil/src/cil_internal.h | 16 ++++--
> > libsepol/cil/src/cil_post.c | 8 +++
> > libsepol/cil/src/cil_reset_ast.c | 1 +
> > libsepol/cil/src/cil_resolve_ast.c | 53 ++++++++++++++++++-
> > libsepol/cil/src/cil_tree.c | 11 ++++
> > libsepol/include/sepol/policydb/policydb.h | 6 ++-
> > libsepol/src/module_to_cil.c | 11 ++++
> > 16 files changed, 307 insertions(+), 5 deletions(-)
> >
> > diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
> > index 949ca711..63e3c53f 100644
> > --- a/checkpolicy/policy_define.c
> > +++ b/checkpolicy/policy_define.c
> > @@ -1139,6 +1139,88 @@ int define_attrib(void)
> > return 0;
> > }
> >
> > +int expand_attrib(void)
> > +{
> > + char *id;
> > + ebitmap_t attrs;
> > + type_datum_t *attr;
> > + ebitmap_node_t *node;
> > + uint32_t i;
> > + int rc = -1;
> > + int flags = 0;
> > +
> > + if (pass == 1) {
> > + for (i = 0; i < 2; i++) {
> > + while ((id = queue_remove(id_queue))) {
> > + free(id);
> > + }
> > + }
> > + return 0;
> > + }
> > +
> > + ebitmap_init(&attrs);
> > + while ((id = queue_remove(id_queue))) {
> > + if (!id) {
> > + yyerror("No attribute name for expandattribute
> statement?");
> > + goto exit;
> > + }
> > +
> > + if (!is_id_in_scope(SYM_TYPES, id)) {
> > + yyerror2("attribute %s is not within scope", id);
> > + goto exit;
> > + }
> > +
> > + attr = hashtab_search(policydbp->p_types.table, id);
> > + if (!attr) {
> > + yyerror2("attribute %s is not declared", id);
> > + goto exit;
> > + }
> > +
> > + if (attr->flavor != TYPE_ATTRIB) {
> > + yyerror2("%s is a type, not an attribute", id);
> > + goto exit;
> > + }
> > +
> > + if (attr->flags & TYPE_FLAGS_EXPAND_ATTR) {
> > + yyerror2("%s already has the expandattribute
> option specified", id);
> > + goto exit;
> > + }
> > + if (ebitmap_set_bit(&attrs, attr->s.value - 1, TRUE)) {
> > + yyerror("Out of memory!");
> > + goto exit;
> > + }
> > +
> > + free(id);
> > + }
> > +
> > + id = (char *) queue_remove(id_queue);
> > + if (!id) {
> > + yyerror("No option specified for attribute expansion.");
> > + goto exit;
> > + }
> > +
> > + if (!strcmp(id, "T")) {
> > + flags = TYPE_FLAGS_EXPAND_ATTR_TRUE;
> > + } else {
> > + flags = TYPE_FLAGS_EXPAND_ATTR_FALSE;
> > + }
> > +
> > + ebitmap_for_each_bit(&attrs, node, i) {
> > + if (!ebitmap_node_get_bit(node, i)){
> > + continue;
> > + }
> > + attr = hashtab_search(policydbp->p_types.table,
> > + policydbp->sym_val_to_name[SYM_TYPES][i]);
> > + attr->flags |= flags;
> > + }
> > +
> > + rc = 0;
> > +exit:
> > + ebitmap_destroy(&attrs);
> > + free(id);
> > + return rc;
> > +}
> > +
> > static int add_aliases_to_type(type_datum_t * type)
> > {
> > char *id;
> > diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
> > index 964baae0..9f4b6d0d 100644
> > --- a/checkpolicy/policy_define.h
> > +++ b/checkpolicy/policy_define.h
> > @@ -65,6 +65,7 @@ int define_typebounds(void);
> > int define_type(int alias);
> > int define_user(void);
> > int define_validatetrans(constraint_expr_t *expr);
> > +int expand_attrib(void);
> > int insert_id(const char *id,int push);
> > int insert_separator(int push);
> > role_datum_t *define_role_dom(role_datum_t *r);
> > diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
> > index 3b6a2f86..1ac1c96b 100644
> > --- a/checkpolicy/policy_parse.y
> > +++ b/checkpolicy/policy_parse.y
> > @@ -103,6 +103,7 @@ typedef int (* require_func_t)(int pass);
> > %token TYPES
> > %token ALIAS
> > %token ATTRIBUTE
> > +%token EXPANDATTRIBUTE
> > %token BOOL
> > %token TUNABLE
> > %token IF
> > @@ -314,6 +315,7 @@ rbac_decl : attribute_role_def
> > | role_attr_def
> > ;
> > te_decl : attribute_def
> > + | expandattribute_def
> > | type_def
> > | typealias_def
> > | typeattribute_def
> > @@ -328,6 +330,9 @@ te_decl : attribute_def
> > attribute_def : ATTRIBUTE identifier ';'
> > { if (define_attrib()) return -1;}
> > ;
> > +expandattribute_def : EXPANDATTRIBUTE names bool_val ';'
> > + { if (expand_attrib()) return -1;}
> > + ;
> > type_def : TYPE identifier alias_def opt_attr_list ';'
> > {if (define_type(1)) return -1;}
> > | TYPE identifier opt_attr_list ';'
> > diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
> > index 2f7f2216..028bd25e 100644
> > --- a/checkpolicy/policy_scan.l
> > +++ b/checkpolicy/policy_scan.l
> > @@ -106,6 +106,8 @@ ALIAS |
> > alias { return(ALIAS); }
> > ATTRIBUTE |
> > attribute { return(ATTRIBUTE); }
> > +EXPANDATTRIBUTE |
> > +expandattribute { return(EXPANDATTRIBUTE); }
> > TYPE_TRANSITION |
> > type_transition { return(TYPE_TRANSITION); }
> > TYPE_MEMBER |
> > diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
> > index a64c5284..9b9ccc36 100644
> > --- a/libsepol/cil/src/cil.c
> > +++ b/libsepol/cil/src/cil.c
> > @@ -159,6 +159,7 @@ static void cil_init_keys(void)
> > CIL_KEY_SELINUXUSERDEFAULT = cil_strpool_add("selinuxuserdefault");
> > CIL_KEY_TYPEATTRIBUTE = cil_strpool_add("typeattribute");
> > CIL_KEY_TYPEATTRIBUTESET = cil_strpool_add("typeattributeset");
> > + CIL_KEY_EXPANDTYPEATTRIBUTE =
> cil_strpool_add("expandtypeattribute");
> > CIL_KEY_TYPEALIAS = cil_strpool_add("typealias");
> > CIL_KEY_TYPEALIASACTUAL = cil_strpool_add("typealiasactual");
> > CIL_KEY_TYPEBOUNDS = cil_strpool_add("typebounds");
> > @@ -623,6 +624,9 @@ void cil_destroy_data(void **data, enum cil_flavor
> flavor)
> > case CIL_TYPEATTRIBUTESET:
> > cil_destroy_typeattributeset(*data);
> > break;
> > + case CIL_EXPANDTYPEATTRIBUTE:
> > + cil_destroy_expandtypeattribute(*data);
> > + break;
> > case CIL_TYPEALIASACTUAL:
> > cil_destroy_aliasactual(*data);
> > break;
> > @@ -987,6 +991,8 @@ const char * cil_node_to_string(struct cil_tree_node
> *node)
> > return CIL_KEY_TYPEALIAS;
> > case CIL_TYPEATTRIBUTESET:
> > return CIL_KEY_TYPEATTRIBUTESET;
> > + case CIL_EXPANDTYPEATTRIBUTE:
> > + return CIL_KEY_EXPANDTYPEATTRIBUTE;
> > case CIL_TYPEALIASACTUAL:
> > return CIL_KEY_TYPEALIASACTUAL;
> > case CIL_TYPEBOUNDS:
> > @@ -2038,6 +2044,15 @@ void cil_typeattributeset_init(struct
> cil_typeattributeset **attrset)
> > (*attrset)->datum_expr = NULL;
> > }
> >
> > +void cil_expandtypeattribute_init(struct cil_expandtypeattribute
> **expandattr)
> > +{
> > + *expandattr = cil_malloc(sizeof(**expandattr));
> > +
> > + (*expandattr)->attr_strs = NULL;
> > + (*expandattr)->attr_datums = NULL;
> > + (*expandattr)->expand = 0;
> > +}
> > +
> > void cil_alias_init(struct cil_alias **alias)
> > {
> > *alias = cil_malloc(sizeof(**alias));
> > diff --git a/libsepol/cil/src/cil_build_ast.c
> b/libsepol/cil/src/cil_build_ast.c
> > index 4b03dc35..36cc6735 100644
> > --- a/libsepol/cil/src/cil_build_ast.c
> > +++ b/libsepol/cil/src/cil_build_ast.c
> > @@ -3176,6 +3176,75 @@ void cil_destroy_typeattributeset(struct
> cil_typeattributeset *attrset)
> > free(attrset);
> > }
> >
> > +int cil_gen_expandtypeattribute(struct cil_db *db, struct cil_tree_node
> *parse_current, struct cil_tree_node *ast_node)
> > +{
> > + enum cil_syntax syntax[] = {
> > + CIL_SYN_STRING,
> > + CIL_SYN_STRING | CIL_SYN_LIST,
> > + CIL_SYN_STRING,
> > + CIL_SYN_END
> > + };
> > + char *expand_str;
> > + int syntax_len = sizeof(syntax)/sizeof(*syntax);
> > + struct cil_expandtypeattribute *expandattr = NULL;
> > + int rc = SEPOL_ERR;
> > +
> > + if (db == NULL || parse_current == NULL || ast_node == NULL) {
> > + goto exit;
> > + }
> > +
> > + rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
> > + if (rc != SEPOL_OK) {
> > + goto exit;
> > + }
> > +
> > + cil_expandtypeattribute_init(&expandattr);
> > +
> > + if (parse_current->next->cl_head == NULL) {
> > + cil_list_init(&expandattr->attr_strs, CIL_TYPE);
> > + cil_list_append(expandattr->attr_strs, CIL_STRING,
> parse_current->next->data);
> > + } else {
> > + rc = cil_fill_list(parse_current->next->cl_head, CIL_TYPE,
> &expandattr->attr_strs);
> > + if (rc != SEPOL_OK) {
> > + goto exit;
> > + }
> > + }
> > +
> > + expand_str = parse_current->next->next->data;
> > +
> > + if (expand_str == CIL_KEY_CONDTRUE) {
> > + expandattr->expand = CIL_TRUE;
> > + } else if (expand_str == CIL_KEY_CONDFALSE) {
> > + expandattr->expand = CIL_FALSE;
> > + } else {
> > + cil_log(CIL_ERR, "Value must be either \'true\' or
> \'false\'");
> > + goto exit;
> > + }
> > +
> > + ast_node->data = expandattr;
> > + ast_node->flavor = CIL_EXPANDTYPEATTRIBUTE;
> > +
> > + return SEPOL_OK;
> > +
> > +exit:
> > + cil_tree_log(parse_current, CIL_ERR, "Bad expandtypeattribute
> statement");
> > + cil_destroy_expandtypeattribute(expandattr);
> > + return rc;
> > +}
> > +
> > +void cil_destroy_expandtypeattribute(struct cil_expandtypeattribute
> *expandattr)
> > +{
> > + if (expandattr == NULL) {
> > + return;
> > + }
> > +
> > + cil_list_destroy(&expandattr->attr_strs, CIL_TRUE);
> > +
> > + cil_list_destroy(&expandattr->attr_datums, CIL_FALSE);
> > +
> > + free(expandattr);
> > +}
> > +
> > int cil_gen_typepermissive(struct cil_db *db, struct cil_tree_node
> *parse_current, struct cil_tree_node *ast_node)
> > {
> > enum cil_syntax syntax[] = {
> > @@ -6013,6 +6082,9 @@ int __cil_build_ast_node_helper(struct
> cil_tree_node *parse_current, uint32_t *f
> > } else if (parse_current->data == CIL_KEY_TYPEATTRIBUTESET) {
> > rc = cil_gen_typeattributeset(db, parse_current, ast_node);
> > *finished = CIL_TREE_SKIP_NEXT;
> > + } else if (parse_current->data == CIL_KEY_EXPANDTYPEATTRIBUTE) {
> > + rc = cil_gen_expandtypeattribute(db, parse_current,
> ast_node);
> > + *finished = CIL_TREE_SKIP_NEXT;
> > } else if (parse_current->data == CIL_KEY_TYPEALIAS) {
> > rc = cil_gen_alias(db, parse_current, ast_node,
> CIL_TYPEALIAS);
> > } else if (parse_current->data == CIL_KEY_TYPEALIASACTUAL) {
> > diff --git a/libsepol/cil/src/cil_build_ast.h
> b/libsepol/cil/src/cil_build_ast.h
> > index 54662035..33bae997 100644
> > --- a/libsepol/cil/src/cil_build_ast.h
> > +++ b/libsepol/cil/src/cil_build_ast.h
> > @@ -138,6 +138,8 @@ int cil_gen_aliasactual(struct cil_db *db, struct
> cil_tree_node *parse_current,
> > void cil_destroy_aliasactual(struct cil_aliasactual *aliasactual);
> > int cil_gen_typeattributeset(struct cil_db *db, struct cil_tree_node
> *parse_current, struct cil_tree_node *ast_node);
> > void cil_destroy_typeattributeset(struct cil_typeattributeset
> *attrtypes);
> > +int cil_gen_expandtypeattribute(struct cil_db *db, struct cil_tree_node
> *parse_current, struct cil_tree_node *ast_node);
> > +void cil_destroy_expandtypeattribute(struct cil_expandtypeattribute
> *expandattr);
> > int cil_gen_typebounds(struct cil_db *db, struct cil_tree_node
> *parse_current, struct cil_tree_node *ast_node);
> > int cil_gen_typepermissive(struct cil_db *db, struct cil_tree_node
> *parse_current, struct cil_tree_node *ast_node);
> > void cil_destroy_typepermissive(struct cil_typepermissive *typeperm);
> > diff --git a/libsepol/cil/src/cil_copy_ast.c
> b/libsepol/cil/src/cil_copy_ast.c
> > index 2d085dd7..d6685050 100644
> > --- a/libsepol/cil/src/cil_copy_ast.c
> > +++ b/libsepol/cil/src/cil_copy_ast.c
> > @@ -648,6 +648,29 @@ int cil_copy_typeattributeset(struct cil_db *db,
> void *data, void **copy, __attr
> > return SEPOL_OK;
> > }
> >
> > +int cil_copy_expandtypeattribute(__attribute__((unused)) struct cil_db
> *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
> > +{
> > + struct cil_expandtypeattribute *orig = data;
> > + struct cil_expandtypeattribute *new = NULL;
> > +
> > + fprintf(stderr, "%s %u\n", __func__, __LINE__);
> > + cil_expandtypeattribute_init(&new);
> > +
> > + if (orig->attr_strs != NULL) {
> > + cil_copy_list(orig->attr_strs, &new->attr_strs);
> > + }
> > +
> > + if (orig->attr_datums != NULL) {
> > + cil_copy_list(orig->attr_datums, &new->attr_datums);
> > + }
> > +
> > + new->expand = orig->expand;
> > +
> > + *copy = new;
> > +
> > + return SEPOL_OK;
> > +}
> > +
> > int cil_copy_alias(__attribute__((unused)) struct cil_db *db, void
> *data, void **copy, symtab_t *symtab)
> > {
> > struct cil_alias *orig = data;
> > @@ -1808,6 +1831,9 @@ int __cil_copy_node_helper(struct cil_tree_node
> *orig, __attribute__((unused)) u
> > case CIL_TYPEATTRIBUTESET:
> > copy_func = &cil_copy_typeattributeset;
> > break;
> > + case CIL_EXPANDTYPEATTRIBUTE:
> > + copy_func = &cil_copy_expandtypeattribute;
> > + break;
> > case CIL_TYPEALIAS:
> > copy_func = &cil_copy_alias;
> > break;
> > diff --git a/libsepol/cil/src/cil_flavor.h
> b/libsepol/cil/src/cil_flavor.h
> > index cd08b972..c01f967a 100644
> > --- a/libsepol/cil/src/cil_flavor.h
> > +++ b/libsepol/cil/src/cil_flavor.h
> > @@ -73,6 +73,7 @@ enum cil_flavor {
> > CIL_ROLETYPE,
> > CIL_ROLEBOUNDS,
> > CIL_TYPEATTRIBUTESET,
> > + CIL_EXPANDTYPEATTRIBUTE,
> > CIL_TYPEALIASACTUAL,
> > CIL_TYPEBOUNDS,
> > CIL_TYPEPERMISSIVE,
> > diff --git a/libsepol/cil/src/cil_internal.h
> b/libsepol/cil/src/cil_internal.h
> > index efa2cd6e..aee3f00c 100644
> > --- a/libsepol/cil/src/cil_internal.h
> > +++ b/libsepol/cil/src/cil_internal.h
> > @@ -174,6 +174,7 @@ char *CIL_KEY_SELINUXUSER;
> > char *CIL_KEY_SELINUXUSERDEFAULT;
> > char *CIL_KEY_TYPEATTRIBUTE;
> > char *CIL_KEY_TYPEATTRIBUTESET;
> > +char *CIL_KEY_EXPANDTYPEATTRIBUTE;
> > char *CIL_KEY_TYPEALIAS;
> > char *CIL_KEY_TYPEALIASACTUAL;
> > char *CIL_KEY_TYPEBOUNDS;
> > @@ -515,9 +516,11 @@ struct cil_type {
> > int value;
> > };
> >
> > -#define CIL_ATTR_AVRULE 0x01
> > -#define CIL_ATTR_NEVERALLOW 0x02
> > -#define CIL_ATTR_CONSTRAINT 0x04
> > +#define CIL_ATTR_AVRULE (1 << 0)
> > +#define CIL_ATTR_NEVERALLOW (1 << 1)
> > +#define CIL_ATTR_CONSTRAINT (1 << 2)
> > +#define CIL_ATTR_EXPAND_TRUE (1 << 3)
> > +#define CIL_ATTR_EXPAND_FALSE (1 << 4)
> > struct cil_typeattribute {
> > struct cil_symtab_datum datum;
> > struct cil_list *expr_list;
> > @@ -531,6 +534,12 @@ struct cil_typeattributeset {
> > struct cil_list *datum_expr;
> > };
> >
> > +struct cil_expandtypeattribute {
> > + struct cil_list *attr_strs;
> > + struct cil_list *attr_datums;
> > + int expand;
> > +};
> > +
> > struct cil_typepermissive {
> > char *type_str;
> > void *type; /* type or alias */
> > @@ -977,6 +986,7 @@ void cil_roleattributeset_init(struct
> cil_roleattributeset **attrset);
> > void cil_roletype_init(struct cil_roletype **roletype);
> > void cil_typeattribute_init(struct cil_typeattribute **attribute);
> > void cil_typeattributeset_init(struct cil_typeattributeset **attrset);
> > +void cil_expandtypeattribute_init(struct cil_expandtypeattribute
> **expandattr);
> > void cil_alias_init(struct cil_alias **alias);
> > void cil_aliasactual_init(struct cil_aliasactual **aliasactual);
> > void cil_typepermissive_init(struct cil_typepermissive **typeperm);
> > diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
> > index e32a8fc9..1941fab3 100644
> > --- a/libsepol/cil/src/cil_post.c
> > +++ b/libsepol/cil/src/cil_post.c
> > @@ -1194,6 +1194,14 @@ static int cil_typeattribute_used(struct
> cil_typeattribute *attr, struct cil_db
> > return CIL_FALSE;
> > }
> >
> > + if (attr->used & CIL_ATTR_EXPAND_FALSE) {
> > + return CIL_TRUE;
> > + }
> > +
> > + if (attr->used & CIL_ATTR_EXPAND_TRUE) {
> > + return CIL_FALSE;
> > + }
> > +
> > if (attr->used & CIL_ATTR_CONSTRAINT) {
> > return CIL_TRUE;
> > }
> > diff --git a/libsepol/cil/src/cil_reset_ast.c
> b/libsepol/cil/src/cil_reset_ast.c
> > index de00679e..676e156e 100644
> > --- a/libsepol/cil/src/cil_reset_ast.c
> > +++ b/libsepol/cil/src/cil_reset_ast.c
> > @@ -549,6 +549,7 @@ int __cil_reset_node(struct cil_tree_node *node,
> __attribute__((unused)) uint32
> > case CIL_CLASSORDER:
> > case CIL_CATORDER:
> > case CIL_SENSITIVITYORDER:
> > + case CIL_EXPANDTYPEATTRIBUTE:
> > break; /* Nothing to reset */
> > default:
> > break;
> > diff --git a/libsepol/cil/src/cil_resolve_ast.c
> b/libsepol/cil/src/cil_resolve_ast.c
> > index 6da44ba1..8925b271 100644
> > --- a/libsepol/cil/src/cil_resolve_ast.c
> > +++ b/libsepol/cil/src/cil_resolve_ast.c
> > @@ -271,14 +271,24 @@ exit:
> >
> > int cil_type_used(struct cil_symtab_datum *datum, int used)
> > {
> > + int rc = SEPOL_ERR;
> > struct cil_typeattribute *attr = NULL;
> >
> > if (FLAVOR(datum) == CIL_TYPEATTRIBUTE) {
> > attr = (struct cil_typeattribute*)datum;
> > attr->used |= used;
> > + if ((attr->used & CIL_ATTR_EXPAND_TRUE) &&
> > + (attr->used & CIL_ATTR_EXPAND_FALSE)) {
> > + cil_log(CIL_ERR, "Conflicting use of
> expandtypeattribute. "
> > + "Expandtypeattribute may be set to
> true or false "
> > + "but not both. \n");
> > + goto exit;
> > + }
> > }
> >
> > - return 0;
> > + return SEPOL_OK;
> > +exit:
> > + return rc;
> > }
> >
> > int cil_resolve_permissionx(struct cil_tree_node *current, struct
> cil_permissionx *permx, void *extra_args)
> > @@ -453,6 +463,44 @@ exit:
> > return rc;
> > }
> >
> > +int cil_resolve_expandtypeattribute(struct cil_tree_node *current, void
> *extra_args)
> > +{
> > + struct cil_expandtypeattribute *expandattr = current->data;
> > + struct cil_symtab_datum *attr_datum = NULL;
> > + struct cil_tree_node *attr_node = NULL;
> > + struct cil_list_item *curr;
> > + int used;
> > + int rc = SEPOL_ERR;
> > +
> > + cil_list_init(&expandattr->attr_datums, CIL_TYPE);
> > +
> > + cil_list_for_each(curr, expandattr->attr_strs) {
> > + rc = cil_resolve_name(current, (char *)curr->data,
> CIL_SYM_TYPES, extra_args, &attr_datum);
> > + if (rc != SEPOL_OK) {
> > + goto exit;
> > + }
> > +
> > + attr_node = attr_datum->nodes->head->data;
> > +
> > + if (attr_node->flavor != CIL_TYPEATTRIBUTE) {
> > + rc = SEPOL_ERR;
> > + cil_log(CIL_ERR, "Attribute type not an
> attribute\n");
> > + goto exit;
> > + }
> > + used = expandattr->expand ? CIL_ATTR_EXPAND_TRUE :
> CIL_ATTR_EXPAND_FALSE;
> > + rc = cil_type_used(attr_datum, used);
> > + if (rc != SEPOL_OK) {
> > + goto exit;
> > + }
> > +
> > + cil_list_append(expandattr->attr_datums, CIL_TYPE,
> attr_datum);
> > + }
> > +
> > + return SEPOL_OK;
> > +exit:
> > + return rc;
> > +}
> > +
> > int cil_resolve_aliasactual(struct cil_tree_node *current, void
> *extra_args, enum cil_flavor flavor, enum cil_flavor alias_flavor)
> > {
> > int rc = SEPOL_ERR;
> > @@ -3432,6 +3480,9 @@ int __cil_resolve_ast_node(struct cil_tree_node
> *node, void *extra_args)
> > case CIL_TYPEATTRIBUTESET:
> > rc = cil_resolve_typeattributeset(node, args);
> > break;
> > + case CIL_EXPANDTYPEATTRIBUTE:
> > + rc = cil_resolve_expandtypeattribute(node, args);
> > + break;
> > case CIL_TYPEBOUNDS:
> > rc = cil_resolve_bounds(node, args, CIL_TYPE,
> CIL_TYPEATTRIBUTE);
> > break;
> > diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c
> > index 9ff9d4b4..2cc2744a 100644
> > --- a/libsepol/cil/src/cil_tree.c
> > +++ b/libsepol/cil/src/cil_tree.c
> > @@ -703,6 +703,17 @@ void cil_tree_print_node(struct cil_tree_node *node)
> > cil_log(CIL_INFO, "TYPE: %s\n", type->datum.name);
> > return;
> > }
> > + case CIL_EXPANDTYPEATTRIBUTE: {
> > + struct cil_expandtypeattribute *attr = node->data;
> > +
> > + fprintf(stderr, "%s %u\n", __func__, __LINE__);
> > + cil_log(CIL_INFO, "(EXPANDTYPEATTRIBUTE ");
> > + cil_tree_print_expr(attr->attr_datums,
> attr->attr_strs);
> > + cil_log(CIL_INFO, "%s)\n",attr->expand ?
> > + CIL_KEY_CONDTRUE :
> CIL_KEY_CONDFALSE);
> > +
> > + return;
> > + }
> > case CIL_TYPEATTRIBUTESET: {
> > struct cil_typeattributeset *attr = node->data;
> >
> > diff --git a/libsepol/include/sepol/policydb/policydb.h
> b/libsepol/include/sepol/policydb/policydb.h
> > index 4336a3f2..37e0c9e5 100644
> > --- a/libsepol/include/sepol/policydb/policydb.h
> > +++ b/libsepol/include/sepol/policydb/policydb.h
> > @@ -178,7 +178,11 @@ typedef struct type_datum {
> > #define TYPE_ALIAS 2 /* alias in modular policy */
> > uint32_t flavor;
> > ebitmap_t types; /* types with this attribute */
> > -#define TYPE_FLAGS_PERMISSIVE 0x01
> > +#define TYPE_FLAGS_PERMISSIVE (1 << 0)
> > +#define TYPE_FLAGS_EXPAND_ATTR_TRUE (1 << 1)
> > +#define TYPE_FLAGS_EXPAND_ATTR_FALSE (1 << 2)
> > +#define TYPE_FLAGS_EXPAND_ATTR (TYPE_FLAGS_EXPAND_ATTR_TRUE | \
> > + TYPE_FLAGS_EXPAND_ATTR_FALSE)
> > uint32_t flags;
> > uint32_t bounds; /* bounds type, if exist */
> > } type_datum_t;
> > diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
> > index ac095c30..7d8eb204 100644
> > --- a/libsepol/src/module_to_cil.c
> > +++ b/libsepol/src/module_to_cil.c
> > @@ -2244,6 +2244,17 @@ static int type_to_cil(int indent, struct
> policydb *pdb, struct avrule_block *UN
> > cil_println(indent, "(typeattribute %s)", key);
> > }
> >
> > + if (type->flags & TYPE_FLAGS_EXPAND_ATTR) {
> > + cil_indent(indent);
> > + cil_printf("(expandtypeattribute (%s) ", key);
> > + if (type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE) {
> > + cil_printf("true");
> > + } else if (type->flags &
> TYPE_FLAGS_EXPAND_ATTR_FALSE) {
> > + cil_printf("false");
> > + }
> > + cil_printf(")\n");
> > + }
> > +
> > if (ebitmap_cardinality(&type->types) > 0) {
> > cil_indent(indent);
> > cil_printf("(typeattributeset %s (", key);
> >
>
>
> --
> James Carter <[email protected]>
> National Security Agency
>