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> --- 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; } -- 2.2.0.rc0.207.ga3a616c _______________________________________________ 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.