Message ID | 20241023172044.98572-1-cgoettsche@seltendoof.de (mailing list archive) |
---|---|
State | Accepted |
Commit | 438b16d17799 |
Delegated to: | Petr Lautrbach |
Headers | show |
Series | [1/3] libsepol: add support for xperms in conditional policies | expand |
On Wed, Oct 23, 2024 at 1:21 PM Christian Göttsche <cgoettsche@seltendoof.de> wrote: > > From: Christian Göttsche <cgzones@googlemail.com> > > Add support for extended permission rules in conditional policies by > adding a new policy version and adjusting writing and validating > policies accordingly. Some changes are going to be needed to the assertion checking for this. optional work as expected. boolean if's work if everything is in one branch, but problems occur if they are not. A couple of examples that fail if bb04 { allow tp41 tpx : clx ioctl; } else { allowxperm tp41 tpx : clx ioctl 0x1101; } neverallowxperm tp41 tpx : clx ioctl 0x4101; This should be an assertion failure, but is not. allow tp51 tpx : clx ioctl; if bb05 { allowxperm tp51 tpx : clx ioctl 0x1101; } else { allowxperm tp51 tpx : clx ioctl 0x1101; } neverallowxperm tp51 tpx : clx ioctl 0x4101; This should not be an assertion failure, but is. Thanks, Jim > > Signed-off-by: Christian Göttsche <cgzones@googlemail.com> > --- > libsepol/include/sepol/policydb/policydb.h | 12 +++++- > libsepol/src/policydb.c | 21 ++++++++++ > libsepol/src/policydb_validate.c | 4 +- > libsepol/src/write.c | 46 +++++++++++++++------- > 4 files changed, 64 insertions(+), 19 deletions(-) > > diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h > index f73e21fc..ccff4d71 100644 > --- a/libsepol/include/sepol/policydb/policydb.h > +++ b/libsepol/include/sepol/policydb/policydb.h > @@ -759,10 +759,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); > #define POLICYDB_VERSION_INFINIBAND 31 /* Linux-specific */ > #define POLICYDB_VERSION_GLBLUB 32 > #define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */ > +#define POLICYDB_VERSION_COND_XPERMS 34 /* extended permissions in conditional policies */ > > /* Range of policy versions we understand*/ > #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE > -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COMP_FTRANS > +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COND_XPERMS > > /* Module versions and specific changes*/ > #define MOD_POLICYDB_VERSION_BASE 4 > @@ -785,9 +786,10 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); > #define MOD_POLICYDB_VERSION_INFINIBAND 19 > #define MOD_POLICYDB_VERSION_GLBLUB 20 > #define MOD_POLICYDB_VERSION_SELF_TYPETRANS 21 > +#define MOD_POLICYDB_VERSION_COND_XPERMS 22 > > #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE > -#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_SELF_TYPETRANS > +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_COND_XPERMS > > #define POLICYDB_CONFIG_MLS 1 > > @@ -801,6 +803,12 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); > ((p)->policy_type != POLICY_KERN \ > && (p)->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY)) > > +#define policydb_has_cond_xperms_feature(p) \ > + (((p)->policy_type == POLICY_KERN \ > + && (p)->policyvers >= POLICYDB_VERSION_COND_XPERMS) || \ > + ((p)->policy_type != POLICY_KERN \ > + && (p)->policyvers >= MOD_POLICYDB_VERSION_COND_XPERMS)) > + > /* the config flags related to unknown classes/perms are bits 2 and 3 */ > #define DENY_UNKNOWN SEPOL_DENY_UNKNOWN > #define REJECT_UNKNOWN SEPOL_REJECT_UNKNOWN > diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c > index e90ccca1..0747e789 100644 > --- a/libsepol/src/policydb.c > +++ b/libsepol/src/policydb.c > @@ -208,6 +208,13 @@ static const struct policydb_compat_info policydb_compat[] = { > .ocon_num = OCON_IBENDPORT + 1, > .target_platform = SEPOL_TARGET_SELINUX, > }, > + { > + .type = POLICY_KERN, > + .version = POLICYDB_VERSION_COND_XPERMS, > + .sym_num = SYM_NUM, > + .ocon_num = OCON_IBENDPORT + 1, > + .target_platform = SEPOL_TARGET_SELINUX, > + }, > { > .type = POLICY_BASE, > .version = MOD_POLICYDB_VERSION_BASE, > @@ -334,6 +341,13 @@ static const struct policydb_compat_info policydb_compat[] = { > .ocon_num = OCON_IBENDPORT + 1, > .target_platform = SEPOL_TARGET_SELINUX, > }, > + { > + .type = POLICY_BASE, > + .version = MOD_POLICYDB_VERSION_COND_XPERMS, > + .sym_num = SYM_NUM, > + .ocon_num = OCON_IBENDPORT + 1, > + .target_platform = SEPOL_TARGET_SELINUX, > + }, > { > .type = POLICY_MOD, > .version = MOD_POLICYDB_VERSION_BASE, > @@ -460,6 +474,13 @@ static const struct policydb_compat_info policydb_compat[] = { > .ocon_num = 0, > .target_platform = SEPOL_TARGET_SELINUX, > }, > + { > + .type = POLICY_MOD, > + .version = MOD_POLICYDB_VERSION_COND_XPERMS, > + .sym_num = SYM_NUM, > + .ocon_num = 0, > + .target_platform = SEPOL_TARGET_SELINUX, > + }, > }; > > #if 0 > diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c > index 5035313b..e021e025 100644 > --- a/libsepol/src/policydb_validate.c > +++ b/libsepol/src/policydb_validate.c > @@ -903,7 +903,7 @@ static int validate_avtab_key(const avtab_key_t *key, int conditional, const pol > case AVTAB_XPERMS_DONTAUDIT: > if (p->target_platform != SEPOL_TARGET_SELINUX) > goto bad; > - if (conditional) > + if (conditional && !policydb_has_cond_xperms_feature(p)) > goto bad; > break; > default: > @@ -1046,7 +1046,7 @@ static int validate_avrules(sepol_handle_t *handle, const avrule_t *avrule, int > case AVRULE_XPERMS_AUDITALLOW: > case AVRULE_XPERMS_DONTAUDIT: > case AVRULE_XPERMS_NEVERALLOW: > - if (conditional) > + if (conditional && !policydb_has_cond_xperms_feature(p)) > goto bad; > break; > default: > diff --git a/libsepol/src/write.c b/libsepol/src/write.c > index a52e2e82..4ef98449 100644 > --- a/libsepol/src/write.c > +++ b/libsepol/src/write.c > @@ -56,7 +56,8 @@ struct policy_data { > }; > > static int avrule_write_list(policydb_t *p, > - avrule_t * avrules, struct policy_file *fp); > + avrule_t * avrules, struct policy_file *fp, > + unsigned conditional); > > static int ebitmap_write(ebitmap_t * e, struct policy_file *fp) > { > @@ -104,7 +105,8 @@ static uint16_t spec_order[] = { > > static int avtab_write_item(policydb_t * p, > avtab_ptr_t cur, struct policy_file *fp, > - unsigned merge, unsigned commit, uint32_t * nel) > + unsigned merge, unsigned commit, unsigned conditional, > + uint32_t * nel) > { > avtab_ptr_t node; > uint8_t buf8; > @@ -229,14 +231,20 @@ static int avtab_write_item(policydb_t * p, > return POLICYDB_ERROR; > if ((p->policyvers < POLICYDB_VERSION_XPERMS_IOCTL) && > (cur->key.specified & AVTAB_XPERMS)) { > - ERR(fp->handle, "policy version %u does not support ioctl extended" > + ERR(fp->handle, "policy version %u does not support extended" > "permissions rules and one was specified", p->policyvers); > return POLICYDB_ERROR; > } > > + if (!policydb_has_cond_xperms_feature(p) && (cur->key.specified & AVTAB_XPERMS) && conditional) { > + ERR(fp->handle, "policy version %u does not support extended" > + "permissions rules in conditional policies and one was specified", p->policyvers); > + return POLICYDB_ERROR; > + } > + > if (p->target_platform != SEPOL_TARGET_SELINUX && > (cur->key.specified & AVTAB_XPERMS)) { > - ERR(fp->handle, "Target platform %s does not support ioctl " > + ERR(fp->handle, "Target platform %s does not support " > "extended permissions rules and one was specified", > policydb_target_strings[p->target_platform]); > return POLICYDB_ERROR; > @@ -313,7 +321,7 @@ static int avtab_write(struct policydb *p, avtab_t * a, struct policy_file *fp) > for (cur = a->htable[i]; cur; cur = cur->next) { > /* If old format, compute final nel. > If new format, write out the items. */ > - if (avtab_write_item(p, cur, fp, 1, !oldvers, &nel)) { > + if (avtab_write_item(p, cur, fp, 1, !oldvers, 0, &nel)) { > rc = -1; > goto out; > } > @@ -332,7 +340,7 @@ static int avtab_write(struct policydb *p, avtab_t * a, struct policy_file *fp) > avtab_reset_merged(a); > for (i = 0; i < a->nslot; i++) { > for (cur = a->htable[i]; cur; cur = cur->next) { > - if (avtab_write_item(p, cur, fp, 1, 1, NULL)) { > + if (avtab_write_item(p, cur, fp, 1, 1, 0, NULL)) { > rc = -1; > goto out; > } > @@ -795,7 +803,7 @@ static int cond_write_av_list(policydb_t * p, > > for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) { > if (cur_list->node->parse_context) > - if (avtab_write_item(p, cur_list->node, fp, 0, 1, NULL)) > + if (avtab_write_item(p, cur_list->node, fp, 0, 1, 1, NULL)) > goto out; > } > > @@ -846,9 +854,9 @@ static int cond_write_node(policydb_t * p, > if (cond_write_av_list(p, node->false_list, fp) != 0) > return POLICYDB_ERROR; > } else { > - if (avrule_write_list(p, node->avtrue_list, fp)) > + if (avrule_write_list(p, node->avtrue_list, fp, 1)) > return POLICYDB_ERROR; > - if (avrule_write_list(p, node->avfalse_list, fp)) > + if (avrule_write_list(p, node->avfalse_list, fp, 1)) > return POLICYDB_ERROR; > } > > @@ -1743,7 +1751,7 @@ static int range_write(policydb_t * p, struct policy_file *fp) > /************** module writing functions below **************/ > > static int avrule_write(policydb_t *p, avrule_t * avrule, > - struct policy_file *fp) > + struct policy_file *fp, unsigned conditional) > { > size_t items, items2; > uint32_t buf[32], len; > @@ -1801,15 +1809,23 @@ static int avrule_write(policydb_t *p, avrule_t * avrule, > > if (p->policyvers < MOD_POLICYDB_VERSION_XPERMS_IOCTL) { > ERR(fp->handle, > - "module policy version %u does not support ioctl" > + "module policy version %u does not support" > " extended permissions rules and one was specified", > p->policyvers); > return POLICYDB_ERROR; > } > > + if (conditional && !policydb_has_cond_xperms_feature(p)) { > + ERR(fp->handle, > + "module policy version %u does not support" > + " extended permissions rules in conditional policies and one was specified", > + p->policyvers); > + return POLICYDB_ERROR; > + } > + > if (p->target_platform != SEPOL_TARGET_SELINUX) { > ERR(fp->handle, > - "Target platform %s does not support ioctl" > + "Target platform %s does not support" > " extended permissions rules and one was specified", > policydb_target_strings[p->target_platform]); > return POLICYDB_ERROR; > @@ -1834,7 +1850,7 @@ static int avrule_write(policydb_t *p, avrule_t * avrule, > } > > static int avrule_write_list(policydb_t *p, avrule_t * avrules, > - struct policy_file *fp) > + struct policy_file *fp, unsigned conditional) > { > uint32_t buf[32], len; > avrule_t *avrule; > @@ -1852,7 +1868,7 @@ static int avrule_write_list(policydb_t *p, avrule_t * avrules, > > avrule = avrules; > while (avrule) { > - if (avrule_write(p, avrule, fp)) > + if (avrule_write(p, avrule, fp, conditional)) > return POLICYDB_ERROR; > avrule = avrule->next; > } > @@ -2056,7 +2072,7 @@ static int avrule_decl_write(avrule_decl_t * decl, int num_scope_syms, > return POLICYDB_ERROR; > } > if (cond_write_list(p, decl->cond_list, fp) == -1 || > - avrule_write_list(p, decl->avrules, fp) == -1 || > + avrule_write_list(p, decl->avrules, fp, 0) == -1 || > role_trans_rule_write(p, decl->role_tr_rules, fp) == -1 || > role_allow_rule_write(decl->role_allow_rules, fp) == -1) { > return POLICYDB_ERROR; > -- > 2.45.2 > >
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h index f73e21fc..ccff4d71 100644 --- a/libsepol/include/sepol/policydb/policydb.h +++ b/libsepol/include/sepol/policydb/policydb.h @@ -759,10 +759,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); #define POLICYDB_VERSION_INFINIBAND 31 /* Linux-specific */ #define POLICYDB_VERSION_GLBLUB 32 #define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */ +#define POLICYDB_VERSION_COND_XPERMS 34 /* extended permissions in conditional policies */ /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COMP_FTRANS +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COND_XPERMS /* Module versions and specific changes*/ #define MOD_POLICYDB_VERSION_BASE 4 @@ -785,9 +786,10 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); #define MOD_POLICYDB_VERSION_INFINIBAND 19 #define MOD_POLICYDB_VERSION_GLBLUB 20 #define MOD_POLICYDB_VERSION_SELF_TYPETRANS 21 +#define MOD_POLICYDB_VERSION_COND_XPERMS 22 #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE -#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_SELF_TYPETRANS +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_COND_XPERMS #define POLICYDB_CONFIG_MLS 1 @@ -801,6 +803,12 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); ((p)->policy_type != POLICY_KERN \ && (p)->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY)) +#define policydb_has_cond_xperms_feature(p) \ + (((p)->policy_type == POLICY_KERN \ + && (p)->policyvers >= POLICYDB_VERSION_COND_XPERMS) || \ + ((p)->policy_type != POLICY_KERN \ + && (p)->policyvers >= MOD_POLICYDB_VERSION_COND_XPERMS)) + /* the config flags related to unknown classes/perms are bits 2 and 3 */ #define DENY_UNKNOWN SEPOL_DENY_UNKNOWN #define REJECT_UNKNOWN SEPOL_REJECT_UNKNOWN diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c index e90ccca1..0747e789 100644 --- a/libsepol/src/policydb.c +++ b/libsepol/src/policydb.c @@ -208,6 +208,13 @@ static const struct policydb_compat_info policydb_compat[] = { .ocon_num = OCON_IBENDPORT + 1, .target_platform = SEPOL_TARGET_SELINUX, }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_COND_XPERMS, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, { .type = POLICY_BASE, .version = MOD_POLICYDB_VERSION_BASE, @@ -334,6 +341,13 @@ static const struct policydb_compat_info policydb_compat[] = { .ocon_num = OCON_IBENDPORT + 1, .target_platform = SEPOL_TARGET_SELINUX, }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_COND_XPERMS, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, { .type = POLICY_MOD, .version = MOD_POLICYDB_VERSION_BASE, @@ -460,6 +474,13 @@ static const struct policydb_compat_info policydb_compat[] = { .ocon_num = 0, .target_platform = SEPOL_TARGET_SELINUX, }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_COND_XPERMS, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, }; #if 0 diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c index 5035313b..e021e025 100644 --- a/libsepol/src/policydb_validate.c +++ b/libsepol/src/policydb_validate.c @@ -903,7 +903,7 @@ static int validate_avtab_key(const avtab_key_t *key, int conditional, const pol case AVTAB_XPERMS_DONTAUDIT: if (p->target_platform != SEPOL_TARGET_SELINUX) goto bad; - if (conditional) + if (conditional && !policydb_has_cond_xperms_feature(p)) goto bad; break; default: @@ -1046,7 +1046,7 @@ static int validate_avrules(sepol_handle_t *handle, const avrule_t *avrule, int case AVRULE_XPERMS_AUDITALLOW: case AVRULE_XPERMS_DONTAUDIT: case AVRULE_XPERMS_NEVERALLOW: - if (conditional) + if (conditional && !policydb_has_cond_xperms_feature(p)) goto bad; break; default: diff --git a/libsepol/src/write.c b/libsepol/src/write.c index a52e2e82..4ef98449 100644 --- a/libsepol/src/write.c +++ b/libsepol/src/write.c @@ -56,7 +56,8 @@ struct policy_data { }; static int avrule_write_list(policydb_t *p, - avrule_t * avrules, struct policy_file *fp); + avrule_t * avrules, struct policy_file *fp, + unsigned conditional); static int ebitmap_write(ebitmap_t * e, struct policy_file *fp) { @@ -104,7 +105,8 @@ static uint16_t spec_order[] = { static int avtab_write_item(policydb_t * p, avtab_ptr_t cur, struct policy_file *fp, - unsigned merge, unsigned commit, uint32_t * nel) + unsigned merge, unsigned commit, unsigned conditional, + uint32_t * nel) { avtab_ptr_t node; uint8_t buf8; @@ -229,14 +231,20 @@ static int avtab_write_item(policydb_t * p, return POLICYDB_ERROR; if ((p->policyvers < POLICYDB_VERSION_XPERMS_IOCTL) && (cur->key.specified & AVTAB_XPERMS)) { - ERR(fp->handle, "policy version %u does not support ioctl extended" + ERR(fp->handle, "policy version %u does not support extended" "permissions rules and one was specified", p->policyvers); return POLICYDB_ERROR; } + if (!policydb_has_cond_xperms_feature(p) && (cur->key.specified & AVTAB_XPERMS) && conditional) { + ERR(fp->handle, "policy version %u does not support extended" + "permissions rules in conditional policies and one was specified", p->policyvers); + return POLICYDB_ERROR; + } + if (p->target_platform != SEPOL_TARGET_SELINUX && (cur->key.specified & AVTAB_XPERMS)) { - ERR(fp->handle, "Target platform %s does not support ioctl " + ERR(fp->handle, "Target platform %s does not support " "extended permissions rules and one was specified", policydb_target_strings[p->target_platform]); return POLICYDB_ERROR; @@ -313,7 +321,7 @@ static int avtab_write(struct policydb *p, avtab_t * a, struct policy_file *fp) for (cur = a->htable[i]; cur; cur = cur->next) { /* If old format, compute final nel. If new format, write out the items. */ - if (avtab_write_item(p, cur, fp, 1, !oldvers, &nel)) { + if (avtab_write_item(p, cur, fp, 1, !oldvers, 0, &nel)) { rc = -1; goto out; } @@ -332,7 +340,7 @@ static int avtab_write(struct policydb *p, avtab_t * a, struct policy_file *fp) avtab_reset_merged(a); for (i = 0; i < a->nslot; i++) { for (cur = a->htable[i]; cur; cur = cur->next) { - if (avtab_write_item(p, cur, fp, 1, 1, NULL)) { + if (avtab_write_item(p, cur, fp, 1, 1, 0, NULL)) { rc = -1; goto out; } @@ -795,7 +803,7 @@ static int cond_write_av_list(policydb_t * p, for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) { if (cur_list->node->parse_context) - if (avtab_write_item(p, cur_list->node, fp, 0, 1, NULL)) + if (avtab_write_item(p, cur_list->node, fp, 0, 1, 1, NULL)) goto out; } @@ -846,9 +854,9 @@ static int cond_write_node(policydb_t * p, if (cond_write_av_list(p, node->false_list, fp) != 0) return POLICYDB_ERROR; } else { - if (avrule_write_list(p, node->avtrue_list, fp)) + if (avrule_write_list(p, node->avtrue_list, fp, 1)) return POLICYDB_ERROR; - if (avrule_write_list(p, node->avfalse_list, fp)) + if (avrule_write_list(p, node->avfalse_list, fp, 1)) return POLICYDB_ERROR; } @@ -1743,7 +1751,7 @@ static int range_write(policydb_t * p, struct policy_file *fp) /************** module writing functions below **************/ static int avrule_write(policydb_t *p, avrule_t * avrule, - struct policy_file *fp) + struct policy_file *fp, unsigned conditional) { size_t items, items2; uint32_t buf[32], len; @@ -1801,15 +1809,23 @@ static int avrule_write(policydb_t *p, avrule_t * avrule, if (p->policyvers < MOD_POLICYDB_VERSION_XPERMS_IOCTL) { ERR(fp->handle, - "module policy version %u does not support ioctl" + "module policy version %u does not support" " extended permissions rules and one was specified", p->policyvers); return POLICYDB_ERROR; } + if (conditional && !policydb_has_cond_xperms_feature(p)) { + ERR(fp->handle, + "module policy version %u does not support" + " extended permissions rules in conditional policies and one was specified", + p->policyvers); + return POLICYDB_ERROR; + } + if (p->target_platform != SEPOL_TARGET_SELINUX) { ERR(fp->handle, - "Target platform %s does not support ioctl" + "Target platform %s does not support" " extended permissions rules and one was specified", policydb_target_strings[p->target_platform]); return POLICYDB_ERROR; @@ -1834,7 +1850,7 @@ static int avrule_write(policydb_t *p, avrule_t * avrule, } static int avrule_write_list(policydb_t *p, avrule_t * avrules, - struct policy_file *fp) + struct policy_file *fp, unsigned conditional) { uint32_t buf[32], len; avrule_t *avrule; @@ -1852,7 +1868,7 @@ static int avrule_write_list(policydb_t *p, avrule_t * avrules, avrule = avrules; while (avrule) { - if (avrule_write(p, avrule, fp)) + if (avrule_write(p, avrule, fp, conditional)) return POLICYDB_ERROR; avrule = avrule->next; } @@ -2056,7 +2072,7 @@ static int avrule_decl_write(avrule_decl_t * decl, int num_scope_syms, return POLICYDB_ERROR; } if (cond_write_list(p, decl->cond_list, fp) == -1 || - avrule_write_list(p, decl->avrules, fp) == -1 || + avrule_write_list(p, decl->avrules, fp, 0) == -1 || role_trans_rule_write(p, decl->role_tr_rules, fp) == -1 || role_allow_rule_write(decl->role_allow_rules, fp) == -1) { return POLICYDB_ERROR;