aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 14:08:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 14:08:27 -0400
commitd488d3a4ce08e96dad5cb3b6117517d57ccec98f (patch)
tree169b09c589e38f6d5f2ea0a9e25c6a9fb3ebf783 /security/selinux
parentcb906953d2c3fd450655d9fa833f03690ad50c23 (diff)
parent5deeb5cece3f9b30c8129786726b9d02c412c8ca (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris: "Highlights for this window: - improved AVC hashing for SELinux by John Brooks and Stephen Smalley - addition of an unconfined label to Smack - Smack documentation update - TPM driver updates" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (28 commits) lsm: copy comm before calling audit_log to avoid race in string printing tomoyo: Do not generate empty policy files tomoyo: Use if_changed when generating builtin-policy.h tomoyo: Use bin2c to generate builtin-policy.h selinux: increase avtab max buckets selinux: Use a better hash function for avtab selinux: convert avtab hash table to flex_array selinux: reconcile security_netlbl_secattr_to_sid() and mls_import_netlbl_cat() selinux: remove unnecessary pointer reassignment Smack: Updates for Smack documentation tpm/st33zp24/spi: Add missing device table for spi phy. tpm/st33zp24: Add proper wait for ordinal duration in case of irq mode smack: Fix gcc warning from unused smack_syslog_lock mutex in smackfs.c Smack: Allow an unconfined label in bringup mode Smack: getting the Smack security context of keys Smack: Assign smack_known_web as default smk_in label for kernel thread's socket tpm/tpm_infineon: Use struct dev_pm_ops for power management MAINTAINERS: Add Jason as designated reviewer for TPM tpm: Update KConfig text to include TPM2.0 FIFO chips tpm/st33zp24/dts/st33zp24-spi: Add dts documentation for st33zp24 spi phy ...
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/avc.c6
-rw-r--r--security/selinux/ss/avtab.c72
-rw-r--r--security/selinux/ss/avtab.h8
-rw-r--r--security/selinux/ss/mls.c10
-rw-r--r--security/selinux/ss/services.c6
5 files changed, 67 insertions, 35 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index afcc0aed9393..3c17dda9571d 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -724,12 +724,10 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
724 rcu_read_lock(); 724 rcu_read_lock();
725 725
726 node = avc_lookup(ssid, tsid, tclass); 726 node = avc_lookup(ssid, tsid, tclass);
727 if (unlikely(!node)) { 727 if (unlikely(!node))
728 node = avc_compute_av(ssid, tsid, tclass, avd); 728 node = avc_compute_av(ssid, tsid, tclass, avd);
729 } else { 729 else
730 memcpy(avd, &node->ae.avd, sizeof(*avd)); 730 memcpy(avd, &node->ae.avd, sizeof(*avd));
731 avd = &node->ae.avd;
732 }
733 731
734 denied = requested & ~(avd->allowed); 732 denied = requested & ~(avd->allowed);
735 if (unlikely(denied)) 733 if (unlikely(denied))
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index a3dd9faa19c0..b64f2772b030 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -25,10 +25,43 @@
25 25
26static struct kmem_cache *avtab_node_cachep; 26static struct kmem_cache *avtab_node_cachep;
27 27
28static inline int avtab_hash(struct avtab_key *keyp, u16 mask) 28/* Based on MurmurHash3, written by Austin Appleby and placed in the
29 * public domain.
30 */
31static inline int avtab_hash(struct avtab_key *keyp, u32 mask)
29{ 32{
30 return ((keyp->target_class + (keyp->target_type << 2) + 33 static const u32 c1 = 0xcc9e2d51;
31 (keyp->source_type << 9)) & mask); 34 static const u32 c2 = 0x1b873593;
35 static const u32 r1 = 15;
36 static const u32 r2 = 13;
37 static const u32 m = 5;
38 static const u32 n = 0xe6546b64;
39
40 u32 hash = 0;
41
42#define mix(input) { \
43 u32 v = input; \
44 v *= c1; \
45 v = (v << r1) | (v >> (32 - r1)); \
46 v *= c2; \
47 hash ^= v; \
48 hash = (hash << r2) | (hash >> (32 - r2)); \
49 hash = hash * m + n; \
50}
51
52 mix(keyp->target_class);
53 mix(keyp->target_type);
54 mix(keyp->source_type);
55
56#undef mix
57
58 hash ^= hash >> 16;
59 hash *= 0x85ebca6b;
60 hash ^= hash >> 13;
61 hash *= 0xc2b2ae35;
62 hash ^= hash >> 16;
63
64 return hash & mask;
32} 65}
33 66
34static struct avtab_node* 67static struct avtab_node*
@@ -46,8 +79,12 @@ avtab_insert_node(struct avtab *h, int hvalue,
46 newnode->next = prev->next; 79 newnode->next = prev->next;
47 prev->next = newnode; 80 prev->next = newnode;
48 } else { 81 } else {
49 newnode->next = h->htable[hvalue]; 82 newnode->next = flex_array_get_ptr(h->htable, hvalue);
50 h->htable[hvalue] = newnode; 83 if (flex_array_put_ptr(h->htable, hvalue, newnode,
84 GFP_KERNEL|__GFP_ZERO)) {
85 kmem_cache_free(avtab_node_cachep, newnode);
86 return NULL;
87 }
51 } 88 }
52 89
53 h->nel++; 90 h->nel++;
@@ -64,7 +101,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
64 return -EINVAL; 101 return -EINVAL;
65 102
66 hvalue = avtab_hash(key, h->mask); 103 hvalue = avtab_hash(key, h->mask);
67 for (prev = NULL, cur = h->htable[hvalue]; 104 for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue);
68 cur; 105 cur;
69 prev = cur, cur = cur->next) { 106 prev = cur, cur = cur->next) {
70 if (key->source_type == cur->key.source_type && 107 if (key->source_type == cur->key.source_type &&
@@ -104,7 +141,7 @@ avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datu
104 if (!h || !h->htable) 141 if (!h || !h->htable)
105 return NULL; 142 return NULL;
106 hvalue = avtab_hash(key, h->mask); 143 hvalue = avtab_hash(key, h->mask);
107 for (prev = NULL, cur = h->htable[hvalue]; 144 for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue);
108 cur; 145 cur;
109 prev = cur, cur = cur->next) { 146 prev = cur, cur = cur->next) {
110 if (key->source_type == cur->key.source_type && 147 if (key->source_type == cur->key.source_type &&
@@ -135,7 +172,8 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
135 return NULL; 172 return NULL;
136 173
137 hvalue = avtab_hash(key, h->mask); 174 hvalue = avtab_hash(key, h->mask);
138 for (cur = h->htable[hvalue]; cur; cur = cur->next) { 175 for (cur = flex_array_get_ptr(h->htable, hvalue); cur;
176 cur = cur->next) {
139 if (key->source_type == cur->key.source_type && 177 if (key->source_type == cur->key.source_type &&
140 key->target_type == cur->key.target_type && 178 key->target_type == cur->key.target_type &&
141 key->target_class == cur->key.target_class && 179 key->target_class == cur->key.target_class &&
@@ -170,7 +208,8 @@ avtab_search_node(struct avtab *h, struct avtab_key *key)
170 return NULL; 208 return NULL;
171 209
172 hvalue = avtab_hash(key, h->mask); 210 hvalue = avtab_hash(key, h->mask);
173 for (cur = h->htable[hvalue]; cur; cur = cur->next) { 211 for (cur = flex_array_get_ptr(h->htable, hvalue); cur;
212 cur = cur->next) {
174 if (key->source_type == cur->key.source_type && 213 if (key->source_type == cur->key.source_type &&
175 key->target_type == cur->key.target_type && 214 key->target_type == cur->key.target_type &&
176 key->target_class == cur->key.target_class && 215 key->target_class == cur->key.target_class &&
@@ -228,15 +267,14 @@ void avtab_destroy(struct avtab *h)
228 return; 267 return;
229 268
230 for (i = 0; i < h->nslot; i++) { 269 for (i = 0; i < h->nslot; i++) {
231 cur = h->htable[i]; 270 cur = flex_array_get_ptr(h->htable, i);
232 while (cur) { 271 while (cur) {
233 temp = cur; 272 temp = cur;
234 cur = cur->next; 273 cur = cur->next;
235 kmem_cache_free(avtab_node_cachep, temp); 274 kmem_cache_free(avtab_node_cachep, temp);
236 } 275 }
237 h->htable[i] = NULL;
238 } 276 }
239 kfree(h->htable); 277 flex_array_free(h->htable);
240 h->htable = NULL; 278 h->htable = NULL;
241 h->nslot = 0; 279 h->nslot = 0;
242 h->mask = 0; 280 h->mask = 0;
@@ -251,7 +289,7 @@ int avtab_init(struct avtab *h)
251 289
252int avtab_alloc(struct avtab *h, u32 nrules) 290int avtab_alloc(struct avtab *h, u32 nrules)
253{ 291{
254 u16 mask = 0; 292 u32 mask = 0;
255 u32 shift = 0; 293 u32 shift = 0;
256 u32 work = nrules; 294 u32 work = nrules;
257 u32 nslot = 0; 295 u32 nslot = 0;
@@ -270,7 +308,8 @@ int avtab_alloc(struct avtab *h, u32 nrules)
270 nslot = MAX_AVTAB_HASH_BUCKETS; 308 nslot = MAX_AVTAB_HASH_BUCKETS;
271 mask = nslot - 1; 309 mask = nslot - 1;
272 310
273 h->htable = kcalloc(nslot, sizeof(*(h->htable)), GFP_KERNEL); 311 h->htable = flex_array_alloc(sizeof(struct avtab_node *), nslot,
312 GFP_KERNEL | __GFP_ZERO);
274 if (!h->htable) 313 if (!h->htable)
275 return -ENOMEM; 314 return -ENOMEM;
276 315
@@ -293,7 +332,7 @@ void avtab_hash_eval(struct avtab *h, char *tag)
293 max_chain_len = 0; 332 max_chain_len = 0;
294 chain2_len_sum = 0; 333 chain2_len_sum = 0;
295 for (i = 0; i < h->nslot; i++) { 334 for (i = 0; i < h->nslot; i++) {
296 cur = h->htable[i]; 335 cur = flex_array_get_ptr(h->htable, i);
297 if (cur) { 336 if (cur) {
298 slots_used++; 337 slots_used++;
299 chain_len = 0; 338 chain_len = 0;
@@ -534,7 +573,8 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp)
534 return rc; 573 return rc;
535 574
536 for (i = 0; i < a->nslot; i++) { 575 for (i = 0; i < a->nslot; i++) {
537 for (cur = a->htable[i]; cur; cur = cur->next) { 576 for (cur = flex_array_get_ptr(a->htable, i); cur;
577 cur = cur->next) {
538 rc = avtab_write_item(p, cur, fp); 578 rc = avtab_write_item(p, cur, fp);
539 if (rc) 579 if (rc)
540 return rc; 580 return rc;
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index 63ce2f9e441d..adb451cd44f9 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -23,6 +23,8 @@
23#ifndef _SS_AVTAB_H_ 23#ifndef _SS_AVTAB_H_
24#define _SS_AVTAB_H_ 24#define _SS_AVTAB_H_
25 25
26#include <linux/flex_array.h>
27
26struct avtab_key { 28struct avtab_key {
27 u16 source_type; /* source type */ 29 u16 source_type; /* source type */
28 u16 target_type; /* target type */ 30 u16 target_type; /* target type */
@@ -51,10 +53,10 @@ struct avtab_node {
51}; 53};
52 54
53struct avtab { 55struct avtab {
54 struct avtab_node **htable; 56 struct flex_array *htable;
55 u32 nel; /* number of elements */ 57 u32 nel; /* number of elements */
56 u32 nslot; /* number of hash slots */ 58 u32 nslot; /* number of hash slots */
57 u16 mask; /* mask to compute hash func */ 59 u32 mask; /* mask to compute hash func */
58 60
59}; 61};
60 62
@@ -84,7 +86,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified
84void avtab_cache_init(void); 86void avtab_cache_init(void);
85void avtab_cache_destroy(void); 87void avtab_cache_destroy(void);
86 88
87#define MAX_AVTAB_HASH_BITS 11 89#define MAX_AVTAB_HASH_BITS 16
88#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) 90#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
89 91
90#endif /* _SS_AVTAB_H_ */ 92#endif /* _SS_AVTAB_H_ */
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index d307b37ddc2b..e1088842232c 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -654,19 +654,15 @@ int mls_import_netlbl_cat(struct context *context,
654 654
655 rc = ebitmap_netlbl_import(&context->range.level[0].cat, 655 rc = ebitmap_netlbl_import(&context->range.level[0].cat,
656 secattr->attr.mls.cat); 656 secattr->attr.mls.cat);
657 if (rc != 0) 657 if (rc)
658 goto import_netlbl_cat_failure;
659
660 rc = ebitmap_cpy(&context->range.level[1].cat,
661 &context->range.level[0].cat);
662 if (rc != 0)
663 goto import_netlbl_cat_failure; 658 goto import_netlbl_cat_failure;
659 memcpy(&context->range.level[1].cat, &context->range.level[0].cat,
660 sizeof(context->range.level[0].cat));
664 661
665 return 0; 662 return 0;
666 663
667import_netlbl_cat_failure: 664import_netlbl_cat_failure:
668 ebitmap_destroy(&context->range.level[0].cat); 665 ebitmap_destroy(&context->range.level[0].cat);
669 ebitmap_destroy(&context->range.level[1].cat);
670 return rc; 666 return rc;
671} 667}
672#endif /* CONFIG_NETLABEL */ 668#endif /* CONFIG_NETLABEL */
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index a1d3944751b9..9e2d82070915 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -3179,13 +3179,9 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3179 ctx_new.type = ctx->type; 3179 ctx_new.type = ctx->type;
3180 mls_import_netlbl_lvl(&ctx_new, secattr); 3180 mls_import_netlbl_lvl(&ctx_new, secattr);
3181 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { 3181 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
3182 rc = ebitmap_netlbl_import(&ctx_new.range.level[0].cat, 3182 rc = mls_import_netlbl_cat(&ctx_new, secattr);
3183 secattr->attr.mls.cat);
3184 if (rc) 3183 if (rc)
3185 goto out; 3184 goto out;
3186 memcpy(&ctx_new.range.level[1].cat,
3187 &ctx_new.range.level[0].cat,
3188 sizeof(ctx_new.range.level[0].cat));
3189 } 3185 }
3190 rc = -EIDRM; 3186 rc = -EIDRM;
3191 if (!mls_context_isvalid(&policydb, &ctx_new)) 3187 if (!mls_context_isvalid(&policydb, &ctx_new))