On 06/12/2015 12:01 PM, Jeff Vander Stoep wrote: > The ioctl operations code is being renamed to the more generic > "extended permissions." This commit brings the policy compiler > up to date with the kernel patch. > > Signed-off-by: Jeff Vander Stoep <jeffv@xxxxxxxxxx> Thanks, applied. > --- > checkpolicy/policy_define.c | 343 +++++++++++++++-------------- > checkpolicy/policy_define.h | 2 +- > checkpolicy/policy_parse.y | 43 ++-- > checkpolicy/policy_scan.l | 6 + > checkpolicy/test/dispol.c | 47 ++-- > libsepol/include/sepol/policydb/avtab.h | 26 +-- > libsepol/include/sepol/policydb/policydb.h | 33 ++- > libsepol/src/avtab.c | 54 ++--- > libsepol/src/expand.c | 102 ++++----- > libsepol/src/policydb.c | 2 +- > libsepol/src/write.c | 30 +-- > 11 files changed, 363 insertions(+), 325 deletions(-) > > diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c > index 093bded..8c01739 100644 > --- a/checkpolicy/policy_define.c > +++ b/checkpolicy/policy_define.c > @@ -1728,32 +1728,31 @@ avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl) > return sl; > } > > -#define operation_perm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f))) > -#define operation_perm_set(x, p) (p[x >> 5] |= (1 << (x & 0x1f))) > -#define operation_perm_clear(x, p) (p[x >> 5] &= ~(1 << (x & 0x1f))) > +#define xperm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f))) > +#define xperm_set(x, p) (p[x >> 5] |= (1 << (x & 0x1f))) > +#define xperm_clear(x, p) (p[x >> 5] &= ~(1 << (x & 0x1f))) > > -typedef struct av_operations_range { > +typedef struct av_ioctl_range { > uint16_t low; > uint16_t high; > -} av_operations_range_t; > +} av_ioctl_range_t; > > -struct av_operations_range_list { > +struct av_ioctl_range_list { > uint8_t omit; > - av_operations_range_t range; > - struct av_operations_range_list *next; > + av_ioctl_range_t range; > + struct av_ioctl_range_list *next; > }; > > -int avrule_sort_operations( > - struct av_operations_range_list **rangehead) > +int avrule_sort_ioctls(struct av_ioctl_range_list **rangehead) > { > - struct av_operations_range_list *r, *r2, *sorted, *sortedhead = NULL; > + struct av_ioctl_range_list *r, *r2, *sorted, *sortedhead = NULL; > > /* order list by range.low */ > for (r = *rangehead; r != NULL; r = r->next) { > - sorted = malloc(sizeof(struct av_operations_range_list)); > + sorted = malloc(sizeof(struct av_ioctl_range_list)); > if (sorted == NULL) > goto error; > - memcpy(sorted, r, sizeof(struct av_operations_range_list)); > + memcpy(sorted, r, sizeof(struct av_ioctl_range_list)); > sorted->next = NULL; > if (sortedhead == NULL) { > sortedhead = sorted; > @@ -1792,9 +1791,9 @@ error: > return -1; > } > > -int avrule_merge_operations(struct av_operations_range_list **rangehead) > +int avrule_merge_ioctls(struct av_ioctl_range_list **rangehead) > { > - struct av_operations_range_list *r, *tmp; > + struct av_ioctl_range_list *r, *tmp; > r = *rangehead; > while (r != NULL && r->next != NULL) { > /* merge */ > @@ -1812,14 +1811,14 @@ int avrule_merge_operations(struct av_operations_range_list **rangehead) > return 0; > } > > -int avrule_read_operations(struct av_operations_range_list **rangehead) > +int avrule_read_ioctls(struct av_ioctl_range_list **rangehead) > { > char *id; > - struct av_operations_range_list *rnew, *r = NULL; > + struct av_ioctl_range_list *rnew, *r = NULL; > *rangehead = NULL; > uint8_t omit = 0; > > - /* read in all the operations */ > + /* read in all the ioctl commands */ > while ((id = queue_remove(id_queue))) { > if (strcmp(id,"~") == 0) { > /* these are values to be omitted */ > @@ -1837,7 +1836,7 @@ int avrule_read_operations(struct av_operations_range_list **rangehead) > free(id); > } else { > /* read in new low value */ > - rnew = malloc(sizeof(struct av_operations_range_list)); > + rnew = malloc(sizeof(struct av_ioctl_range_list)); > if (rnew == NULL) > goto error; > rnew->next = NULL; > @@ -1862,11 +1861,11 @@ error: > } > > /* flip to included ranges */ > -int avrule_omit_operations(struct av_operations_range_list **rangehead) > +int avrule_omit_ioctls(struct av_ioctl_range_list **rangehead) > { > - struct av_operations_range_list *rnew, *r, *newhead, *r2; > + struct av_ioctl_range_list *rnew, *r, *newhead, *r2; > > - rnew = calloc(1, sizeof(struct av_operations_range_list)); > + rnew = calloc(1, sizeof(struct av_ioctl_range_list)); > if (!rnew) > goto error; > > @@ -1884,7 +1883,7 @@ int avrule_omit_operations(struct av_operations_range_list **rangehead) > > while (r) { > r2->range.high = r->range.low - 1; > - rnew = calloc(1, sizeof(struct av_operations_range_list)); > + rnew = calloc(1, sizeof(struct av_ioctl_range_list)); > if (!rnew) > goto error; > r2->next = rnew; > @@ -1910,27 +1909,27 @@ error: > return -1; > } > > -int avrule_operation_ranges(struct av_operations_range_list **rangelist) > +int avrule_ioctl_ranges(struct av_ioctl_range_list **rangelist) > { > - struct av_operations_range_list *rangehead; > + struct av_ioctl_range_list *rangehead; > uint8_t omit; > > /* read in ranges to include and omit */ > - if (avrule_read_operations(&rangehead)) > + if (avrule_read_ioctls(&rangehead)) > return -1; > omit = rangehead->omit; > if (rangehead == NULL) { > - yyerror("error processing ioctl operations"); > + yyerror("error processing ioctl commands"); > return -1; > } > - /* sort and merge the input operations */ > - if (avrule_sort_operations(&rangehead)) > + /* sort and merge the input ioctls */ > + if (avrule_sort_ioctls(&rangehead)) > return -1; > - if (avrule_merge_operations(&rangehead)) > + if (avrule_merge_ioctls(&rangehead)) > return -1; > /* flip ranges if these are ommited*/ > if (omit) { > - if (avrule_omit_operations(&rangehead)) > + if (avrule_omit_ioctls(&rangehead)) > return -1; > } > > @@ -1938,7 +1937,7 @@ int avrule_operation_ranges(struct av_operations_range_list **rangelist) > return 0; > } > > -int define_te_avtab_operation_helper(int which, avrule_t ** rule) > +int define_te_avtab_xperms_helper(int which, avrule_t ** rule) > { > char *id; > class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL; > @@ -1959,7 +1958,7 @@ int define_te_avtab_operation_helper(int which, avrule_t ** rule) > avrule->line = policydb_lineno; > avrule->source_line = source_lineno; > avrule->source_filename = strdup(source_file); > - avrule->ops = NULL; > + avrule->xperms = NULL; > if (!avrule->source_filename) { > yyerror("out of memory"); > return -1; > @@ -2023,95 +2022,102 @@ out: > } > > /* index of the u32 containing the permission */ > -#define OP_IDX(x) (x >> 5) > +#define XPERM_IDX(x) (x >> 5) > /* set bits 0 through x-1 within the u32 */ > -#define OP_SETBITS(x) ((1 << (x & 0x1f)) - 1) > +#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1) > /* low value for this u32 */ > -#define OP_LOW(x) (x << 5) > +#define XPERM_LOW(x) (x << 5) > /* high value for this u32 */ > -#define OP_HIGH(x) (((x + 1) << 5) - 1) > -void avrule_operation_setrangebits(uint16_t low, uint16_t high, av_operations_t *ops) > +#define XPERM_HIGH(x) (((x + 1) << 5) - 1) > +void avrule_xperm_setrangebits(uint16_t low, uint16_t high, > + av_extended_perms_t *xperms) > { > unsigned int i; > uint16_t h = high + 1; > - /* for each u32 that this low-high range touches, set type permissions */ > - for (i = OP_IDX(low); i <= OP_IDX(high); i++) { > + /* for each u32 that this low-high range touches, set driver permissions */ > + for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) { > /* set all bits in u32 */ > - if ((low <= OP_LOW(i)) && (high >= OP_HIGH(i))) > - ops->perms[i] |= ~0U; > + if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i))) > + xperms->perms[i] |= ~0U; > /* set low bits */ > - else if ((low <= OP_LOW(i)) && (high < OP_HIGH(i))) > - ops->perms[i] |= OP_SETBITS(h); > + else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i))) > + xperms->perms[i] |= XPERM_SETBITS(h); > /* set high bits */ > - else if ((low > OP_LOW(i)) && (high >= OP_HIGH(i))) > - ops->perms[i] |= ~0U - OP_SETBITS(low); > + else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i))) > + xperms->perms[i] |= ~0U - XPERM_SETBITS(low); > /* set middle bits */ > - else if ((low > OP_LOW(i)) && (high <= OP_HIGH(i))) > - ops->perms[i] |= OP_SETBITS(h) - OP_SETBITS(low); > + else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i))) > + xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low); > } > } > > -int avrule_operation_used(av_operations_t *ops) > +int avrule_xperms_used(av_extended_perms_t *xperms) > { > unsigned int i; > > - for (i = 0; i < sizeof(ops->perms)/sizeof(ops->perms[0]); i++) { > - if (ops->perms[i]) > + for (i = 0; i < sizeof(xperms->perms)/sizeof(xperms->perms[0]); i++) { > + if (xperms->perms[i]) > return 1; > } > return 0; > } > > -#define OP_TYPE(x) (x >> 8) > -#define OP_NUM(x) (x & 0xff) > -#define OP_CMD(type, num) ((type << 8) + num) > -int avrule_operation_partialtype(struct av_operations_range_list *rangelist, > - av_operations_t *complete_type, > - av_operations_t **operations) > +/* > + * using definitions found in kernel document ioctl-number.txt > + * The kernel components of an ioctl command are: > + * dir, size, driver, and fucntion. Only the driver and function fields > + * are considered here > + */ > +#define IOC_DRIV(x) (x >> 8) > +#define IOC_FUNC(x) (x & 0xff) > +#define IOC_CMD(driver, func) ((driver << 8) + func) > +int avrule_ioctl_partialdriver(struct av_ioctl_range_list *rangelist, > + av_extended_perms_t *complete_driver, > + av_extended_perms_t **extended_perms) > { > - struct av_operations_range_list *r; > - av_operations_t *ops; > + struct av_ioctl_range_list *r; > + av_extended_perms_t *xperms; > uint8_t low, high; > > - ops = calloc(1, sizeof(av_operations_t)); > - if (!ops) { > + xperms = calloc(1, sizeof(av_extended_perms_t)); > + if (!xperms) { > yyerror("out of memory"); > return - 1; > } > > r = rangelist; > while(r) { > - low = OP_TYPE(r->range.low); > - high = OP_TYPE(r->range.high); > - if (complete_type) { > - if (!operation_perm_test(low, complete_type->perms)) > - operation_perm_set(low, ops->perms); > - if (!operation_perm_test(high, complete_type->perms)) > - operation_perm_set(high, ops->perms); > + low = IOC_DRIV(r->range.low); > + high = IOC_DRIV(r->range.high); > + if (complete_driver) { > + if (!xperm_test(low, complete_driver->perms)) > + xperm_set(low, xperms->perms); > + if (!xperm_test(high, complete_driver->perms)) > + xperm_set(high, xperms->perms); > } else { > - operation_perm_set(low, ops->perms); > - operation_perm_set(high, ops->perms); > + xperm_set(low, xperms->perms); > + xperm_set(high, xperms->perms); > } > r = r->next; > } > - if (avrule_operation_used(ops)) { > - *operations = ops; > + if (avrule_xperms_used(xperms)) { > + *extended_perms = xperms; > } else { > - free(ops); > - *operations = NULL; > + free(xperms); > + *extended_perms = NULL; > } > return 0; > > } > > -int avrule_operation_completetype(struct av_operations_range_list *rangelist, > - av_operations_t **operations) > +int avrule_ioctl_completedriver(struct av_ioctl_range_list *rangelist, > + av_extended_perms_t **extended_perms) > { > - struct av_operations_range_list *r; > - av_operations_t *ops; > + struct av_ioctl_range_list *r; > + av_extended_perms_t *xperms; > uint16_t low, high; > - ops = calloc(1, sizeof(av_operations_t)); > - if (!ops) { > + xperms = calloc(1, sizeof(av_extended_perms_t)); > + if (!xperms) { > yyerror("out of memory"); > return - 1; > } > @@ -2119,83 +2125,86 @@ int avrule_operation_completetype(struct av_operations_range_list *rangelist, > r = rangelist; > while(r) { > /* > - * Any type that has numbers 0x00 - 0xff is a complete type, > + * Any driver code that has sequence 0x00 - 0xff is a complete code, > * > - * if command number = 0xff, then round high up to next type, > - * else 0x00 - 0xfe keep current type > + * if command number = 0xff, then round high up to next code, > + * else 0x00 - 0xfe keep current code > * of this range. temporarily u32 for the + 1 > * to account for possible rollover before right shift > */ > - high = OP_TYPE((uint32_t) (r->range.high + 1)); > - /* if 0x00 keep current type else 0x01 - 0xff round up to next type */ > - low = OP_TYPE(r->range.low); > - if (OP_NUM(r->range.low)) > + high = IOC_DRIV((uint32_t) (r->range.high + 1)); > + /* if 0x00 keep current driver code else 0x01 - 0xff round up to next code*/ > + low = IOC_DRIV(r->range.low); > + if (IOC_FUNC(r->range.low)) > low++; > if (high > low) > - avrule_operation_setrangebits(low, high - 1, ops); > + avrule_xperm_setrangebits(low, high - 1, xperms); > r = r->next; > } > - if (avrule_operation_used(ops)) { > - *operations = ops; > + if (avrule_xperms_used(xperms)) { > + xperms->driver = 0x00; > + xperms->specified = AVRULE_XPERMS_IOCTLDRIVER; > + *extended_perms = xperms; > } else { > - free(ops); > - *operations = NULL; > + free(xperms); > + *extended_perms = NULL; > } > return 0; > } > > -int avrule_operation_num(struct av_operations_range_list *rangelist, > - av_operations_t **operations, unsigned int type) > +int avrule_ioctl_func(struct av_ioctl_range_list *rangelist, > + av_extended_perms_t **extended_perms, unsigned int driver) > { > - struct av_operations_range_list *r; > - av_operations_t *ops; > + struct av_ioctl_range_list *r; > + av_extended_perms_t *xperms; > uint16_t low, high; > > - *operations = NULL; > - ops = calloc(1, sizeof(av_operations_t)); > - if (!ops) { > + *extended_perms = NULL; > + xperms = calloc(1, sizeof(av_extended_perms_t)); > + if (!xperms) { > yyerror("out of memory"); > return - 1; > } > > r = rangelist; > - /* for the passed in types, find the ranges that apply */ > + /* for the passed in driver code, find the ranges that apply */ > while (r) { > low = r->range.low; > high = r->range.high; > - if ((type != OP_TYPE(low)) && (type != OP_TYPE(high))) { > + if ((driver != IOC_DRIV(low)) && (driver != IOC_DRIV(high))) { > r = r->next; > continue; > } > > - if (type == OP_TYPE(low)) { > - if (high > OP_CMD(type, 0xff)) > - high = OP_CMD(type, 0xff); > + if (driver == IOC_DRIV(low)) { > + if (high > IOC_CMD(driver, 0xff)) > + high = IOC_CMD(driver, 0xff); > > } else { > - if (low < OP_CMD(type, 0)) > - low = OP_CMD(type, 0); > + if (low < IOC_CMD(driver, 0)) > + low = IOC_CMD(driver, 0); > } > > - low = OP_NUM(low); > - high = OP_NUM(high); > - avrule_operation_setrangebits(low, high, ops); > - ops->type = type; > + low = IOC_FUNC(low); > + high = IOC_FUNC(high); > + avrule_xperm_setrangebits(low, high, xperms); > + xperms->driver = driver; > + xperms->specified = AVRULE_XPERMS_IOCTLFUNCTION; > r = r->next; > } > > - if (avrule_operation_used(ops)) { > - *operations = ops; > + if (avrule_xperms_used(xperms)) { > + *extended_perms = xperms; > } else { > - free(ops); > - *operations = NULL; > + free(xperms); > + *extended_perms = NULL; > } > return 0; > } > > -void avrule_operation_freeranges(struct av_operations_range_list *rangelist) > +void avrule_ioctl_freeranges(struct av_ioctl_range_list *rangelist) > { > - struct av_operations_range_list *r, *tmp; > + struct av_ioctl_range_list *r, *tmp; > r = rangelist; > while (r) { > tmp = r; > @@ -2204,12 +2213,12 @@ void avrule_operation_freeranges(struct av_operations_range_list *rangelist) > } > } > > -unsigned int operation_for_each_bit(unsigned int *bit, av_operations_t *ops) > +unsigned int xperms_for_each_bit(unsigned int *bit, av_extended_perms_t *xperms) > { > unsigned int i; > - for (i = *bit; i < sizeof(ops->perms)*8; i++) { > - if (operation_perm_test(i,ops->perms)) { > - operation_perm_clear(i, ops->perms); > + for (i = *bit; i < sizeof(xperms->perms)*8; i++) { > + if (xperm_test(i,xperms->perms)) { > + xperm_clear(i, xperms->perms); > *bit = i; > return 1; > } > @@ -2261,35 +2270,22 @@ int avrule_cpy(avrule_t *dest, avrule_t *src) > return 0; > } > > -int define_te_avtab_operation(int which) > +int define_te_avtab_ioctl(avrule_t *avrule_template) > { > - char *id; > - avrule_t *avrule_template; > avrule_t *avrule; > - struct av_operations_range_list *rangelist; > - av_operations_t *complete_type, *partial_type, *ops; > + struct av_ioctl_range_list *rangelist; > + av_extended_perms_t *complete_driver, *partial_driver, *xperms; > unsigned int i; > > - if (pass == 1) { > - for (i = 0; i < 4; i++) { > - while ((id = queue_remove(id_queue))) > - free(id); > - } > - return 0; > - } > - > - /* populate avrule template with source/target/tclass */ > - if (define_te_avtab_operation_helper(which, &avrule_template)) > - return -1; > > - /* organize operation ranges */ > - if (avrule_operation_ranges(&rangelist)) > + /* organize ioctl ranges */ > + if (avrule_ioctl_ranges(&rangelist)) > return -1; > > - /* create rule for ioctl operation types that are entirely enabled */ > - if (avrule_operation_completetype(rangelist, &complete_type)) > + /* create rule for ioctl driver types that are entirely enabled */ > + if (avrule_ioctl_completedriver(rangelist, &complete_driver)) > return -1; > - if (complete_type) { > + if (complete_driver) { > avrule = (avrule_t *) calloc(1, sizeof(avrule_t)); > if (!avrule) { > yyerror("out of memory"); > @@ -2297,31 +2293,28 @@ int define_te_avtab_operation(int which) > } > if (avrule_cpy(avrule, avrule_template)) > return -1; > - avrule->ops = complete_type; > - if (which == AVRULE_OPNUM_ALLOWED) > - avrule->specified = AVRULE_OPTYPE_ALLOWED; > - else if (which == AVRULE_OPNUM_AUDITALLOW) > - avrule->specified = AVRULE_OPTYPE_AUDITALLOW; > - else if (which == AVRULE_OPNUM_DONTAUDIT) > - avrule->specified = AVRULE_OPTYPE_DONTAUDIT; > - > + avrule->xperms = complete_driver; > append_avrule(avrule); > } > > - /* flag ioctl types that are partially enabled */ > - if (avrule_operation_partialtype(rangelist, complete_type, &partial_type)) > + /* flag ioctl driver codes that are partially enabled */ > + if (avrule_ioctl_partialdriver(rangelist, complete_driver, &partial_driver)) > return -1; > > - if (!partial_type || !avrule_operation_used(partial_type)) > + if (!partial_driver || !avrule_xperms_used(partial_driver)) > goto done; > > - /* create rule for each partially enabled type */ > + /* > + * create rule for each partially used driver codes > + * "partially used" meaning that the code number e.g. socket 0x89 > + * has some permission bits set and others not set. > + */ > i = 0; > - while (operation_for_each_bit(&i, partial_type)) { > - if (avrule_operation_num(rangelist, &ops, i)) > + while (xperms_for_each_bit(&i, partial_driver)) { > + if (avrule_ioctl_func(rangelist, &xperms, i)) > return -1; > > - if (ops) { > + if (xperms) { > avrule = (avrule_t *) calloc(1, sizeof(avrule_t)); > if (!avrule) { > yyerror("out of memory"); > @@ -2329,15 +2322,45 @@ int define_te_avtab_operation(int which) > } > if (avrule_cpy(avrule, avrule_template)) > return -1; > - avrule->ops = ops; > + avrule->xperms = xperms; > append_avrule(avrule); > } > } > > done: > - if (partial_type) > - free(partial_type); > + if (partial_driver) > + free(partial_driver); > + > + return 0; > +} > + > +int define_te_avtab_extended_perms(int which) > +{ > + char *id; > + unsigned int i; > + avrule_t *avrule_template; > + > + if (pass == 1) { > + for (i = 0; i < 4; i++) { > + while ((id = queue_remove(id_queue))) > + free(id); > + } > + return 0; > + } > > + /* populate avrule template with source/target/tclass */ > + if (define_te_avtab_xperms_helper(which, &avrule_template)) > + return -1; > + > + id = queue_remove(id_queue); > + if (strcmp(id,"ioctl") == 0) { > + if (define_te_avtab_ioctl(avrule_template)) > + return -1; > + free(id); > + } else { > + yyerror("only ioctl extended permissions are supported"); > + return -1; > + } > return 0; > } > > @@ -2365,7 +2388,7 @@ int define_te_avtab_helper(int which, avrule_t ** rule) > avrule->line = policydb_lineno; > avrule->source_line = source_lineno; > avrule->source_filename = strdup(source_file); > - avrule->ops = NULL; > + avrule->xperms = NULL; > if (!avrule->source_filename) { > yyerror("out of memory"); > return -1; > diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h > index 43c7c08..964baae 100644 > --- a/checkpolicy/policy_define.h > +++ b/checkpolicy/policy_define.h > @@ -58,7 +58,7 @@ int define_roleattribute(void); > int define_filename_trans(void); > int define_sens(void); > int define_te_avtab(int which); > -int define_te_avtab_operation(int which); > +int define_te_avtab_extended_perms(int which); > int define_typealias(void); > int define_typeattribute(void); > int define_typebounds(void); > diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y > index 059b7b8..d8b8ac0 100644 > --- a/checkpolicy/policy_parse.y > +++ b/checkpolicy/policy_parse.y > @@ -126,6 +126,9 @@ typedef int (* require_func_t)(int pass); > %token AUDITALLOW > %token AUDITDENY > %token DONTAUDIT > +%token ALLOWXPERM > +%token AUDITALLOWXPERM > +%token DONTAUDITXPERM > %token SOURCE > %token TARGET > %token SAMEUSER > @@ -457,9 +460,9 @@ te_avtab_def : allow_def > | auditdeny_def > | dontaudit_def > | neverallow_def > - | operation_allow_def > - | operation_auditallow_def > - | operation_dontaudit_def > + | xperm_allow_def > + | xperm_auditallow_def > + | xperm_dontaudit_def > ; > allow_def : ALLOW names names ':' names names ';' > {if (define_te_avtab(AVRULE_ALLOWED)) return -1; } > @@ -476,14 +479,14 @@ dontaudit_def : DONTAUDIT names names ':' names names ';' > neverallow_def : NEVERALLOW names names ':' names names ';' > {if (define_te_avtab(AVRULE_NEVERALLOW)) return -1; } > ; > -operation_allow_def : ALLOW names names ':' names operations ';' > - {if (define_te_avtab_operation(AVRULE_OPNUM_ALLOWED)) return -1; } > +xperm_allow_def : ALLOWXPERM names names ':' names identifier xperms ';' > + {if (define_te_avtab_extended_perms(AVRULE_XPERMS_ALLOWED)) return -1; } > ; > -operation_auditallow_def: AUDITALLOW names names ':' names operations ';' > - {if (define_te_avtab_operation(AVRULE_OPNUM_AUDITALLOW)) return -1; } > +xperm_auditallow_def : AUDITALLOWXPERM names names ':' names identifier xperms ';' > + {if (define_te_avtab_extended_perms(AVRULE_XPERMS_AUDITALLOW)) return -1; } > ; > -operation_dontaudit_def : DONTAUDIT names names ':' names operations ';' > - {if (define_te_avtab_operation(AVRULE_OPNUM_DONTAUDIT)) return -1; } > +xperm_dontaudit_def : DONTAUDITXPERM names names ':' names identifier xperms ';' > + {if (define_te_avtab_extended_perms(AVRULE_XPERMS_DONTAUDIT)) return -1; } > ; > attribute_role_def : ATTRIBUTE_ROLE identifier ';' > {if (define_attrib_role()) return -1; } > @@ -749,26 +752,26 @@ genfs_context_def : GENFSCON filesystem path '-' identifier security_context_def > ipv4_addr_def : IPV4_ADDR > { if (insert_id(yytext,0)) return -1; } > ; > -operations : operation > +xperms : xperm > { if (insert_separator(0)) return -1; } > - | nested_operation_set > + | nested_xperm_set > { if (insert_separator(0)) return -1; } > - | tilde operation > + | tilde xperm > { if (insert_id("~", 0)) return -1; } > - | tilde nested_operation_set > + | tilde nested_xperm_set > { if (insert_id("~", 0)) return -1; > if (insert_separator(0)) return -1; } > ; > -nested_operation_set : '{' nested_operation_list '}' > +nested_xperm_set : '{' nested_xperm_list '}' > ; > -nested_operation_list : nested_operation_element > - | nested_operation_list nested_operation_element > +nested_xperm_list : nested_xperm_element > + | nested_xperm_list nested_xperm_element > ; > -nested_operation_element: operation '-' { if (insert_id("-", 0)) return -1; } operation > - | operation > - | nested_operation_set > +nested_xperm_element: xperm '-' { if (insert_id("-", 0)) return -1; } xperm > + | xperm > + | nested_xperm_set > ; > -operation : number > +xperm : number > { if (insert_id(yytext,0)) return -1; } > ; > security_context_def : identifier ':' identifier ':' identifier opt_mls_range_def > diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l > index 108edbc..e94a917 100644 > --- a/checkpolicy/policy_scan.l > +++ b/checkpolicy/policy_scan.l > @@ -142,6 +142,12 @@ AUDITDENY | > auditdeny { return(AUDITDENY); } > DONTAUDIT | > dontaudit { return(DONTAUDIT); } > +ALLOWXPERM | > +allowxperm { return(ALLOWXPERM); } > +AUDITALLOWXPERM | > +auditallowxperm { return(AUDITALLOWXPERM); } > +DONTAUDITXPERM | > +dontauditxperm { return(DONTAUDITXPERM); } > SOURCE | > source { return(SOURCE); } > TARGET | > diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c > index 157361a..0c6b8d8 100644 > --- a/checkpolicy/test/dispol.c > +++ b/checkpolicy/test/dispol.c > @@ -54,11 +54,11 @@ int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p, > return 0; > } > > -#define operation_perm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f))) > +#define xperms_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f))) > #define next_bit_in_range(i, p) \ > - ((i + 1 < sizeof(p)*8) && operation_perm_test((i + 1), p)) > + ((i + 1 < sizeof(p)*8) && xperms_test((i + 1), p)) > > -int render_operations(avtab_operations_t *ops, avtab_key_t * key, FILE * fp) > +int render_ioctl(avtab_extended_perms_t * xperms, FILE * fp) > { > uint16_t value; > uint16_t low_bit; > @@ -67,28 +67,28 @@ int render_operations(avtab_operations_t *ops, avtab_key_t * key, FILE * fp) > unsigned int in_range = 0; > > fprintf(fp, "{ "); > - for (bit = 0; bit < sizeof(ops->perms)*8; bit++) { > - if (!operation_perm_test(bit, ops->perms)) > + for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) { > + if (!xperms_test(bit, xperms->perms)) > continue; > > - if (in_range && next_bit_in_range(bit, ops->perms)) { > + if (in_range && next_bit_in_range(bit, xperms->perms)) { > /* continue until high value found */ > continue; > - } else if (next_bit_in_range(bit, ops->perms)) { > + } else if (next_bit_in_range(bit, xperms->perms)) { > /* low value */ > low_bit = bit; > in_range = 1; > continue; > } > > - if (key->specified & AVTAB_OPNUM) { > - value = ops->type<<8 | bit; > - low_value = ops->type<<8 | low_bit; > + if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) { > + value = xperms->driver<<8 | bit; > + low_value = xperms->driver<<8 | low_bit; > if (in_range) > fprintf(fp, "0x%hx-0x%hx ", low_value, value); > else > fprintf(fp, "0x%hx ", value); > - } else if (key->specified & AVTAB_OPTYPE) { > + } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) { > value = bit << 8; > low_value = low_bit << 8; > if (in_range) > @@ -104,6 +104,15 @@ int render_operations(avtab_operations_t *ops, avtab_key_t * key, FILE * fp) > return 0; > } > > +int render_xperms(avtab_extended_perms_t * xperms, FILE * fp) > +{ > + if ((xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) || > + (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER)) > + render_ioctl(xperms, fp); > + > + return 0; > +} > + > int render_type(uint32_t type, policydb_t * p, FILE * fp) > { > fprintf(fp, "%s", p->p_type_val_to_name[type - 1]); > @@ -197,15 +206,15 @@ int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t what, > render_type(datum->data, p, fp); > fprintf(fp, ";\n"); > } > - } else if (key->specified & AVTAB_OP) { > - if (key->specified & (AVTAB_OPNUM_ALLOWED|AVTAB_OPTYPE_ALLOWED)) > - fprintf(fp, "allow "); > - else if (key->specified & (AVTAB_OPNUM_AUDITALLOW|AVTAB_OPTYPE_AUDITALLOW)) > - fprintf(fp, "auditallow "); > - else if (key->specified & (AVTAB_OPNUM_DONTAUDIT|AVTAB_OPTYPE_DONTAUDIT)) > - fprintf(fp, "dontaudit "); > + } else if (key->specified & AVTAB_XPERMS) { > + if (key->specified & AVTAB_XPERMS_ALLOWED) > + fprintf(fp, "allowxperm "); > + else if (key->specified & AVTAB_XPERMS_AUDITALLOW) > + fprintf(fp, "auditallowxperm "); > + else if (key->specified & AVTAB_XPERMS_DONTAUDIT) > + fprintf(fp, "dontauditxperm "); > render_key(key, p, fp); > - render_operations(datum->ops, key, fp); > + render_xperms(datum->xperms, fp); > fprintf(fp, ";\n"); > } else { > fprintf(fp, " ERROR: no valid rule type specified\n"); > diff --git a/libsepol/include/sepol/policydb/avtab.h b/libsepol/include/sepol/policydb/avtab.h > index 2ea821c..14bc082 100644 > --- a/libsepol/include/sepol/policydb/avtab.h > +++ b/libsepol/include/sepol/policydb/avtab.h > @@ -59,28 +59,28 @@ typedef struct avtab_key { > #define AVTAB_MEMBER 0x0020 > #define AVTAB_CHANGE 0x0040 > #define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) > -#define AVTAB_OPNUM_ALLOWED 0x0100 > -#define AVTAB_OPNUM_AUDITALLOW 0x0200 > -#define AVTAB_OPNUM_DONTAUDIT 0x0400 > -#define AVTAB_OPNUM (AVTAB_OPNUM_ALLOWED | AVTAB_OPNUM_AUDITALLOW | AVTAB_OPNUM_DONTAUDIT) > -#define AVTAB_OPTYPE_ALLOWED 0x1000 > -#define AVTAB_OPTYPE_AUDITALLOW 0x2000 > -#define AVTAB_OPTYPE_DONTAUDIT 0x4000 > -#define AVTAB_OPTYPE (AVTAB_OPTYPE_ALLOWED | AVTAB_OPTYPE_AUDITALLOW | AVTAB_OPTYPE_DONTAUDIT) > -#define AVTAB_OP (AVTAB_OPNUM | AVTAB_OPTYPE) > +#define AVTAB_XPERMS_ALLOWED 0x0100 > +#define AVTAB_XPERMS_AUDITALLOW 0x0200 > +#define AVTAB_XPERMS_DONTAUDIT 0x0400 > +#define AVTAB_XPERMS (AVTAB_XPERMS_ALLOWED | AVTAB_XPERMS_AUDITALLOW | AVTAB_XPERMS_DONTAUDIT) > #define AVTAB_ENABLED_OLD 0x80000000 > #define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ > uint16_t specified; /* what fields are specified */ > } avtab_key_t; > > -typedef struct avtab_operations { > - uint8_t type; > +typedef struct avtab_extended_perms { > + > +#define AVTAB_XPERMS_IOCTLFUNCTION 0x01 > +#define AVTAB_XPERMS_IOCTLDRIVER 0x02 > + /* extension of the avtab_key specified */ > + uint8_t specified; > + uint8_t driver; > uint32_t perms[8]; > -} avtab_operations_t; > +} avtab_extended_perms_t; > > typedef struct avtab_datum { > uint32_t data; /* access vector or type */ > - avtab_operations_t *ops; > + avtab_extended_perms_t *xperms; > } avtab_datum_t; > > typedef struct avtab_node *avtab_ptr_t; > diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h > index 1d8310c..78b09c4 100644 > --- a/libsepol/include/sepol/policydb/policydb.h > +++ b/libsepol/include/sepol/policydb/policydb.h > @@ -241,11 +241,14 @@ typedef struct class_perm_node { > struct class_perm_node *next; > } class_perm_node_t; > > -typedef struct av_operations { > - uint8_t type; > - /* 256 bits of ioctl number permissions */ > +typedef struct av_extended_perms { > +#define AVRULE_XPERMS_IOCTLFUNCTION 0x01 > +#define AVRULE_XPERMS_IOCTLDRIVER 0x02 > + uint8_t specified; > + uint8_t driver; > + /* 256 bits of permissions */ > uint32_t perms[8]; > -} av_operations_t; > +} av_extended_perms_t; > > typedef struct avrule { > /* these typedefs are almost exactly the same as those in avtab.h - they are > @@ -260,24 +263,18 @@ typedef struct avrule { > #define AVRULE_MEMBER 0x0020 > #define AVRULE_CHANGE 0x0040 > #define AVRULE_TYPE (AVRULE_TRANSITION | AVRULE_MEMBER | AVRULE_CHANGE) > -#define AVRULE_OPNUM_ALLOWED 0x0100 > -#define AVRULE_OPNUM_AUDITALLOW 0x0200 > -#define AVRULE_OPNUM_DONTAUDIT 0x0400 > -#define AVRULE_OPNUM (AVRULE_OPNUM_ALLOWED | AVRULE_OPNUM_AUDITALLOW | \ > - AVRULE_OPNUM_DONTAUDIT) > -#define AVRULE_OPTYPE_ALLOWED 0x1000 > -#define AVRULE_OPTYPE_AUDITALLOW 0x2000 > -#define AVRULE_OPTYPE_DONTAUDIT 0x4000 > -#define AVRULE_OPTYPE (AVRULE_OPTYPE_ALLOWED | AVRULE_OPTYPE_AUDITALLOW | \ > - AVRULE_OPTYPE_DONTAUDIT) > -#define AVRULE_OP (AVRULE_OPNUM | AVRULE_OPTYPE) > +#define AVRULE_XPERMS_ALLOWED 0x0100 > +#define AVRULE_XPERMS_AUDITALLOW 0x0200 > +#define AVRULE_XPERMS_DONTAUDIT 0x0400 > +#define AVRULE_XPERMS (AVRULE_XPERMS_ALLOWED | AVRULE_XPERMS_AUDITALLOW | \ > + AVRULE_XPERMS_DONTAUDIT) > uint32_t specified; > #define RULE_SELF 1 > uint32_t flags; > type_set_t stypes; > type_set_t ttypes; > class_perm_node_t *perms; > - av_operations_t * ops; > + av_extended_perms_t *xperms; > unsigned long line; /* line number from policy.conf where > * this rule originated */ > /* source file name and line number (e.g. .te file) */ > @@ -709,11 +706,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); > #define POLICYDB_VERSION_DEFAULT_TYPE 28 > #define POLICYDB_VERSION_CONSTRAINT_NAMES 29 > #define POLICYDB_VERSION_XEN_DEVICETREE 30 /* Xen-specific */ > -#define POLICYDB_VERSION_IOCTL_OPERATIONS 30 /* Linux-specific */ > +#define POLICYDB_VERSION_XPERMS_IOCTL 30 /* Linux-specific */ > > /* Range of policy versions we understand*/ > #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE > -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_IOCTL_OPERATIONS > +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_XPERMS_IOCTL > > /* Module versions and specific changes*/ > #define MOD_POLICYDB_VERSION_BASE 4 > diff --git a/libsepol/src/avtab.c b/libsepol/src/avtab.c > index d3745fe..799b98f 100644 > --- a/libsepol/src/avtab.c > +++ b/libsepol/src/avtab.c > @@ -93,7 +93,7 @@ avtab_insert_node(avtab_t * h, int hvalue, avtab_ptr_t prev, avtab_key_t * key, > avtab_datum_t * datum) > { > avtab_ptr_t newnode; > - avtab_operations_t *ops; > + avtab_extended_perms_t *xperms; > > newnode = (avtab_ptr_t) malloc(sizeof(struct avtab_node)); > if (newnode == NULL) > @@ -101,16 +101,16 @@ avtab_insert_node(avtab_t * h, int hvalue, avtab_ptr_t prev, avtab_key_t * key, > memset(newnode, 0, sizeof(struct avtab_node)); > newnode->key = *key; > > - if (key->specified & AVTAB_OP) { > - ops = calloc(1, sizeof(avtab_operations_t)); > - if (ops == NULL) { > + if (key->specified & AVTAB_XPERMS) { > + xperms = calloc(1, sizeof(avtab_extended_perms_t)); > + if (xperms == NULL) { > free(newnode); > return NULL; > } > - if (datum->ops) /* else caller populates ops*/ > - *ops = *(datum->ops); > + if (datum->xperms) /* else caller populates xperms */ > + *xperms = *(datum->xperms); > > - newnode->datum.ops = ops; > + newnode->datum.xperms = xperms; > } else { > newnode->datum = *datum; > } > @@ -144,7 +144,8 @@ int avtab_insert(avtab_t * h, avtab_key_t * key, avtab_datum_t * datum) > key->target_type == cur->key.target_type && > key->target_class == cur->key.target_class && > (specified & cur->key.specified)) { > - if (specified & AVTAB_OPNUM) > + /* Extended permissions are not necessarily unique */ > + if (specified & AVTAB_XPERMS) > break; > return SEPOL_EEXIST; > } > @@ -416,12 +417,9 @@ static uint16_t spec_order[] = { > AVTAB_TRANSITION, > AVTAB_CHANGE, > AVTAB_MEMBER, > - AVTAB_OPNUM_ALLOWED, > - AVTAB_OPNUM_AUDITALLOW, > - AVTAB_OPNUM_DONTAUDIT, > - AVTAB_OPTYPE_ALLOWED, > - AVTAB_OPTYPE_AUDITALLOW, > - AVTAB_OPTYPE_DONTAUDIT > + AVTAB_XPERMS_ALLOWED, > + AVTAB_XPERMS_AUDITALLOW, > + AVTAB_XPERMS_DONTAUDIT > }; > > int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a, > @@ -433,14 +431,14 @@ int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a, > uint32_t buf32[8], items, items2, val; > avtab_key_t key; > avtab_datum_t datum; > - avtab_operations_t ops; > + avtab_extended_perms_t xperms; > unsigned set; > unsigned int i; > int rc; > > memset(&key, 0, sizeof(avtab_key_t)); > memset(&datum, 0, sizeof(avtab_datum_t)); > - memset(&ops, 0, sizeof(avtab_operations_t)); > + memset(&xperms, 0, sizeof(avtab_extended_perms_t)); > > if (vers < POLICYDB_VERSION_AVTAB) { > rc = next_entry(buf32, fp, sizeof(uint32_t)); > @@ -533,26 +531,32 @@ int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a, > return -1; > } > > - if ((vers < POLICYDB_VERSION_IOCTL_OPERATIONS) && > - (key.specified & AVTAB_OP)) { > - ERR(fp->handle, "policy version %u does not support ioctl " > - "operation rules and one was specified\n", vers); > + if ((vers < POLICYDB_VERSION_XPERMS_IOCTL) && > + (key.specified & AVTAB_XPERMS)) { > + ERR(fp->handle, "policy version %u does not support extended " > + "permissions rules and one was specified\n", vers); > return -1; > - } else if (key.specified & AVTAB_OP) { > + } else if (key.specified & AVTAB_XPERMS) { > rc = next_entry(&buf8, fp, sizeof(uint8_t)); > if (rc < 0) { > ERR(fp->handle, "truncated entry"); > return -1; > } > - ops.type = buf8; > + xperms.specified = buf8; > + rc = next_entry(&buf8, fp, sizeof(uint8_t)); > + if (rc < 0) { > + ERR(fp->handle, "truncated entry"); > + return -1; > + } > + xperms.driver = buf8; > rc = next_entry(buf32, fp, sizeof(uint32_t)*8); > if (rc < 0) { > ERR(fp->handle, "truncated entry"); > return -1; > } > - for (i = 0; i < ARRAY_SIZE(ops.perms); i++) > - ops.perms[i] = le32_to_cpu(buf32[i]); > - datum.ops = &ops; > + for (i = 0; i < ARRAY_SIZE(xperms.perms); i++) > + xperms.perms[i] = le32_to_cpu(buf32[i]); > + datum.xperms = &xperms; > } else { > rc = next_entry(buf32, fp, sizeof(uint32_t)); > if (rc < 0) { > diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c > index b999890..478eaff 100644 > --- a/libsepol/src/expand.c > +++ b/libsepol/src/expand.c > @@ -1604,24 +1604,25 @@ static int expand_range_trans(expand_state_t * state, > static avtab_ptr_t find_avtab_node(sepol_handle_t * handle, > avtab_t * avtab, avtab_key_t * key, > cond_av_list_t ** cond, > - av_operations_t *operations) > + av_extended_perms_t *xperms) > { > avtab_ptr_t node; > avtab_datum_t avdatum; > cond_av_list_t *nl; > - int type_match = 0; > + int match = 0; > > - /* AVTAB_OPNUM entries are not necessarily unique */ > - if (key->specified & AVTAB_OPNUM) { > + /* AVTAB_XPERMS entries are not necessarily unique */ > + if (key->specified & AVTAB_XPERMS) { > node = avtab_search_node(avtab, key); > while (node) { > - if (node->datum.ops->type == operations->type) { > - type_match = 1; > + if ((node->datum.xperms->specified == xperms->specified) && > + (node->datum.xperms->driver == xperms->driver)) { > + match = 1; > break; > } > node = avtab_search_node_next(node, key->specified); > } > - if (!type_match) > + if (!match) > node = NULL; > } else { > node = avtab_search_node(avtab, key); > @@ -1780,11 +1781,11 @@ static int expand_avrule_helper(sepol_handle_t * handle, > cond_av_list_t ** cond, > uint32_t stype, uint32_t ttype, > class_perm_node_t * perms, avtab_t * avtab, > - int enabled, av_operations_t *operations) > + int enabled, av_extended_perms_t *extended_perms) > { > avtab_key_t avkey; > avtab_datum_t *avdatump; > - avtab_operations_t *ops; > + avtab_extended_perms_t *xperms; > avtab_ptr_t node; > class_perm_node_t *cur; > uint32_t spec = 0; > @@ -1802,22 +1803,14 @@ static int expand_avrule_helper(sepol_handle_t * handle, > spec = AVTAB_AUDITDENY; > } else if (specified & AVRULE_NEVERALLOW) { > spec = AVTAB_NEVERALLOW; > - } else if (specified & AVRULE_OPNUM_ALLOWED) { > - spec = AVTAB_OPNUM_ALLOWED; > - } else if (specified & AVRULE_OPNUM_AUDITALLOW) { > - spec = AVTAB_OPNUM_AUDITALLOW; > - } else if (specified & AVRULE_OPNUM_DONTAUDIT) { > + } else if (specified & AVRULE_XPERMS_ALLOWED) { > + spec = AVTAB_XPERMS_ALLOWED; > + } else if (specified & AVRULE_XPERMS_AUDITALLOW) { > + spec = AVTAB_XPERMS_AUDITALLOW; > + } else if (specified & AVRULE_XPERMS_DONTAUDIT) { > if (handle && handle->disable_dontaudit) > return EXPAND_RULE_SUCCESS; > - spec = AVTAB_OPNUM_DONTAUDIT; > - } else if (specified & AVRULE_OPTYPE_ALLOWED) { > - spec = AVTAB_OPTYPE_ALLOWED; > - } else if (specified & AVRULE_OPTYPE_AUDITALLOW) { > - spec = AVTAB_OPTYPE_AUDITALLOW; > - } else if (specified & AVRULE_OPTYPE_DONTAUDIT) { > - if (handle && handle->disable_dontaudit) > - return EXPAND_RULE_SUCCESS; > - spec = AVTAB_OPTYPE_DONTAUDIT; > + spec = AVTAB_XPERMS_DONTAUDIT; > } else { > assert(0); /* unreachable */ > } > @@ -1829,7 +1822,7 @@ static int expand_avrule_helper(sepol_handle_t * handle, > avkey.target_class = cur->tclass; > avkey.specified = spec; > > - node = find_avtab_node(handle, avtab, &avkey, cond, operations); > + node = find_avtab_node(handle, avtab, &avkey, cond, extended_perms); > if (!node) > return EXPAND_RULE_ERROR; > if (enabled) { > @@ -1859,20 +1852,21 @@ static int expand_avrule_helper(sepol_handle_t * handle, > avdatump->data &= ~cur->data; > else > avdatump->data = ~cur->data; > - } else if (specified & AVRULE_OP) { > - if (!avdatump->ops) { > - ops = (avtab_operations_t *) > - calloc(1, sizeof(avtab_operations_t)); > - if (!ops) { > + } else if (specified & AVRULE_XPERMS) { > + if (!avdatump->xperms) { > + xperms = (avtab_extended_perms_t *) > + calloc(1, sizeof(avtab_extended_perms_t)); > + if (!xperms) { > ERR(handle, "Out of memory!"); > return -1; > } > - node->datum.ops = ops; > - } > - node->datum.ops->type = operations->type; > - for (i = 0; i < ARRAY_SIZE(operations->perms); i++) { > - node->datum.ops->perms[i] |= operations->perms[i]; > + node->datum.xperms = xperms; > } > + node->datum.xperms->specified = extended_perms->specified; > + node->datum.xperms->driver = extended_perms->driver; > + > + for (i = 0; i < ARRAY_SIZE(xperms->perms); i++) > + node->datum.xperms->perms[i] |= extended_perms->perms[i]; > } else { > assert(0); /* should never occur */ > } > @@ -1897,10 +1891,10 @@ static int expand_rule_helper(sepol_handle_t * handle, > if (!ebitmap_node_get_bit(snode, i)) > continue; > if (source_rule->flags & RULE_SELF) { > - if (source_rule->specified & (AVRULE_AV | AVRULE_OP)) { > + if (source_rule->specified & (AVRULE_AV | AVRULE_XPERMS)) { > retval = expand_avrule_helper(handle, source_rule->specified, > cond, i, i, source_rule->perms, > - dest_avtab, enabled, source_rule->ops); > + dest_avtab, enabled, source_rule->xperms); > if (retval != EXPAND_RULE_SUCCESS) > return retval; > } else { > @@ -1915,10 +1909,10 @@ static int expand_rule_helper(sepol_handle_t * handle, > ebitmap_for_each_bit(ttypes, tnode, j) { > if (!ebitmap_node_get_bit(tnode, j)) > continue; > - if (source_rule->specified & (AVRULE_AV | AVRULE_OP)) { > + if (source_rule->specified & (AVRULE_AV | AVRULE_XPERMS)) { > retval = expand_avrule_helper(handle, source_rule->specified, > cond, i, j, source_rule->perms, > - dest_avtab, enabled, source_rule->ops); > + dest_avtab, enabled, source_rule->xperms); > if (retval != EXPAND_RULE_SUCCESS) > return retval; > } else { > @@ -3155,24 +3149,25 @@ static int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d) > { > avtab_ptr_t node; > avtab_datum_t *avd; > - avtab_operations_t *ops; > + avtab_extended_perms_t *xperms; > unsigned int i; > - unsigned int type_match = 0; > + unsigned int match = 0; > > - if (k->specified & AVTAB_OPNUM) { > + if (k->specified & AVTAB_XPERMS) { > /* > - * AVTAB_OPNUM entries are not necessarily unique. > - * find node with matching ops->type > + * AVTAB_XPERMS entries are not necessarily unique. > + * find node with matching xperms > */ > node = avtab_search_node(a, k); > while (node) { > - if (node->datum.ops->type == d->ops->type) { > - type_match = 1; > + if ((node->datum.xperms->specified == d->xperms->specified) && > + (node->datum.xperms->driver == d->xperms->driver)) { > + match = 1; > break; > } > node = avtab_search_node_next(node, k->specified); > } > - if (!type_match) > + if (!match) > node = NULL; > } else { > node = avtab_search_node(a, k); > @@ -3189,7 +3184,7 @@ static int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d) > } > > avd = &node->datum; > - ops = node->datum.ops; > + xperms = node->datum.xperms; > switch (k->specified & ~AVTAB_ENABLED) { > case AVTAB_ALLOWED: > case AVTAB_AUDITALLOW: > @@ -3198,14 +3193,11 @@ static int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d) > case AVTAB_AUDITDENY: > avd->data &= d->data; > break; > - case AVTAB_OPNUM_ALLOWED: > - case AVTAB_OPNUM_AUDITALLOW: > - case AVTAB_OPNUM_DONTAUDIT: > - case AVTAB_OPTYPE_ALLOWED: > - case AVTAB_OPTYPE_AUDITALLOW: > - case AVTAB_OPTYPE_DONTAUDIT: > - for (i = 0; i < ARRAY_SIZE(ops->perms); i++) > - ops->perms[i] |= d->ops->perms[i]; > + case AVTAB_XPERMS_ALLOWED: > + case AVTAB_XPERMS_AUDITALLOW: > + case AVTAB_XPERMS_DONTAUDIT: > + for (i = 0; i < ARRAY_SIZE(xperms->perms); i++) > + xperms->perms[i] |= d->xperms->perms[i]; > break; > default: > ERR(NULL, "Type conflict!"); > diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c > index 8c3c7ac..1677eb5 100644 > --- a/libsepol/src/policydb.c > +++ b/libsepol/src/policydb.c > @@ -180,7 +180,7 @@ static struct policydb_compat_info policydb_compat[] = { > }, > { > .type = POLICY_KERN, > - .version = POLICYDB_VERSION_IOCTL_OPERATIONS, > + .version = POLICYDB_VERSION_XPERMS_IOCTL, > .sym_num = SYM_NUM, > .ocon_num = OCON_NODE6 + 1, > .target_platform = SEPOL_TARGET_SELINUX, > diff --git a/libsepol/src/write.c b/libsepol/src/write.c > index 6e78eb3..d87ea61 100644 > --- a/libsepol/src/write.c > +++ b/libsepol/src/write.c > @@ -221,28 +221,32 @@ static int avtab_write_item(policydb_t * p, > items = put_entry(buf16, sizeof(uint16_t), 4, fp); > if (items != 4) > return POLICYDB_ERROR; > - if ((p->policyvers < POLICYDB_VERSION_IOCTL_OPERATIONS) && > - (cur->key.specified & AVTAB_OP)) { > - ERR(fp->handle, "policy version %u does not support ioctl operation" > - " rules and one was specified", p->policyvers); > + if ((p->policyvers < POLICYDB_VERSION_XPERMS_IOCTL) && > + (cur->key.specified & AVTAB_XPERMS)) { > + ERR(fp->handle, "policy version %u does not support ioctl extended" > + "permissions rules and one was specified", p->policyvers); > return POLICYDB_ERROR; > } > > if (p->target_platform != SEPOL_TARGET_SELINUX && > - (cur->key.specified & AVTAB_OP)) { > + (cur->key.specified & AVTAB_XPERMS)) { > ERR(fp->handle, "Target platform %s does not support ioctl " > - "operation rules and one was specified", > + "extended permissions rules and one was specified", > policydb_target_strings[p->target_platform]); > return POLICYDB_ERROR; > } > > - if (cur->key.specified & AVTAB_OP) { > - buf8 = cur->datum.ops->type; > + if (cur->key.specified & AVTAB_XPERMS) { > + buf8 = cur->datum.xperms->specified; > items = put_entry(&buf8, sizeof(uint8_t),1,fp); > if (items != 1) > return POLICYDB_ERROR; > - for (i = 0; i < ARRAY_SIZE(cur->datum.ops->perms); i++) > - buf32[i] = cpu_to_le32(cur->datum.ops->perms[i]); > + buf8 = cur->datum.xperms->driver; > + items = put_entry(&buf8, sizeof(uint8_t),1,fp); > + if (items != 1) > + return POLICYDB_ERROR; > + for (i = 0; i < ARRAY_SIZE(cur->datum.xperms->perms); i++) > + buf32[i] = cpu_to_le32(cur->datum.xperms->perms[i]); > items = put_entry(buf32, sizeof(uint32_t),8,fp); > if (items != 8) > return POLICYDB_ERROR; > @@ -1546,9 +1550,9 @@ static int avrule_write(avrule_t * avrule, struct policy_file *fp) > uint32_t buf[32], len; > class_perm_node_t *cur; > > - if (avrule->specified & AVRULE_OP) { > - ERR(fp->handle, "module policy does not support ioctl operation" > - " rules and one was specified"); > + if (avrule->specified & AVRULE_XPERMS) { > + ERR(fp->handle, "module policy does not support extended" > + " permissions rules and one was specified"); > return POLICYDB_ERROR; > } > > _______________________________________________ Selinux mailing list Selinux@xxxxxxxxxxxxx To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx. To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.