diff options
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r-- | security/selinux/ss/services.c | 161 |
1 files changed, 86 insertions, 75 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 88178da2b83..cf905cdce93 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -95,7 +95,7 @@ static void context_struct_compute_av(struct context *scontext, struct context *tcontext, u16 tclass, struct av_decision *avd, - struct operation *ops); + struct extended_perms *xperms); struct selinux_mapping { u16 value; /* policy value */ @@ -615,39 +615,40 @@ static void type_attribute_bounds_av(struct context *scontext, } } -/* flag ioctl types that have operation permissions */ -void services_compute_operation_type( - struct operation *ops, +/* + * flag which drivers have permissions + * only looking for ioctl based extended permssions + */ +void services_compute_xperms_drivers( + struct extended_perms *xperms, struct avtab_node *node) { - u8 type; unsigned int i; - if (node->key.specified & AVTAB_OPTYPE) { - /* if allowing one or more complete types */ - for (i = 0; i < ARRAY_SIZE(ops->type); i++) - ops->type[i] |= node->datum.u.ops->op.perms[i]; - } else { - /* if allowing operations within a type */ - type = node->datum.u.ops->type; - security_operation_set(ops->type, type); + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + /* if one or more driver has all permissions allowed */ + for (i = 0; i < ARRAY_SIZE(xperms->drivers.p); i++) + xperms->drivers.p[i] |= node->datum.u.xperms->perms.p[i]; + } else if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + /* if allowing permissions within a driver */ + security_xperm_set(xperms->drivers.p, + node->datum.u.xperms->driver); } /* If no ioctl commands are allowed, ignore auditallow and auditdeny */ - if (node->key.specified & AVTAB_OPTYPE_ALLOWED || - node->key.specified & AVTAB_OPNUM_ALLOWED) - ops->len = 1; + if (node->key.specified & AVTAB_XPERMS_ALLOWED) + xperms->len = 1; } /* - * Compute access vectors and operations ranges based on a context + * Compute access vectors and extended permissions based on a context * structure pair for the permissions in a particular class. */ static void context_struct_compute_av(struct context *scontext, struct context *tcontext, u16 tclass, struct av_decision *avd, - struct operation *ops) + struct extended_perms *xperms) { struct constraint_node *constraint; struct role_allow *ra; @@ -661,9 +662,9 @@ static void context_struct_compute_av(struct context *scontext, avd->allowed = 0; avd->auditallow = 0; avd->auditdeny = 0xffffffff; - if (ops) { - memset(&ops->type, 0, sizeof(ops->type)); - ops->len = 0; + if (xperms) { + memset(&xperms->drivers, 0, sizeof(xperms->drivers)); + xperms->len = 0; } if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { @@ -679,7 +680,7 @@ static void context_struct_compute_av(struct context *scontext, * this permission check, then use it. */ avkey.target_class = tclass; - avkey.specified = AVTAB_AV | AVTAB_OP; + avkey.specified = AVTAB_AV | AVTAB_XPERMS; sattr = flex_array_get(policydb.type_attr_map_array, scontext->type - 1); BUG_ON(!sattr); tattr = flex_array_get(policydb.type_attr_map_array, tcontext->type - 1); @@ -697,12 +698,13 @@ static void context_struct_compute_av(struct context *scontext, avd->auditallow |= node->datum.u.data; else if (node->key.specified == AVTAB_AUDITDENY) avd->auditdeny &= node->datum.u.data; - else if (ops && (node->key.specified & AVTAB_OP)) - services_compute_operation_type(ops, node); + else if (xperms && (node->key.specified & AVTAB_XPERMS)) + services_compute_xperms_drivers(xperms, node); } /* Check conditional av table for additional permissions */ - cond_compute_av(&policydb.te_cond_avtab, &avkey, avd, ops); + cond_compute_av(&policydb.te_cond_avtab, &avkey, + avd, xperms); } } @@ -933,57 +935,65 @@ static void avd_init(struct av_decision *avd) avd->flags = 0; } -void services_compute_operation_num(struct operation_decision *od, +void services_compute_xperms_decision(struct extended_perms_decision *xpermd, struct avtab_node *node) { unsigned int i; - if (node->key.specified & AVTAB_OPNUM) { - if (od->type != node->datum.u.ops->type) + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + if (xpermd->driver != node->datum.u.xperms->driver) return; - } else { - if (!security_operation_test(node->datum.u.ops->op.perms, - od->type)) + } else if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + if (!security_xperm_test(node->datum.u.xperms->perms.p, + xpermd->driver)) return; + } else { + BUG(); } - if (node->key.specified == AVTAB_OPTYPE_ALLOWED) { - od->specified |= OPERATION_ALLOWED; - memset(od->allowed->perms, 0xff, - sizeof(od->allowed->perms)); - } else if (node->key.specified == AVTAB_OPTYPE_AUDITALLOW) { - od->specified |= OPERATION_AUDITALLOW; - memset(od->auditallow->perms, 0xff, - sizeof(od->auditallow->perms)); - } else if (node->key.specified == AVTAB_OPTYPE_DONTAUDIT) { - od->specified |= OPERATION_DONTAUDIT; - memset(od->dontaudit->perms, 0xff, - sizeof(od->dontaudit->perms)); - } else if (node->key.specified == AVTAB_OPNUM_ALLOWED) { - od->specified |= OPERATION_ALLOWED; - for (i = 0; i < ARRAY_SIZE(od->allowed->perms); i++) - od->allowed->perms[i] |= - node->datum.u.ops->op.perms[i]; - } else if (node->key.specified == AVTAB_OPNUM_AUDITALLOW) { - od->specified |= OPERATION_AUDITALLOW; - for (i = 0; i < ARRAY_SIZE(od->auditallow->perms); i++) - od->auditallow->perms[i] |= - node->datum.u.ops->op.perms[i]; - } else if (node->key.specified == AVTAB_OPNUM_DONTAUDIT) { - od->specified |= OPERATION_DONTAUDIT; - for (i = 0; i < ARRAY_SIZE(od->dontaudit->perms); i++) - od->dontaudit->perms[i] |= - node->datum.u.ops->op.perms[i]; + if (node->key.specified == AVTAB_XPERMS_ALLOWED) { + xpermd->used |= XPERMS_ALLOWED; + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + memset(xpermd->allowed->p, 0xff, + sizeof(xpermd->allowed->p)); + } + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + for (i = 0; i < ARRAY_SIZE(xpermd->allowed->p); i++) + xpermd->allowed->p[i] |= + node->datum.u.xperms->perms.p[i]; + } + } else if (node->key.specified == AVTAB_XPERMS_AUDITALLOW) { + xpermd->used |= XPERMS_AUDITALLOW; + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + memset(xpermd->auditallow->p, 0xff, + sizeof(xpermd->auditallow->p)); + } + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + for (i = 0; i < ARRAY_SIZE(xpermd->auditallow->p); i++) + xpermd->auditallow->p[i] |= + node->datum.u.xperms->perms.p[i]; + } + } else if (node->key.specified == AVTAB_XPERMS_DONTAUDIT) { + xpermd->used |= XPERMS_DONTAUDIT; + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + memset(xpermd->dontaudit->p, 0xff, + sizeof(xpermd->dontaudit->p)); + } + if (node->datum.u.xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) { + for (i = 0; i < ARRAY_SIZE(xpermd->dontaudit->p); i++) + xpermd->dontaudit->p[i] |= + node->datum.u.xperms->perms.p[i]; + } } else { BUG(); } } -void security_compute_operation(u32 ssid, +void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 orig_tclass, - u8 type, - struct operation_decision *od) + u8 driver, + struct extended_perms_decision *xpermd) { u16 tclass; struct context *scontext, *tcontext; @@ -993,11 +1003,11 @@ void security_compute_operation(u32 ssid, struct ebitmap_node *snode, *tnode; unsigned int i, j; - od->type = type; - od->specified = 0; - memset(od->allowed->perms, 0, sizeof(od->allowed->perms)); - memset(od->auditallow->perms, 0, sizeof(od->auditallow->perms)); - memset(od->dontaudit->perms, 0, sizeof(od->dontaudit->perms)); + xpermd->driver = driver; + xpermd->used = 0; + memset(xpermd->allowed->p, 0, sizeof(xpermd->allowed->p)); + memset(xpermd->auditallow->p, 0, sizeof(xpermd->auditallow->p)); + memset(xpermd->dontaudit->p, 0, sizeof(xpermd->dontaudit->p)); read_lock(&policy_rwlock); if (!ss_initialized) @@ -1031,7 +1041,7 @@ void security_compute_operation(u32 ssid, } avkey.target_class = tclass; - avkey.specified = AVTAB_OP; + avkey.specified = AVTAB_XPERMS; sattr = flex_array_get(policydb.type_attr_map_array, scontext->type - 1); BUG_ON(!sattr); @@ -1045,26 +1055,27 @@ void security_compute_operation(u32 ssid, for (node = avtab_search_node(&policydb.te_avtab, &avkey); node; node = avtab_search_node_next(node, avkey.specified)) - services_compute_operation_num(od, node); + services_compute_xperms_decision(xpermd, node); - cond_compute_operation(&policydb.te_cond_avtab, - &avkey, od); + cond_compute_xperms(&policydb.te_cond_avtab, + &avkey, xpermd); } } out: read_unlock(&policy_rwlock); return; allow: - memset(od->allowed->perms, 0xff, sizeof(od->allowed->perms)); + memset(xpermd->allowed->p, 0xff, sizeof(xpermd->allowed->p)); goto out; } + /** * security_compute_av - Compute access vector decisions. * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class * @avd: access vector decisions - * @od: operation decisions + * @xperms: extended permissions * * Compute a set of access vector decisions based on the * SID pair (@ssid, @tsid) for the permissions in @tclass. @@ -1073,14 +1084,14 @@ void security_compute_av(u32 ssid, u32 tsid, u16 orig_tclass, struct av_decision *avd, - struct operation *ops) + struct extended_perms *xperms) { u16 tclass; struct context *scontext = NULL, *tcontext = NULL; read_lock(&policy_rwlock); avd_init(avd); - ops->len = 0; + xperms->len = 0; if (!ss_initialized) goto allow; @@ -1108,7 +1119,7 @@ void security_compute_av(u32 ssid, goto allow; goto out; } - context_struct_compute_av(scontext, tcontext, tclass, avd, ops); + context_struct_compute_av(scontext, tcontext, tclass, avd, xperms); map_decision(orig_tclass, avd, policydb.allow_unknown); out: read_unlock(&policy_rwlock); |