summaryrefslogtreecommitdiff
path: root/security/selinux/ss/services.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r--security/selinux/ss/services.c161
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);