summaryrefslogtreecommitdiff
path: root/security/selinux/ss
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss')
-rw-r--r--security/selinux/ss/conditional.c2
-rw-r--r--security/selinux/ss/ebitmap.c5
-rw-r--r--security/selinux/ss/policydb.c12
-rw-r--r--security/selinux/ss/services.c76
4 files changed, 39 insertions, 56 deletions
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index 456e1a9bcfde..34afeadd9e73 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -242,6 +242,8 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
goto err;
len = le32_to_cpu(buf[2]);
+ if (((len == 0) || (len == (u32)-1)))
+ goto err;
rc = -ENOMEM;
key = kmalloc(len + 1, GFP_KERNEL);
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 57644b1dc42e..7d10e5d418bb 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -165,7 +165,7 @@ int ebitmap_netlbl_import(struct ebitmap *ebmap,
e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC);
if (e_iter == NULL)
goto netlbl_import_failure;
- e_iter->startbit = offset & ~(EBITMAP_SIZE - 1);
+ e_iter->startbit = offset - (offset % EBITMAP_SIZE);
if (e_prev == NULL)
ebmap->node = e_iter;
else
@@ -374,6 +374,9 @@ int ebitmap_read(struct ebitmap *e, void *fp)
goto ok;
}
+ if (e->highbit && !count)
+ goto bad;
+
for (i = 0; i < count; i++) {
rc = next_entry(&startbit, fp, sizeof(u32));
if (rc < 0) {
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 992a31530825..ace683838d80 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -541,21 +541,21 @@ static int policydb_index(struct policydb *p)
rc = -ENOMEM;
p->class_val_to_struct =
- kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)),
+ kzalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)),
GFP_KERNEL);
if (!p->class_val_to_struct)
goto out;
rc = -ENOMEM;
p->role_val_to_struct =
- kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),
+ kzalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),
GFP_KERNEL);
if (!p->role_val_to_struct)
goto out;
rc = -ENOMEM;
p->user_val_to_struct =
- kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),
+ kzalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),
GFP_KERNEL);
if (!p->user_val_to_struct)
goto out;
@@ -964,7 +964,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
* Role must be authorized for the type.
*/
role = p->role_val_to_struct[c->role - 1];
- if (!ebitmap_get_bit(&role->types, c->type - 1))
+ if (!role || !ebitmap_get_bit(&role->types, c->type - 1))
/* role may not be associated with type */
return 0;
@@ -1094,6 +1094,9 @@ static int str_read(char **strp, gfp_t flags, void *fp, u32 len)
int rc;
char *str;
+ if ((len == 0) || (len == (u32)-1))
+ return -EINVAL;
+
str = kmalloc(len + 1, flags);
if (!str)
return -ENOMEM;
@@ -2414,6 +2417,7 @@ int policydb_read(struct policydb *p, void *fp)
} else
tr->tclass = p->process_class;
+ rc = -EINVAL;
if (!policydb_role_isvalid(p, tr->role) ||
!policydb_type_isvalid(p, tr->type) ||
!policydb_class_isvalid(p, tr->tclass) ||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index ebda97333f1b..082b20c78363 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -543,7 +543,7 @@ static void type_attribute_bounds_av(struct context *scontext,
struct av_decision *avd)
{
struct context lo_scontext;
- struct context lo_tcontext;
+ struct context lo_tcontext, *tcontextp = tcontext;
struct av_decision lo_avd;
struct type_datum *source;
struct type_datum *target;
@@ -553,67 +553,41 @@ static void type_attribute_bounds_av(struct context *scontext,
scontext->type - 1);
BUG_ON(!source);
+ if (!source->bounds)
+ return;
+
target = flex_array_get_ptr(policydb.type_val_to_struct_array,
tcontext->type - 1);
BUG_ON(!target);
- if (source->bounds) {
- memset(&lo_avd, 0, sizeof(lo_avd));
-
- memcpy(&lo_scontext, scontext, sizeof(lo_scontext));
- lo_scontext.type = source->bounds;
+ memset(&lo_avd, 0, sizeof(lo_avd));
- context_struct_compute_av(&lo_scontext,
- tcontext,
- tclass,
- &lo_avd,
- NULL);
- if ((lo_avd.allowed & avd->allowed) == avd->allowed)
- return; /* no masked permission */
- masked = ~lo_avd.allowed & avd->allowed;
- }
+ memcpy(&lo_scontext, scontext, sizeof(lo_scontext));
+ lo_scontext.type = source->bounds;
if (target->bounds) {
- memset(&lo_avd, 0, sizeof(lo_avd));
-
memcpy(&lo_tcontext, tcontext, sizeof(lo_tcontext));
lo_tcontext.type = target->bounds;
-
- context_struct_compute_av(scontext,
- &lo_tcontext,
- tclass,
- &lo_avd,
- NULL);
- if ((lo_avd.allowed & avd->allowed) == avd->allowed)
- return; /* no masked permission */
- masked = ~lo_avd.allowed & avd->allowed;
+ tcontextp = &lo_tcontext;
}
- if (source->bounds && target->bounds) {
- memset(&lo_avd, 0, sizeof(lo_avd));
- /*
- * lo_scontext and lo_tcontext are already
- * set up.
- */
+ context_struct_compute_av(&lo_scontext,
+ tcontextp,
+ tclass,
+ &lo_avd,
+ NULL);
- context_struct_compute_av(&lo_scontext,
- &lo_tcontext,
- tclass,
- &lo_avd,
- NULL);
- if ((lo_avd.allowed & avd->allowed) == avd->allowed)
- return; /* no masked permission */
- masked = ~lo_avd.allowed & avd->allowed;
- }
+ masked = ~lo_avd.allowed & avd->allowed;
- if (masked) {
- /* mask violated permissions */
- avd->allowed &= ~masked;
+ if (likely(!masked))
+ return; /* no masked permission */
- /* audit masked permissions */
- security_dump_masked_av(scontext, tcontext,
- tclass, masked, "bounds");
- }
+ /* mask violated permissions */
+ avd->allowed &= ~masked;
+
+ /* audit masked permissions */
+ security_dump_masked_av(scontext, tcontext,
+ tclass, masked, "bounds");
}
/*
@@ -2696,7 +2670,7 @@ out:
return rc;
}
-int security_get_bool_value(int bool)
+int security_get_bool_value(int index)
{
int rc;
int len;
@@ -2705,10 +2679,10 @@ int security_get_bool_value(int bool)
rc = -EFAULT;
len = policydb.p_bools.nprim;
- if (bool >= len)
+ if (index >= len)
goto out;
- rc = policydb.bool_val_to_struct[bool]->state;
+ rc = policydb.bool_val_to_struct[index]->state;
out:
read_unlock(&policy_rwlock);
return rc;