diff options
| author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-03-12 02:31:10 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-12 13:04:02 -0400 |
| commit | acdf52d97f824019888422842757013b37441dd1 (patch) | |
| tree | aedfff666343c46bb27e0f6adff03bfde05cbaff | |
| parent | b330e6a49dc3e9145de5c986b29bbbb884351e92 (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>
| -rw-r--r-- | security/selinux/ss/avtab.c | 40 | ||||
| -rw-r--r-- | security/selinux/ss/avtab.h | 4 | ||||
| -rw-r--r-- | security/selinux/ss/conditional.c | 6 | ||||
| -rw-r--r-- | security/selinux/ss/policydb.c | 122 | ||||
| -rw-r--r-- | security/selinux/ss/policydb.h | 12 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 22 |
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 | ||
| 304 | int avtab_init(struct avtab *h) | 302 | int 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 | ||
| 29 | struct avtab_key { | 28 | struct 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 | ||
| 86 | struct avtab { | 85 | struct 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 | ||
| 94 | int avtab_init(struct avtab *); | 92 | int 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 | ||
| 370 | static inline char *sym_name(struct policydb *p, unsigned int sym_num, unsigned int element_nr) | 368 | static 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 | ||
| 377 | extern u16 string_to_security_class(struct policydb *p, const char *name); | 373 | extern 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) { |
