diff options
Diffstat (limited to 'security/selinux/ss')
-rw-r--r-- | security/selinux/ss/conditional.c | 2 | ||||
-rw-r--r-- | security/selinux/ss/ebitmap.c | 5 | ||||
-rw-r--r-- | security/selinux/ss/policydb.c | 12 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 76 |
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; |