summaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-03-12 02:31:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-12 13:04:02 -0400
commitacdf52d97f824019888422842757013b37441dd1 (patch)
treeaedfff666343c46bb27e0f6adff03bfde05cbaff /security/selinux
parentb330e6a49dc3e9145de5c986b29bbbb884351e92 (diff)
selinux: convert to kvmalloc
The flex arrays were being used for constant sized arrays, so there's no benefit to using flex_arrays over something simpler. Link: http://lkml.kernel.org/r/20181217131929.11727-4-kent.overstreet@gmail.com Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Cc: Paul Moore <paul@paul-moore.com> Cc: Stephen Smalley <sds@tycho.nsa.gov> Cc: Eric Paris <eparis@parisplace.org> Cc: Alexey Dobriyan <adobriyan@gmail.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Cc: Matthew Wilcox <willy@infradead.org> Cc: Neil Horman <nhorman@tuxdriver.com> Cc: Pravin B Shelar <pshelar@ovn.org> Cc: Shaohua Li <shli@kernel.org> Cc: Vlad Yasevich <vyasevich@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/ss/avtab.c40
-rw-r--r--security/selinux/ss/avtab.h4
-rw-r--r--security/selinux/ss/conditional.c6
-rw-r--r--security/selinux/ss/policydb.c122
-rw-r--r--security/selinux/ss/policydb.h12
-rw-r--r--security/selinux/ss/services.c22
6 files changed, 62 insertions, 144 deletions
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index c0417cf17fee..8c5800750fa8 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -93,12 +93,10 @@ avtab_insert_node(struct avtab *h, int hvalue,
93 newnode->next = prev->next; 93 newnode->next = prev->next;
94 prev->next = newnode; 94 prev->next = newnode;
95 } else { 95 } else {
96 newnode->next = flex_array_get_ptr(h->htable, hvalue); 96 struct avtab_node **n = &h->htable[hvalue];
97 if (flex_array_put_ptr(h->htable, hvalue, newnode, 97
98 GFP_KERNEL|__GFP_ZERO)) { 98 newnode->next = *n;
99 kmem_cache_free(avtab_node_cachep, newnode); 99 *n = newnode;
100 return NULL;
101 }
102 } 100 }
103 101
104 h->nel++; 102 h->nel++;
@@ -111,11 +109,11 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
111 struct avtab_node *prev, *cur, *newnode; 109 struct avtab_node *prev, *cur, *newnode;
112 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); 110 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
113 111
114 if (!h || !h->htable) 112 if (!h)
115 return -EINVAL; 113 return -EINVAL;
116 114
117 hvalue = avtab_hash(key, h->mask); 115 hvalue = avtab_hash(key, h->mask);
118 for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue); 116 for (prev = NULL, cur = h->htable[hvalue];
119 cur; 117 cur;
120 prev = cur, cur = cur->next) { 118 prev = cur, cur = cur->next) {
121 if (key->source_type == cur->key.source_type && 119 if (key->source_type == cur->key.source_type &&
@@ -156,10 +154,10 @@ avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datu
156 struct avtab_node *prev, *cur; 154 struct avtab_node *prev, *cur;
157 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); 155 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
158 156
159 if (!h || !h->htable) 157 if (!h)
160 return NULL; 158 return NULL;
161 hvalue = avtab_hash(key, h->mask); 159 hvalue = avtab_hash(key, h->mask);
162 for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue); 160 for (prev = NULL, cur = h->htable[hvalue];
163 cur; 161 cur;
164 prev = cur, cur = cur->next) { 162 prev = cur, cur = cur->next) {
165 if (key->source_type == cur->key.source_type && 163 if (key->source_type == cur->key.source_type &&
@@ -186,11 +184,11 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
186 struct avtab_node *cur; 184 struct avtab_node *cur;
187 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); 185 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
188 186
189 if (!h || !h->htable) 187 if (!h)
190 return NULL; 188 return NULL;
191 189
192 hvalue = avtab_hash(key, h->mask); 190 hvalue = avtab_hash(key, h->mask);
193 for (cur = flex_array_get_ptr(h->htable, hvalue); cur; 191 for (cur = h->htable[hvalue]; cur;
194 cur = cur->next) { 192 cur = cur->next) {
195 if (key->source_type == cur->key.source_type && 193 if (key->source_type == cur->key.source_type &&
196 key->target_type == cur->key.target_type && 194 key->target_type == cur->key.target_type &&
@@ -222,11 +220,11 @@ avtab_search_node(struct avtab *h, struct avtab_key *key)
222 struct avtab_node *cur; 220 struct avtab_node *cur;
223 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); 221 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
224 222
225 if (!h || !h->htable) 223 if (!h)
226 return NULL; 224 return NULL;
227 225
228 hvalue = avtab_hash(key, h->mask); 226 hvalue = avtab_hash(key, h->mask);
229 for (cur = flex_array_get_ptr(h->htable, hvalue); cur; 227 for (cur = h->htable[hvalue]; cur;
230 cur = cur->next) { 228 cur = cur->next) {
231 if (key->source_type == cur->key.source_type && 229 if (key->source_type == cur->key.source_type &&
232 key->target_type == cur->key.target_type && 230 key->target_type == cur->key.target_type &&
@@ -281,11 +279,11 @@ void avtab_destroy(struct avtab *h)
281 int i; 279 int i;
282 struct avtab_node *cur, *temp; 280 struct avtab_node *cur, *temp;
283 281
284 if (!h || !h->htable) 282 if (!h)
285 return; 283 return;
286 284
287 for (i = 0; i < h->nslot; i++) { 285 for (i = 0; i < h->nslot; i++) {
288 cur = flex_array_get_ptr(h->htable, i); 286 cur = h->htable[i];
289 while (cur) { 287 while (cur) {
290 temp = cur; 288 temp = cur;
291 cur = cur->next; 289 cur = cur->next;
@@ -295,7 +293,7 @@ void avtab_destroy(struct avtab *h)
295 kmem_cache_free(avtab_node_cachep, temp); 293 kmem_cache_free(avtab_node_cachep, temp);
296 } 294 }
297 } 295 }
298 flex_array_free(h->htable); 296 kvfree(h->htable);
299 h->htable = NULL; 297 h->htable = NULL;
300 h->nslot = 0; 298 h->nslot = 0;
301 h->mask = 0; 299 h->mask = 0;
@@ -303,6 +301,7 @@ void avtab_destroy(struct avtab *h)
303 301
304int avtab_init(struct avtab *h) 302int avtab_init(struct avtab *h)
305{ 303{
304 kvfree(h->htable);
306 h->htable = NULL; 305 h->htable = NULL;
307 h->nel = 0; 306 h->nel = 0;
308 return 0; 307 return 0;
@@ -329,8 +328,7 @@ int avtab_alloc(struct avtab *h, u32 nrules)
329 nslot = MAX_AVTAB_HASH_BUCKETS; 328 nslot = MAX_AVTAB_HASH_BUCKETS;
330 mask = nslot - 1; 329 mask = nslot - 1;
331 330
332 h->htable = flex_array_alloc(sizeof(struct avtab_node *), nslot, 331 h->htable = kvcalloc(nslot, sizeof(void *), GFP_KERNEL);
333 GFP_KERNEL | __GFP_ZERO);
334 if (!h->htable) 332 if (!h->htable)
335 return -ENOMEM; 333 return -ENOMEM;
336 334
@@ -353,7 +351,7 @@ void avtab_hash_eval(struct avtab *h, char *tag)
353 max_chain_len = 0; 351 max_chain_len = 0;
354 chain2_len_sum = 0; 352 chain2_len_sum = 0;
355 for (i = 0; i < h->nslot; i++) { 353 for (i = 0; i < h->nslot; i++) {
356 cur = flex_array_get_ptr(h->htable, i); 354 cur = h->htable[i];
357 if (cur) { 355 if (cur) {
358 slots_used++; 356 slots_used++;
359 chain_len = 0; 357 chain_len = 0;
@@ -646,7 +644,7 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp)
646 return rc; 644 return rc;
647 645
648 for (i = 0; i < a->nslot; i++) { 646 for (i = 0; i < a->nslot; i++) {
649 for (cur = flex_array_get_ptr(a->htable, i); cur; 647 for (cur = a->htable[i]; cur;
650 cur = cur->next) { 648 cur = cur->next) {
651 rc = avtab_write_item(p, cur, fp); 649 rc = avtab_write_item(p, cur, fp);
652 if (rc) 650 if (rc)
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index 0d652fad5319..de16673b2314 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -24,7 +24,6 @@
24#define _SS_AVTAB_H_ 24#define _SS_AVTAB_H_
25 25
26#include "security.h" 26#include "security.h"
27#include <linux/flex_array.h>
28 27
29struct avtab_key { 28struct avtab_key {
30 u16 source_type; /* source type */ 29 u16 source_type; /* source type */
@@ -84,11 +83,10 @@ struct avtab_node {
84}; 83};
85 84
86struct avtab { 85struct avtab {
87 struct flex_array *htable; 86 struct avtab_node **htable;
88 u32 nel; /* number of elements */ 87 u32 nel; /* number of elements */
89 u32 nslot; /* number of hash slots */ 88 u32 nslot; /* number of hash slots */
90 u32 mask; /* mask to compute hash func */ 89 u32 mask; /* mask to compute hash func */
91
92}; 90};
93 91
94int avtab_init(struct avtab *); 92int avtab_init(struct avtab *);
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index f49e522e932d..3bbb60345209 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -195,7 +195,6 @@ int cond_index_bool(void *key, void *datum, void *datap)
195{ 195{
196 struct policydb *p; 196 struct policydb *p;
197 struct cond_bool_datum *booldatum; 197 struct cond_bool_datum *booldatum;
198 struct flex_array *fa;
199 198
200 booldatum = datum; 199 booldatum = datum;
201 p = datap; 200 p = datap;
@@ -203,10 +202,7 @@ int cond_index_bool(void *key, void *datum, void *datap)
203 if (!booldatum->value || booldatum->value > p->p_bools.nprim) 202 if (!booldatum->value || booldatum->value > p->p_bools.nprim)
204 return -EINVAL; 203 return -EINVAL;
205 204
206 fa = p->sym_val_to_name[SYM_BOOLS]; 205 p->sym_val_to_name[SYM_BOOLS][booldatum->value - 1] = key;
207 if (flex_array_put_ptr(fa, booldatum->value - 1, key,
208 GFP_KERNEL | __GFP_ZERO))
209 BUG();
210 p->bool_val_to_struct[booldatum->value - 1] = booldatum; 206 p->bool_val_to_struct[booldatum->value - 1] = booldatum;
211 207
212 return 0; 208 return 0;
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index c1c31e33657a..6b576e588725 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -36,7 +36,6 @@
36#include <linux/string.h> 36#include <linux/string.h>
37#include <linux/errno.h> 37#include <linux/errno.h>
38#include <linux/audit.h> 38#include <linux/audit.h>
39#include <linux/flex_array.h>
40#include "security.h" 39#include "security.h"
41 40
42#include "policydb.h" 41#include "policydb.h"
@@ -341,17 +340,14 @@ static int common_index(void *key, void *datum, void *datap)
341{ 340{
342 struct policydb *p; 341 struct policydb *p;
343 struct common_datum *comdatum; 342 struct common_datum *comdatum;
344 struct flex_array *fa;
345 343
346 comdatum = datum; 344 comdatum = datum;
347 p = datap; 345 p = datap;
348 if (!comdatum->value || comdatum->value > p->p_commons.nprim) 346 if (!comdatum->value || comdatum->value > p->p_commons.nprim)
349 return -EINVAL; 347 return -EINVAL;
350 348
351 fa = p->sym_val_to_name[SYM_COMMONS]; 349 p->sym_val_to_name[SYM_COMMONS][comdatum->value - 1] = key;
352 if (flex_array_put_ptr(fa, comdatum->value - 1, key, 350
353 GFP_KERNEL | __GFP_ZERO))
354 BUG();
355 return 0; 351 return 0;
356} 352}
357 353
@@ -359,16 +355,13 @@ static int class_index(void *key, void *datum, void *datap)
359{ 355{
360 struct policydb *p; 356 struct policydb *p;
361 struct class_datum *cladatum; 357 struct class_datum *cladatum;
362 struct flex_array *fa;
363 358
364 cladatum = datum; 359 cladatum = datum;
365 p = datap; 360 p = datap;
366 if (!cladatum->value || cladatum->value > p->p_classes.nprim) 361 if (!cladatum->value || cladatum->value > p->p_classes.nprim)
367 return -EINVAL; 362 return -EINVAL;
368 fa = p->sym_val_to_name[SYM_CLASSES]; 363
369 if (flex_array_put_ptr(fa, cladatum->value - 1, key, 364 p->sym_val_to_name[SYM_CLASSES][cladatum->value - 1] = key;
370 GFP_KERNEL | __GFP_ZERO))
371 BUG();
372 p->class_val_to_struct[cladatum->value - 1] = cladatum; 365 p->class_val_to_struct[cladatum->value - 1] = cladatum;
373 return 0; 366 return 0;
374} 367}
@@ -377,7 +370,6 @@ static int role_index(void *key, void *datum, void *datap)
377{ 370{
378 struct policydb *p; 371 struct policydb *p;
379 struct role_datum *role; 372 struct role_datum *role;
380 struct flex_array *fa;
381 373
382 role = datum; 374 role = datum;
383 p = datap; 375 p = datap;
@@ -386,10 +378,7 @@ static int role_index(void *key, void *datum, void *datap)
386 || role->bounds > p->p_roles.nprim) 378 || role->bounds > p->p_roles.nprim)
387 return -EINVAL; 379 return -EINVAL;
388 380
389 fa = p->sym_val_to_name[SYM_ROLES]; 381 p->sym_val_to_name[SYM_ROLES][role->value - 1] = key;
390 if (flex_array_put_ptr(fa, role->value - 1, key,
391 GFP_KERNEL | __GFP_ZERO))
392 BUG();
393 p->role_val_to_struct[role->value - 1] = role; 382 p->role_val_to_struct[role->value - 1] = role;
394 return 0; 383 return 0;
395} 384}
@@ -398,7 +387,6 @@ static int type_index(void *key, void *datum, void *datap)
398{ 387{
399 struct policydb *p; 388 struct policydb *p;
400 struct type_datum *typdatum; 389 struct type_datum *typdatum;
401 struct flex_array *fa;
402 390
403 typdatum = datum; 391 typdatum = datum;
404 p = datap; 392 p = datap;
@@ -408,15 +396,8 @@ static int type_index(void *key, void *datum, void *datap)
408 || typdatum->value > p->p_types.nprim 396 || typdatum->value > p->p_types.nprim
409 || typdatum->bounds > p->p_types.nprim) 397 || typdatum->bounds > p->p_types.nprim)
410 return -EINVAL; 398 return -EINVAL;
411 fa = p->sym_val_to_name[SYM_TYPES]; 399 p->sym_val_to_name[SYM_TYPES][typdatum->value - 1] = key;
412 if (flex_array_put_ptr(fa, typdatum->value - 1, key, 400 p->type_val_to_struct_array[typdatum->value - 1] = typdatum;
413 GFP_KERNEL | __GFP_ZERO))
414 BUG();
415
416 fa = p->type_val_to_struct_array;
417 if (flex_array_put_ptr(fa, typdatum->value - 1, typdatum,
418 GFP_KERNEL | __GFP_ZERO))
419 BUG();
420 } 401 }
421 402
422 return 0; 403 return 0;
@@ -426,7 +407,6 @@ static int user_index(void *key, void *datum, void *datap)
426{ 407{
427 struct policydb *p; 408 struct policydb *p;
428 struct user_datum *usrdatum; 409 struct user_datum *usrdatum;
429 struct flex_array *fa;
430 410
431 usrdatum = datum; 411 usrdatum = datum;
432 p = datap; 412 p = datap;
@@ -435,10 +415,7 @@ static int user_index(void *key, void *datum, void *datap)
435 || usrdatum->bounds > p->p_users.nprim) 415 || usrdatum->bounds > p->p_users.nprim)
436 return -EINVAL; 416 return -EINVAL;
437 417
438 fa = p->sym_val_to_name[SYM_USERS]; 418 p->sym_val_to_name[SYM_USERS][usrdatum->value - 1] = key;
439 if (flex_array_put_ptr(fa, usrdatum->value - 1, key,
440 GFP_KERNEL | __GFP_ZERO))
441 BUG();
442 p->user_val_to_struct[usrdatum->value - 1] = usrdatum; 419 p->user_val_to_struct[usrdatum->value - 1] = usrdatum;
443 return 0; 420 return 0;
444} 421}
@@ -447,7 +424,6 @@ static int sens_index(void *key, void *datum, void *datap)
447{ 424{
448 struct policydb *p; 425 struct policydb *p;
449 struct level_datum *levdatum; 426 struct level_datum *levdatum;
450 struct flex_array *fa;
451 427
452 levdatum = datum; 428 levdatum = datum;
453 p = datap; 429 p = datap;
@@ -456,10 +432,8 @@ static int sens_index(void *key, void *datum, void *datap)
456 if (!levdatum->level->sens || 432 if (!levdatum->level->sens ||
457 levdatum->level->sens > p->p_levels.nprim) 433 levdatum->level->sens > p->p_levels.nprim)
458 return -EINVAL; 434 return -EINVAL;
459 fa = p->sym_val_to_name[SYM_LEVELS]; 435
460 if (flex_array_put_ptr(fa, levdatum->level->sens - 1, key, 436 p->sym_val_to_name[SYM_LEVELS][levdatum->level->sens - 1] = key;
461 GFP_KERNEL | __GFP_ZERO))
462 BUG();
463 } 437 }
464 438
465 return 0; 439 return 0;
@@ -469,7 +443,6 @@ static int cat_index(void *key, void *datum, void *datap)
469{ 443{
470 struct policydb *p; 444 struct policydb *p;
471 struct cat_datum *catdatum; 445 struct cat_datum *catdatum;
472 struct flex_array *fa;
473 446
474 catdatum = datum; 447 catdatum = datum;
475 p = datap; 448 p = datap;
@@ -477,10 +450,8 @@ static int cat_index(void *key, void *datum, void *datap)
477 if (!catdatum->isalias) { 450 if (!catdatum->isalias) {
478 if (!catdatum->value || catdatum->value > p->p_cats.nprim) 451 if (!catdatum->value || catdatum->value > p->p_cats.nprim)
479 return -EINVAL; 452 return -EINVAL;
480 fa = p->sym_val_to_name[SYM_CATS]; 453
481 if (flex_array_put_ptr(fa, catdatum->value - 1, key, 454 p->sym_val_to_name[SYM_CATS][catdatum->value - 1] = key;
482 GFP_KERNEL | __GFP_ZERO))
483 BUG();
484 } 455 }
485 456
486 return 0; 457 return 0;
@@ -568,35 +539,23 @@ static int policydb_index(struct policydb *p)
568 if (!p->user_val_to_struct) 539 if (!p->user_val_to_struct)
569 return -ENOMEM; 540 return -ENOMEM;
570 541
571 /* Yes, I want the sizeof the pointer, not the structure */ 542 p->type_val_to_struct_array = kvcalloc(p->p_types.nprim,
572 p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *), 543 sizeof(*p->type_val_to_struct_array),
573 p->p_types.nprim, 544 GFP_KERNEL);
574 GFP_KERNEL | __GFP_ZERO);
575 if (!p->type_val_to_struct_array) 545 if (!p->type_val_to_struct_array)
576 return -ENOMEM; 546 return -ENOMEM;
577 547
578 rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
579 p->p_types.nprim, GFP_KERNEL | __GFP_ZERO);
580 if (rc)
581 goto out;
582
583 rc = cond_init_bool_indexes(p); 548 rc = cond_init_bool_indexes(p);
584 if (rc) 549 if (rc)
585 goto out; 550 goto out;
586 551
587 for (i = 0; i < SYM_NUM; i++) { 552 for (i = 0; i < SYM_NUM; i++) {
588 p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *), 553 p->sym_val_to_name[i] = kvcalloc(p->symtab[i].nprim,
589 p->symtab[i].nprim, 554 sizeof(char *),
590 GFP_KERNEL | __GFP_ZERO); 555 GFP_KERNEL);
591 if (!p->sym_val_to_name[i]) 556 if (!p->sym_val_to_name[i])
592 return -ENOMEM; 557 return -ENOMEM;
593 558
594 rc = flex_array_prealloc(p->sym_val_to_name[i],
595 0, p->symtab[i].nprim,
596 GFP_KERNEL | __GFP_ZERO);
597 if (rc)
598 goto out;
599
600 rc = hashtab_map(p->symtab[i].table, index_f[i], p); 559 rc = hashtab_map(p->symtab[i].table, index_f[i], p);
601 if (rc) 560 if (rc)
602 goto out; 561 goto out;
@@ -810,16 +769,13 @@ void policydb_destroy(struct policydb *p)
810 hashtab_destroy(p->symtab[i].table); 769 hashtab_destroy(p->symtab[i].table);
811 } 770 }
812 771
813 for (i = 0; i < SYM_NUM; i++) { 772 for (i = 0; i < SYM_NUM; i++)
814 if (p->sym_val_to_name[i]) 773 kvfree(p->sym_val_to_name[i]);
815 flex_array_free(p->sym_val_to_name[i]);
816 }
817 774
818 kfree(p->class_val_to_struct); 775 kfree(p->class_val_to_struct);
819 kfree(p->role_val_to_struct); 776 kfree(p->role_val_to_struct);
820 kfree(p->user_val_to_struct); 777 kfree(p->user_val_to_struct);
821 if (p->type_val_to_struct_array) 778 kvfree(p->type_val_to_struct_array);
822 flex_array_free(p->type_val_to_struct_array);
823 779
824 avtab_destroy(&p->te_avtab); 780 avtab_destroy(&p->te_avtab);
825 781
@@ -872,17 +828,9 @@ void policydb_destroy(struct policydb *p)
872 hashtab_map(p->range_tr, range_tr_destroy, NULL); 828 hashtab_map(p->range_tr, range_tr_destroy, NULL);
873 hashtab_destroy(p->range_tr); 829 hashtab_destroy(p->range_tr);
874 830
875 if (p->type_attr_map_array) { 831 for (i = 0; i < p->p_types.nprim; i++)
876 for (i = 0; i < p->p_types.nprim; i++) { 832 ebitmap_destroy(&p->type_attr_map_array[i]);
877 struct ebitmap *e; 833 kvfree(p->type_attr_map_array);
878
879 e = flex_array_get(p->type_attr_map_array, i);
880 if (!e)
881 continue;
882 ebitmap_destroy(e);
883 }
884 flex_array_free(p->type_attr_map_array);
885 }
886 834
887 ebitmap_destroy(&p->filename_trans_ttypes); 835 ebitmap_destroy(&p->filename_trans_ttypes);
888 ebitmap_destroy(&p->policycaps); 836 ebitmap_destroy(&p->policycaps);
@@ -1770,8 +1718,7 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap)
1770 return -EINVAL; 1718 return -EINVAL;
1771 } 1719 }
1772 1720
1773 upper = flex_array_get_ptr(p->type_val_to_struct_array, 1721 upper = p->type_val_to_struct_array[upper->bounds - 1];
1774 upper->bounds - 1);
1775 BUG_ON(!upper); 1722 BUG_ON(!upper);
1776 1723
1777 if (upper->attribute) { 1724 if (upper->attribute) {
@@ -2543,23 +2490,15 @@ int policydb_read(struct policydb *p, void *fp)
2543 if (rc) 2490 if (rc)
2544 goto bad; 2491 goto bad;
2545 2492
2546 rc = -ENOMEM; 2493 p->type_attr_map_array = kvcalloc(p->p_types.nprim,
2547 p->type_attr_map_array = flex_array_alloc(sizeof(struct ebitmap), 2494 sizeof(*p->type_attr_map_array),
2548 p->p_types.nprim, 2495 GFP_KERNEL);
2549 GFP_KERNEL | __GFP_ZERO);
2550 if (!p->type_attr_map_array) 2496 if (!p->type_attr_map_array)
2551 goto bad; 2497 goto bad;
2552 2498
2553 /* preallocate so we don't have to worry about the put ever failing */
2554 rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim,
2555 GFP_KERNEL | __GFP_ZERO);
2556 if (rc)
2557 goto bad;
2558
2559 for (i = 0; i < p->p_types.nprim; i++) { 2499 for (i = 0; i < p->p_types.nprim; i++) {
2560 struct ebitmap *e = flex_array_get(p->type_attr_map_array, i); 2500 struct ebitmap *e = &p->type_attr_map_array[i];
2561 2501
2562 BUG_ON(!e);
2563 ebitmap_init(e); 2502 ebitmap_init(e);
2564 if (p->policyvers >= POLICYDB_VERSION_AVTAB) { 2503 if (p->policyvers >= POLICYDB_VERSION_AVTAB) {
2565 rc = ebitmap_read(e, fp); 2504 rc = ebitmap_read(e, fp);
@@ -3554,9 +3493,8 @@ int policydb_write(struct policydb *p, void *fp)
3554 return rc; 3493 return rc;
3555 3494
3556 for (i = 0; i < p->p_types.nprim; i++) { 3495 for (i = 0; i < p->p_types.nprim; i++) {
3557 struct ebitmap *e = flex_array_get(p->type_attr_map_array, i); 3496 struct ebitmap *e = &p->type_attr_map_array[i];
3558 3497
3559 BUG_ON(!e);
3560 rc = ebitmap_write(e, fp); 3498 rc = ebitmap_write(e, fp);
3561 if (rc) 3499 if (rc)
3562 return rc; 3500 return rc;
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 215f8f30ac5a..27039149ff0a 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -24,8 +24,6 @@
24#ifndef _SS_POLICYDB_H_ 24#ifndef _SS_POLICYDB_H_
25#define _SS_POLICYDB_H_ 25#define _SS_POLICYDB_H_
26 26
27#include <linux/flex_array.h>
28
29#include "symtab.h" 27#include "symtab.h"
30#include "avtab.h" 28#include "avtab.h"
31#include "sidtab.h" 29#include "sidtab.h"
@@ -251,13 +249,13 @@ struct policydb {
251#define p_cats symtab[SYM_CATS] 249#define p_cats symtab[SYM_CATS]
252 250
253 /* symbol names indexed by (value - 1) */ 251 /* symbol names indexed by (value - 1) */
254 struct flex_array *sym_val_to_name[SYM_NUM]; 252 char **sym_val_to_name[SYM_NUM];
255 253
256 /* class, role, and user attributes indexed by (value - 1) */ 254 /* class, role, and user attributes indexed by (value - 1) */
257 struct class_datum **class_val_to_struct; 255 struct class_datum **class_val_to_struct;
258 struct role_datum **role_val_to_struct; 256 struct role_datum **role_val_to_struct;
259 struct user_datum **user_val_to_struct; 257 struct user_datum **user_val_to_struct;
260 struct flex_array *type_val_to_struct_array; 258 struct type_datum **type_val_to_struct_array;
261 259
262 /* type enforcement access vectors and transitions */ 260 /* type enforcement access vectors and transitions */
263 struct avtab te_avtab; 261 struct avtab te_avtab;
@@ -294,7 +292,7 @@ struct policydb {
294 struct hashtab *range_tr; 292 struct hashtab *range_tr;
295 293
296 /* type -> attribute reverse mapping */ 294 /* type -> attribute reverse mapping */
297 struct flex_array *type_attr_map_array; 295 struct ebitmap *type_attr_map_array;
298 296
299 struct ebitmap policycaps; 297 struct ebitmap policycaps;
300 298
@@ -369,9 +367,7 @@ static inline int put_entry(const void *buf, size_t bytes, int num, struct polic
369 367
370static inline char *sym_name(struct policydb *p, unsigned int sym_num, unsigned int element_nr) 368static inline char *sym_name(struct policydb *p, unsigned int sym_num, unsigned int element_nr)
371{ 369{
372 struct flex_array *fa = p->sym_val_to_name[sym_num]; 370 return p->sym_val_to_name[sym_num][element_nr];
373
374 return flex_array_get_ptr(fa, element_nr);
375} 371}
376 372
377extern u16 string_to_security_class(struct policydb *p, const char *name); 373extern u16 string_to_security_class(struct policydb *p, const char *name);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 1269e2be3c2d..ec62918521b1 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -49,7 +49,6 @@
49#include <linux/sched.h> 49#include <linux/sched.h>
50#include <linux/audit.h> 50#include <linux/audit.h>
51#include <linux/mutex.h> 51#include <linux/mutex.h>
52#include <linux/flex_array.h>
53#include <linux/vmalloc.h> 52#include <linux/vmalloc.h>
54#include <net/netlabel.h> 53#include <net/netlabel.h>
55 54
@@ -545,15 +544,13 @@ static void type_attribute_bounds_av(struct policydb *policydb,
545 struct type_datum *target; 544 struct type_datum *target;
546 u32 masked = 0; 545 u32 masked = 0;
547 546
548 source = flex_array_get_ptr(policydb->type_val_to_struct_array, 547 source = policydb->type_val_to_struct_array[scontext->type - 1];
549 scontext->type - 1);
550 BUG_ON(!source); 548 BUG_ON(!source);
551 549
552 if (!source->bounds) 550 if (!source->bounds)
553 return; 551 return;
554 552
555 target = flex_array_get_ptr(policydb->type_val_to_struct_array, 553 target = policydb->type_val_to_struct_array[tcontext->type - 1];
556 tcontext->type - 1);
557 BUG_ON(!target); 554 BUG_ON(!target);
558 555
559 memset(&lo_avd, 0, sizeof(lo_avd)); 556 memset(&lo_avd, 0, sizeof(lo_avd));
@@ -653,11 +650,9 @@ static void context_struct_compute_av(struct policydb *policydb,
653 */ 650 */
654 avkey.target_class = tclass; 651 avkey.target_class = tclass;
655 avkey.specified = AVTAB_AV | AVTAB_XPERMS; 652 avkey.specified = AVTAB_AV | AVTAB_XPERMS;
656 sattr = flex_array_get(policydb->type_attr_map_array, 653 sattr = &policydb->type_attr_map_array[scontext->type - 1];
657 scontext->type - 1);
658 BUG_ON(!sattr); 654 BUG_ON(!sattr);
659 tattr = flex_array_get(policydb->type_attr_map_array, 655 tattr = &policydb->type_attr_map_array[tcontext->type - 1];
660 tcontext->type - 1);
661 BUG_ON(!tattr); 656 BUG_ON(!tattr);
662 ebitmap_for_each_positive_bit(sattr, snode, i) { 657 ebitmap_for_each_positive_bit(sattr, snode, i) {
663 ebitmap_for_each_positive_bit(tattr, tnode, j) { 658 ebitmap_for_each_positive_bit(tattr, tnode, j) {
@@ -900,8 +895,7 @@ int security_bounded_transition(struct selinux_state *state,
900 895
901 index = new_context->type; 896 index = new_context->type;
902 while (true) { 897 while (true) {
903 type = flex_array_get_ptr(policydb->type_val_to_struct_array, 898 type = policydb->type_val_to_struct_array[index - 1];
904 index - 1);
905 BUG_ON(!type); 899 BUG_ON(!type);
906 900
907 /* not bounded anymore */ 901 /* not bounded anymore */
@@ -1064,11 +1058,9 @@ void security_compute_xperms_decision(struct selinux_state *state,
1064 1058
1065 avkey.target_class = tclass; 1059 avkey.target_class = tclass;
1066 avkey.specified = AVTAB_XPERMS; 1060 avkey.specified = AVTAB_XPERMS;
1067 sattr = flex_array_get(policydb->type_attr_map_array, 1061 sattr = &policydb->type_attr_map_array[scontext->type - 1];
1068 scontext->type - 1);
1069 BUG_ON(!sattr); 1062 BUG_ON(!sattr);
1070 tattr = flex_array_get(policydb->type_attr_map_array, 1063 tattr = &policydb->type_attr_map_array[tcontext->type - 1];
1071 tcontext->type - 1);
1072 BUG_ON(!tattr); 1064 BUG_ON(!tattr);
1073 ebitmap_for_each_positive_bit(sattr, snode, i) { 1065 ebitmap_for_each_positive_bit(sattr, snode, i) {
1074 ebitmap_for_each_positive_bit(tattr, tnode, j) { 1066 ebitmap_for_each_positive_bit(tattr, tnode, j) {