Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'selinux-pr-20200803' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull selinux updates from Paul Moore:
"Beyond the usual smattering of bug fixes, we've got three small
improvements worth highlighting:

- improved SELinux policy symbol table performance due to a reworking
of the insert and search functions

- allow reading of SELinux labels before the policy is loaded,
allowing for some more "exotic" initramfs approaches

- improved checking an error reporting about process
class/permissions during SELinux policy load"

* tag 'selinux-pr-20200803' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
selinux: complete the inlining of hashtab functions
selinux: prepare for inlining of hashtab functions
selinux: specialize symtab insert and search functions
selinux: Fix spelling mistakes in the comments
selinux: fixed a checkpatch warning with the sizeof macro
selinux: log error messages on required process class / permissions
scripts/selinux/mdp: fix initial SID handling
selinux: allow reading labels before policy is loaded

+258 -166
+18 -5
scripts/selinux/mdp/mdp.c
··· 67 67 68 68 initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *); 69 69 /* print out the sids */ 70 - for (i = 1; i < initial_sid_to_string_len; i++) 71 - fprintf(fout, "sid %s\n", initial_sid_to_string[i]); 70 + for (i = 1; i < initial_sid_to_string_len; i++) { 71 + const char *name = initial_sid_to_string[i]; 72 + 73 + if (name) 74 + fprintf(fout, "sid %s\n", name); 75 + else 76 + fprintf(fout, "sid unused%d\n", i); 77 + } 72 78 fprintf(fout, "\n"); 73 79 74 80 /* print out the class permissions */ ··· 132 126 #define OBJUSERROLETYPE "user_u:object_r:base_t" 133 127 134 128 /* default sids */ 135 - for (i = 1; i < initial_sid_to_string_len; i++) 136 - fprintf(fout, "sid %s " SUBJUSERROLETYPE "%s\n", 137 - initial_sid_to_string[i], mls ? ":" SYSTEMLOW : ""); 129 + for (i = 1; i < initial_sid_to_string_len; i++) { 130 + const char *name = initial_sid_to_string[i]; 131 + 132 + if (name) 133 + fprintf(fout, "sid %s ", name); 134 + else 135 + fprintf(fout, "sid unused%d\n", i); 136 + fprintf(fout, SUBJUSERROLETYPE "%s\n", 137 + mls ? ":" SYSTEMLOW : ""); 138 + } 138 139 fprintf(fout, "\n"); 139 140 140 141 #define FS_USE(behavior, fstype) \
+6 -1
security/selinux/hooks.c
··· 3332 3332 char *context = NULL; 3333 3333 struct inode_security_struct *isec; 3334 3334 3335 - if (strcmp(name, XATTR_SELINUX_SUFFIX)) 3335 + /* 3336 + * If we're not initialized yet, then we can't validate contexts, so 3337 + * just let vfs_getxattr fall back to using the on-disk xattr. 3338 + */ 3339 + if (!selinux_initialized(&selinux_state) || 3340 + strcmp(name, XATTR_SELINUX_SUFFIX)) 3336 3341 return -EOPNOTSUPP; 3337 3342 3338 3343 /*
+1 -1
security/selinux/netif.c
··· 124 124 * @sid: interface SID 125 125 * 126 126 * Description: 127 - * This function determines the SID of a network interface by quering the 127 + * This function determines the SID of a network interface by querying the 128 128 * security policy. The result is added to the network interface table to 129 129 * speedup future queries. Returns zero on success, negative values on 130 130 * failure.
+1 -1
security/selinux/netnode.c
··· 181 181 * @sid: node SID 182 182 * 183 183 * Description: 184 - * This function determines the SID of a network address by quering the 184 + * This function determines the SID of a network address by querying the 185 185 * security policy. The result is added to the network address table to 186 186 * speedup future queries. Returns zero on success, negative values on 187 187 * failure.
+1 -1
security/selinux/netport.c
··· 130 130 * @sid: port SID 131 131 * 132 132 * Description: 133 - * This function determines the SID of a network port by quering the security 133 + * This function determines the SID of a network port by querying the security 134 134 * policy. The result is added to the network port table to speedup future 135 135 * queries. Returns zero on success, negative values on failure. 136 136 *
+4 -4
security/selinux/ss/conditional.c
··· 203 203 return 1; 204 204 } 205 205 206 - int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp) 206 + int cond_read_bool(struct policydb *p, struct symtab *s, void *fp) 207 207 { 208 208 char *key = NULL; 209 209 struct cond_bool_datum *booldatum; ··· 215 215 if (!booldatum) 216 216 return -ENOMEM; 217 217 218 - rc = next_entry(buf, fp, sizeof buf); 218 + rc = next_entry(buf, fp, sizeof(buf)); 219 219 if (rc) 220 220 goto err; 221 221 ··· 238 238 if (rc) 239 239 goto err; 240 240 key[len] = '\0'; 241 - rc = hashtab_insert(h, key, booldatum); 241 + rc = symtab_insert(s, key, booldatum); 242 242 if (rc) 243 243 goto err; 244 244 ··· 416 416 u32 i, len; 417 417 int rc; 418 418 419 - rc = next_entry(buf, fp, sizeof buf); 419 + rc = next_entry(buf, fp, sizeof(buf)); 420 420 if (rc) 421 421 return rc; 422 422
+1 -1
security/selinux/ss/conditional.h
··· 69 69 70 70 int cond_index_bool(void *key, void *datum, void *datap); 71 71 72 - int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp); 72 + int cond_read_bool(struct policydb *p, struct symtab *s, void *fp); 73 73 int cond_read_list(struct policydb *p, void *fp); 74 74 int cond_write_bool(void *key, void *datum, void *ptr); 75 75 int cond_write_list(struct policydb *p, void *fp);
+6 -53
security/selinux/ss/hashtab.c
··· 7 7 #include <linux/kernel.h> 8 8 #include <linux/slab.h> 9 9 #include <linux/errno.h> 10 - #include <linux/sched.h> 11 10 #include "hashtab.h" 12 11 13 12 static struct kmem_cache *hashtab_node_cachep; ··· 28 29 return nel == 0 ? 0 : roundup_pow_of_two(nel); 29 30 } 30 31 31 - int hashtab_init(struct hashtab *h, 32 - u32 (*hash_value)(struct hashtab *h, const void *key), 33 - int (*keycmp)(struct hashtab *h, const void *key1, 34 - const void *key2), 35 - u32 nel_hint) 32 + int hashtab_init(struct hashtab *h, u32 nel_hint) 36 33 { 37 34 h->size = hashtab_compute_size(nel_hint); 38 35 h->nel = 0; 39 - h->hash_value = hash_value; 40 - h->keycmp = keycmp; 41 36 if (!h->size) 42 37 return 0; 43 38 ··· 39 46 return h->htable ? 0 : -ENOMEM; 40 47 } 41 48 42 - int hashtab_insert(struct hashtab *h, void *key, void *datum) 49 + int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst, 50 + void *key, void *datum) 43 51 { 44 - u32 hvalue; 45 - struct hashtab_node *prev, *cur, *newnode; 46 - 47 - cond_resched(); 48 - 49 - if (!h->size || h->nel == HASHTAB_MAX_NODES) 50 - return -EINVAL; 51 - 52 - hvalue = h->hash_value(h, key); 53 - prev = NULL; 54 - cur = h->htable[hvalue]; 55 - while (cur && h->keycmp(h, key, cur->key) > 0) { 56 - prev = cur; 57 - cur = cur->next; 58 - } 59 - 60 - if (cur && (h->keycmp(h, key, cur->key) == 0)) 61 - return -EEXIST; 52 + struct hashtab_node *newnode; 62 53 63 54 newnode = kmem_cache_zalloc(hashtab_node_cachep, GFP_KERNEL); 64 55 if (!newnode) 65 56 return -ENOMEM; 66 57 newnode->key = key; 67 58 newnode->datum = datum; 68 - if (prev) { 69 - newnode->next = prev->next; 70 - prev->next = newnode; 71 - } else { 72 - newnode->next = h->htable[hvalue]; 73 - h->htable[hvalue] = newnode; 74 - } 59 + newnode->next = *dst; 60 + *dst = newnode; 75 61 76 62 h->nel++; 77 63 return 0; 78 - } 79 - 80 - void *hashtab_search(struct hashtab *h, const void *key) 81 - { 82 - u32 hvalue; 83 - struct hashtab_node *cur; 84 - 85 - if (!h->size) 86 - return NULL; 87 - 88 - hvalue = h->hash_value(h, key); 89 - cur = h->htable[hvalue]; 90 - while (cur && h->keycmp(h, key, cur->key) > 0) 91 - cur = cur->next; 92 - 93 - if (!cur || (h->keycmp(h, key, cur->key) != 0)) 94 - return NULL; 95 - 96 - return cur->datum; 97 64 } 98 65 99 66 void hashtab_destroy(struct hashtab *h)
+65 -12
security/selinux/ss/hashtab.h
··· 11 11 #ifndef _SS_HASHTAB_H_ 12 12 #define _SS_HASHTAB_H_ 13 13 14 - #define HASHTAB_MAX_NODES 0xffffffff 14 + #include <linux/types.h> 15 + #include <linux/errno.h> 16 + #include <linux/sched.h> 17 + 18 + #define HASHTAB_MAX_NODES U32_MAX 19 + 20 + struct hashtab_key_params { 21 + u32 (*hash)(const void *key); /* hash function */ 22 + int (*cmp)(const void *key1, const void *key2); 23 + /* key comparison function */ 24 + }; 15 25 16 26 struct hashtab_node { 17 27 void *key; ··· 33 23 struct hashtab_node **htable; /* hash table */ 34 24 u32 size; /* number of slots in hash table */ 35 25 u32 nel; /* number of elements in hash table */ 36 - u32 (*hash_value)(struct hashtab *h, const void *key); 37 - /* hash function */ 38 - int (*keycmp)(struct hashtab *h, const void *key1, const void *key2); 39 - /* key comparison function */ 40 26 }; 41 27 42 28 struct hashtab_info { ··· 45 39 * 46 40 * Returns -ENOMEM if insufficient space is available or 0 otherwise. 47 41 */ 48 - int hashtab_init(struct hashtab *h, 49 - u32 (*hash_value)(struct hashtab *h, const void *key), 50 - int (*keycmp)(struct hashtab *h, const void *key1, 51 - const void *key2), 52 - u32 nel_hint); 42 + int hashtab_init(struct hashtab *h, u32 nel_hint); 43 + 44 + int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst, 45 + void *key, void *datum); 53 46 54 47 /* 55 48 * Inserts the specified (key, datum) pair into the specified hash table. ··· 58 53 * -EINVAL for general errors or 59 54 0 otherwise. 60 55 */ 61 - int hashtab_insert(struct hashtab *h, void *k, void *d); 56 + static inline int hashtab_insert(struct hashtab *h, void *key, void *datum, 57 + struct hashtab_key_params key_params) 58 + { 59 + u32 hvalue; 60 + struct hashtab_node *prev, *cur; 61 + 62 + cond_resched(); 63 + 64 + if (!h->size || h->nel == HASHTAB_MAX_NODES) 65 + return -EINVAL; 66 + 67 + hvalue = key_params.hash(key) & (h->size - 1); 68 + prev = NULL; 69 + cur = h->htable[hvalue]; 70 + while (cur) { 71 + int cmp = key_params.cmp(key, cur->key); 72 + 73 + if (cmp == 0) 74 + return -EEXIST; 75 + if (cmp < 0) 76 + break; 77 + prev = cur; 78 + cur = cur->next; 79 + } 80 + 81 + return __hashtab_insert(h, prev ? &prev->next : &h->htable[hvalue], 82 + key, datum); 83 + } 62 84 63 85 /* 64 86 * Searches for the entry with the specified key in the hash table. ··· 93 61 * Returns NULL if no entry has the specified key or 94 62 * the datum of the entry otherwise. 95 63 */ 96 - void *hashtab_search(struct hashtab *h, const void *k); 64 + static inline void *hashtab_search(struct hashtab *h, const void *key, 65 + struct hashtab_key_params key_params) 66 + { 67 + u32 hvalue; 68 + struct hashtab_node *cur; 69 + 70 + if (!h->size) 71 + return NULL; 72 + 73 + hvalue = key_params.hash(key) & (h->size - 1); 74 + cur = h->htable[hvalue]; 75 + while (cur) { 76 + int cmp = key_params.cmp(key, cur->key); 77 + 78 + if (cmp == 0) 79 + return cur->datum; 80 + if (cmp < 0) 81 + break; 82 + cur = cur->next; 83 + } 84 + return NULL; 85 + } 97 86 98 87 /* 99 88 * Destroys the specified hash table.
+12 -11
security/selinux/ss/mls.c
··· 165 165 166 166 if (!l->sens || l->sens > p->p_levels.nprim) 167 167 return 0; 168 - levdatum = hashtab_search(&p->p_levels.table, 169 - sym_name(p, SYM_LEVELS, l->sens - 1)); 168 + levdatum = symtab_search(&p->p_levels, 169 + sym_name(p, SYM_LEVELS, l->sens - 1)); 170 170 if (!levdatum) 171 171 return 0; 172 172 ··· 293 293 *(next_cat++) = '\0'; 294 294 295 295 /* Parse sensitivity. */ 296 - levdatum = hashtab_search(&pol->p_levels.table, sensitivity); 296 + levdatum = symtab_search(&pol->p_levels, sensitivity); 297 297 if (!levdatum) 298 298 return -EINVAL; 299 299 context->range.level[l].sens = levdatum->level->sens; ··· 312 312 *rngptr++ = '\0'; 313 313 } 314 314 315 - catdatum = hashtab_search(&pol->p_cats.table, cur_cat); 315 + catdatum = symtab_search(&pol->p_cats, cur_cat); 316 316 if (!catdatum) 317 317 return -EINVAL; 318 318 ··· 325 325 if (rngptr == NULL) 326 326 continue; 327 327 328 - rngdatum = hashtab_search(&pol->p_cats.table, rngptr); 328 + rngdatum = symtab_search(&pol->p_cats, rngptr); 329 329 if (!rngdatum) 330 330 return -EINVAL; 331 331 ··· 458 458 return 0; 459 459 460 460 for (l = 0; l < 2; l++) { 461 - levdatum = hashtab_search(&newp->p_levels.table, 462 - sym_name(oldp, SYM_LEVELS, 463 - oldc->range.level[l].sens - 1)); 461 + char *name = sym_name(oldp, SYM_LEVELS, 462 + oldc->range.level[l].sens - 1); 463 + 464 + levdatum = symtab_search(&newp->p_levels, name); 464 465 465 466 if (!levdatum) 466 467 return -EINVAL; ··· 471 470 node, i) { 472 471 int rc; 473 472 474 - catdatum = hashtab_search(&newp->p_cats.table, 475 - sym_name(oldp, SYM_CATS, i)); 473 + catdatum = symtab_search(&newp->p_cats, 474 + sym_name(oldp, SYM_CATS, i)); 476 475 if (!catdatum) 477 476 return -EINVAL; 478 477 rc = ebitmap_set_bit(&newc->range.level[l].cat, ··· 507 506 rtr.source_type = scontext->type; 508 507 rtr.target_type = tcontext->type; 509 508 rtr.target_class = tclass; 510 - r = hashtab_search(&p->range_tr, &rtr); 509 + r = policydb_rangetr_search(p, &rtr); 511 510 if (r) 512 511 return mls_range_set(newcontext, r); 513 512
+95 -53
security/selinux/ss/policydb.c
··· 400 400 if (!key) 401 401 goto out; 402 402 403 - rc = hashtab_insert(&p->p_roles.table, key, role); 403 + rc = symtab_insert(&p->p_roles, key, role); 404 404 if (rc) 405 405 goto out; 406 406 ··· 411 411 return rc; 412 412 } 413 413 414 - static u32 filenametr_hash(struct hashtab *h, const void *k) 414 + static u32 filenametr_hash(const void *k) 415 415 { 416 416 const struct filename_trans_key *ft = k; 417 417 unsigned long hash; ··· 423 423 byte_num = 0; 424 424 while ((focus = ft->name[byte_num++])) 425 425 hash = partial_name_hash(focus, hash); 426 - return hash & (h->size - 1); 426 + return hash; 427 427 } 428 428 429 - static int filenametr_cmp(struct hashtab *h, const void *k1, const void *k2) 429 + static int filenametr_cmp(const void *k1, const void *k2) 430 430 { 431 431 const struct filename_trans_key *ft1 = k1; 432 432 const struct filename_trans_key *ft2 = k2; ··· 444 444 445 445 } 446 446 447 - static u32 rangetr_hash(struct hashtab *h, const void *k) 447 + static const struct hashtab_key_params filenametr_key_params = { 448 + .hash = filenametr_hash, 449 + .cmp = filenametr_cmp, 450 + }; 451 + 452 + struct filename_trans_datum *policydb_filenametr_search( 453 + struct policydb *p, struct filename_trans_key *key) 454 + { 455 + return hashtab_search(&p->filename_trans, key, filenametr_key_params); 456 + } 457 + 458 + static u32 rangetr_hash(const void *k) 448 459 { 449 460 const struct range_trans *key = k; 450 461 451 - return (key->source_type + (key->target_type << 3) + 452 - (key->target_class << 5)) & (h->size - 1); 462 + return key->source_type + (key->target_type << 3) + 463 + (key->target_class << 5); 453 464 } 454 465 455 - static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2) 466 + static int rangetr_cmp(const void *k1, const void *k2) 456 467 { 457 468 const struct range_trans *key1 = k1, *key2 = k2; 458 469 int v; ··· 481 470 return v; 482 471 } 483 472 484 - static u32 role_trans_hash(struct hashtab *h, const void *k) 473 + static const struct hashtab_key_params rangetr_key_params = { 474 + .hash = rangetr_hash, 475 + .cmp = rangetr_cmp, 476 + }; 477 + 478 + struct mls_range *policydb_rangetr_search(struct policydb *p, 479 + struct range_trans *key) 480 + { 481 + return hashtab_search(&p->range_tr, key, rangetr_key_params); 482 + } 483 + 484 + static u32 role_trans_hash(const void *k) 485 485 { 486 486 const struct role_trans_key *key = k; 487 487 488 - return (key->role + (key->type << 3) + (key->tclass << 5)) & 489 - (h->size - 1); 488 + return key->role + (key->type << 3) + (key->tclass << 5); 490 489 } 491 490 492 - static int role_trans_cmp(struct hashtab *h, const void *k1, const void *k2) 491 + static int role_trans_cmp(const void *k1, const void *k2) 493 492 { 494 493 const struct role_trans_key *key1 = k1, *key2 = k2; 495 494 int v; ··· 513 492 return v; 514 493 515 494 return key1->tclass - key2->tclass; 495 + } 496 + 497 + static const struct hashtab_key_params roletr_key_params = { 498 + .hash = role_trans_hash, 499 + .cmp = role_trans_cmp, 500 + }; 501 + 502 + struct role_trans_datum *policydb_roletr_search(struct policydb *p, 503 + struct role_trans_key *key) 504 + { 505 + return hashtab_search(&p->role_tr, key, roletr_key_params); 516 506 } 517 507 518 508 /* ··· 1097 1065 return 0; 1098 1066 } 1099 1067 1100 - static int perm_read(struct policydb *p, struct hashtab *h, void *fp) 1068 + static int perm_read(struct policydb *p, struct symtab *s, void *fp) 1101 1069 { 1102 1070 char *key = NULL; 1103 1071 struct perm_datum *perdatum; ··· 1120 1088 if (rc) 1121 1089 goto bad; 1122 1090 1123 - rc = hashtab_insert(h, key, perdatum); 1091 + rc = symtab_insert(s, key, perdatum); 1124 1092 if (rc) 1125 1093 goto bad; 1126 1094 ··· 1130 1098 return rc; 1131 1099 } 1132 1100 1133 - static int common_read(struct policydb *p, struct hashtab *h, void *fp) 1101 + static int common_read(struct policydb *p, struct symtab *s, void *fp) 1134 1102 { 1135 1103 char *key = NULL; 1136 1104 struct common_datum *comdatum; ··· 1160 1128 goto bad; 1161 1129 1162 1130 for (i = 0; i < nel; i++) { 1163 - rc = perm_read(p, &comdatum->permissions.table, fp); 1131 + rc = perm_read(p, &comdatum->permissions, fp); 1164 1132 if (rc) 1165 1133 goto bad; 1166 1134 } 1167 1135 1168 - rc = hashtab_insert(h, key, comdatum); 1136 + rc = symtab_insert(s, key, comdatum); 1169 1137 if (rc) 1170 1138 goto bad; 1171 1139 return 0; ··· 1294 1262 return 0; 1295 1263 } 1296 1264 1297 - static int class_read(struct policydb *p, struct hashtab *h, void *fp) 1265 + static int class_read(struct policydb *p, struct symtab *s, void *fp) 1298 1266 { 1299 1267 char *key = NULL; 1300 1268 struct class_datum *cladatum; ··· 1332 1300 goto bad; 1333 1301 1334 1302 rc = -EINVAL; 1335 - cladatum->comdatum = hashtab_search(&p->p_commons.table, 1336 - cladatum->comkey); 1303 + cladatum->comdatum = symtab_search(&p->p_commons, 1304 + cladatum->comkey); 1337 1305 if (!cladatum->comdatum) { 1338 1306 pr_err("SELinux: unknown common %s\n", 1339 1307 cladatum->comkey); ··· 1341 1309 } 1342 1310 } 1343 1311 for (i = 0; i < nel; i++) { 1344 - rc = perm_read(p, &cladatum->permissions.table, fp); 1312 + rc = perm_read(p, &cladatum->permissions, fp); 1345 1313 if (rc) 1346 1314 goto bad; 1347 1315 } ··· 1379 1347 cladatum->default_type = le32_to_cpu(buf[0]); 1380 1348 } 1381 1349 1382 - rc = hashtab_insert(h, key, cladatum); 1350 + rc = symtab_insert(s, key, cladatum); 1383 1351 if (rc) 1384 1352 goto bad; 1385 1353 ··· 1389 1357 return rc; 1390 1358 } 1391 1359 1392 - static int role_read(struct policydb *p, struct hashtab *h, void *fp) 1360 + static int role_read(struct policydb *p, struct symtab *s, void *fp) 1393 1361 { 1394 1362 char *key = NULL; 1395 1363 struct role_datum *role; ··· 1436 1404 goto bad; 1437 1405 } 1438 1406 1439 - rc = hashtab_insert(h, key, role); 1407 + rc = symtab_insert(s, key, role); 1440 1408 if (rc) 1441 1409 goto bad; 1442 1410 return 0; ··· 1445 1413 return rc; 1446 1414 } 1447 1415 1448 - static int type_read(struct policydb *p, struct hashtab *h, void *fp) 1416 + static int type_read(struct policydb *p, struct symtab *s, void *fp) 1449 1417 { 1450 1418 char *key = NULL; 1451 1419 struct type_datum *typdatum; ··· 1483 1451 if (rc) 1484 1452 goto bad; 1485 1453 1486 - rc = hashtab_insert(h, key, typdatum); 1454 + rc = symtab_insert(s, key, typdatum); 1487 1455 if (rc) 1488 1456 goto bad; 1489 1457 return 0; ··· 1519 1487 return 0; 1520 1488 } 1521 1489 1522 - static int user_read(struct policydb *p, struct hashtab *h, void *fp) 1490 + static int user_read(struct policydb *p, struct symtab *s, void *fp) 1523 1491 { 1524 1492 char *key = NULL; 1525 1493 struct user_datum *usrdatum; ··· 1560 1528 goto bad; 1561 1529 } 1562 1530 1563 - rc = hashtab_insert(h, key, usrdatum); 1531 + rc = symtab_insert(s, key, usrdatum); 1564 1532 if (rc) 1565 1533 goto bad; 1566 1534 return 0; ··· 1569 1537 return rc; 1570 1538 } 1571 1539 1572 - static int sens_read(struct policydb *p, struct hashtab *h, void *fp) 1540 + static int sens_read(struct policydb *p, struct symtab *s, void *fp) 1573 1541 { 1574 1542 char *key = NULL; 1575 1543 struct level_datum *levdatum; ··· 1601 1569 if (rc) 1602 1570 goto bad; 1603 1571 1604 - rc = hashtab_insert(h, key, levdatum); 1572 + rc = symtab_insert(s, key, levdatum); 1605 1573 if (rc) 1606 1574 goto bad; 1607 1575 return 0; ··· 1610 1578 return rc; 1611 1579 } 1612 1580 1613 - static int cat_read(struct policydb *p, struct hashtab *h, void *fp) 1581 + static int cat_read(struct policydb *p, struct symtab *s, void *fp) 1614 1582 { 1615 1583 char *key = NULL; 1616 1584 struct cat_datum *catdatum; ··· 1634 1602 if (rc) 1635 1603 goto bad; 1636 1604 1637 - rc = hashtab_insert(h, key, catdatum); 1605 + rc = symtab_insert(s, key, catdatum); 1638 1606 if (rc) 1639 1607 goto bad; 1640 1608 return 0; ··· 1643 1611 return rc; 1644 1612 } 1645 1613 1646 - static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) = 1614 + static int (*read_f[SYM_NUM]) (struct policydb *p, struct symtab *s, void *fp) = 1647 1615 { 1648 1616 common_read, 1649 1617 class_read, ··· 1783 1751 { 1784 1752 struct class_datum *cladatum; 1785 1753 1786 - cladatum = hashtab_search(&p->p_classes.table, name); 1754 + cladatum = symtab_search(&p->p_classes, name); 1787 1755 if (!cladatum) 1788 1756 return 0; 1789 1757 ··· 1802 1770 cladatum = p->class_val_to_struct[tclass-1]; 1803 1771 comdatum = cladatum->comdatum; 1804 1772 if (comdatum) 1805 - perdatum = hashtab_search(&comdatum->permissions.table, name); 1773 + perdatum = symtab_search(&comdatum->permissions, name); 1806 1774 if (!perdatum) 1807 - perdatum = hashtab_search(&cladatum->permissions.table, name); 1775 + perdatum = symtab_search(&cladatum->permissions, name); 1808 1776 if (!perdatum) 1809 1777 return 0; 1810 1778 ··· 1828 1796 1829 1797 nel = le32_to_cpu(buf[0]); 1830 1798 1831 - rc = hashtab_init(&p->range_tr, rangetr_hash, rangetr_cmp, nel); 1799 + rc = hashtab_init(&p->range_tr, nel); 1832 1800 if (rc) 1833 1801 return rc; 1834 1802 ··· 1873 1841 goto out; 1874 1842 } 1875 1843 1876 - rc = hashtab_insert(&p->range_tr, rt, r); 1844 + rc = hashtab_insert(&p->range_tr, rt, r, rangetr_key_params); 1877 1845 if (rc) 1878 1846 goto out; 1879 1847 ··· 1920 1888 otype = le32_to_cpu(buf[3]); 1921 1889 1922 1890 last = NULL; 1923 - datum = hashtab_search(&p->filename_trans, &key); 1891 + datum = policydb_filenametr_search(p, &key); 1924 1892 while (datum) { 1925 1893 if (unlikely(ebitmap_get_bit(&datum->stypes, stype - 1))) { 1926 1894 /* conflicting/duplicate rules are ignored */ ··· 1950 1918 if (!ft) 1951 1919 goto out; 1952 1920 1953 - rc = hashtab_insert(&p->filename_trans, ft, datum); 1921 + rc = hashtab_insert(&p->filename_trans, ft, datum, 1922 + filenametr_key_params); 1954 1923 if (rc) 1955 1924 goto out; 1956 1925 name = NULL; ··· 2039 2006 ft->tclass = tclass; 2040 2007 ft->name = name; 2041 2008 2042 - rc = hashtab_insert(&p->filename_trans, ft, first); 2009 + rc = hashtab_insert(&p->filename_trans, ft, first, 2010 + filenametr_key_params); 2043 2011 if (rc == -EEXIST) 2044 2012 pr_err("SELinux: Duplicate filename transition key\n"); 2045 2013 if (rc) ··· 2078 2044 if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) { 2079 2045 p->compat_filename_trans_count = nel; 2080 2046 2081 - rc = hashtab_init(&p->filename_trans, filenametr_hash, 2082 - filenametr_cmp, (1 << 11)); 2047 + rc = hashtab_init(&p->filename_trans, (1 << 11)); 2083 2048 if (rc) 2084 2049 return rc; 2085 2050 ··· 2088 2055 return rc; 2089 2056 } 2090 2057 } else { 2091 - rc = hashtab_init(&p->filename_trans, filenametr_hash, 2092 - filenametr_cmp, nel); 2058 + rc = hashtab_init(&p->filename_trans, nel); 2093 2059 if (rc) 2094 2060 return rc; 2095 2061 ··· 2408 2376 struct role_trans_datum *rtd = NULL; 2409 2377 int i, j, rc; 2410 2378 __le32 buf[4]; 2411 - u32 len, nprim, nel; 2379 + u32 len, nprim, nel, perm; 2412 2380 2413 2381 char *policydb_str; 2414 2382 struct policydb_compat_info *info; ··· 2541 2509 } 2542 2510 2543 2511 for (j = 0; j < nel; j++) { 2544 - rc = read_f[i](p, &p->symtab[i].table, fp); 2512 + rc = read_f[i](p, &p->symtab[i], fp); 2545 2513 if (rc) 2546 2514 goto bad; 2547 2515 } ··· 2551 2519 2552 2520 rc = -EINVAL; 2553 2521 p->process_class = string_to_security_class(p, "process"); 2554 - if (!p->process_class) 2522 + if (!p->process_class) { 2523 + pr_err("SELinux: process class is required, not defined in policy\n"); 2555 2524 goto bad; 2525 + } 2556 2526 2557 2527 rc = avtab_read(&p->te_avtab, fp, p); 2558 2528 if (rc) ··· 2571 2537 goto bad; 2572 2538 nel = le32_to_cpu(buf[0]); 2573 2539 2574 - rc = hashtab_init(&p->role_tr, role_trans_hash, role_trans_cmp, nel); 2540 + rc = hashtab_init(&p->role_tr, nel); 2575 2541 if (rc) 2576 2542 goto bad; 2577 2543 for (i = 0; i < nel; i++) { ··· 2608 2574 !policydb_role_isvalid(p, rtd->new_role)) 2609 2575 goto bad; 2610 2576 2611 - rc = hashtab_insert(&p->role_tr, rtk, rtd); 2577 + rc = hashtab_insert(&p->role_tr, rtk, rtd, roletr_key_params); 2612 2578 if (rc) 2613 2579 goto bad; 2614 2580 ··· 2652 2618 goto bad; 2653 2619 2654 2620 rc = -EINVAL; 2655 - p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition"); 2656 - p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition"); 2657 - if (!p->process_trans_perms) 2621 + perm = string_to_av_perm(p, p->process_class, "transition"); 2622 + if (!perm) { 2623 + pr_err("SELinux: process transition permission is required, not defined in policy\n"); 2658 2624 goto bad; 2625 + } 2626 + p->process_trans_perms = perm; 2627 + perm = string_to_av_perm(p, p->process_class, "dyntransition"); 2628 + if (!perm) { 2629 + pr_err("SELinux: process dyntransition permission is required, not defined in policy\n"); 2630 + goto bad; 2631 + } 2632 + p->process_trans_perms |= perm; 2659 2633 2660 2634 rc = ocontext_read(p, info, fp); 2661 2635 if (rc)
+9
security/selinux/ss/policydb.h
··· 324 324 extern int policydb_read(struct policydb *p, void *fp); 325 325 extern int policydb_write(struct policydb *p, void *fp); 326 326 327 + extern struct filename_trans_datum *policydb_filenametr_search( 328 + struct policydb *p, struct filename_trans_key *key); 329 + 330 + extern struct mls_range *policydb_rangetr_search( 331 + struct policydb *p, struct range_trans *key); 332 + 333 + extern struct role_trans_datum *policydb_roletr_search( 334 + struct policydb *p, struct role_trans_key *key); 335 + 327 336 #define POLICYDB_CONFIG_MLS 1 328 337 329 338 /* the config flags related to unknown classes/perms are bits 2 and 3 */
+19 -19
security/selinux/ss/services.c
··· 1441 1441 1442 1442 *p++ = 0; 1443 1443 1444 - usrdatum = hashtab_search(&pol->p_users.table, scontextp); 1444 + usrdatum = symtab_search(&pol->p_users, scontextp); 1445 1445 if (!usrdatum) 1446 1446 goto out; 1447 1447 ··· 1457 1457 1458 1458 *p++ = 0; 1459 1459 1460 - role = hashtab_search(&pol->p_roles.table, scontextp); 1460 + role = symtab_search(&pol->p_roles, scontextp); 1461 1461 if (!role) 1462 1462 goto out; 1463 1463 ctx->role = role->value; ··· 1469 1469 oldc = *p; 1470 1470 *p++ = 0; 1471 1471 1472 - typdatum = hashtab_search(&pol->p_types.table, scontextp); 1472 + typdatum = symtab_search(&pol->p_types, scontextp); 1473 1473 if (!typdatum || typdatum->attribute) 1474 1474 goto out; 1475 1475 ··· 1671 1671 ft.tclass = tclass; 1672 1672 ft.name = objname; 1673 1673 1674 - datum = hashtab_search(&policydb->filename_trans, &ft); 1674 + datum = policydb_filenametr_search(policydb, &ft); 1675 1675 while (datum) { 1676 1676 if (ebitmap_get_bit(&datum->stypes, stype - 1)) { 1677 1677 newcontext->type = datum->otype; ··· 1834 1834 .tclass = tclass, 1835 1835 }; 1836 1836 1837 - rtd = hashtab_search(&policydb->role_tr, &rtk); 1837 + rtd = policydb_roletr_search(policydb, &rtk); 1838 1838 if (rtd) 1839 1839 newcontext.role = rtd->new_role; 1840 1840 } ··· 2024 2024 2025 2025 /* Convert the user. */ 2026 2026 rc = -EINVAL; 2027 - usrdatum = hashtab_search(&args->newp->p_users.table, 2028 - sym_name(args->oldp, 2029 - SYM_USERS, oldc->user - 1)); 2027 + usrdatum = symtab_search(&args->newp->p_users, 2028 + sym_name(args->oldp, 2029 + SYM_USERS, oldc->user - 1)); 2030 2030 if (!usrdatum) 2031 2031 goto bad; 2032 2032 newc->user = usrdatum->value; 2033 2033 2034 2034 /* Convert the role. */ 2035 2035 rc = -EINVAL; 2036 - role = hashtab_search(&args->newp->p_roles.table, 2037 - sym_name(args->oldp, SYM_ROLES, oldc->role - 1)); 2036 + role = symtab_search(&args->newp->p_roles, 2037 + sym_name(args->oldp, SYM_ROLES, oldc->role - 1)); 2038 2038 if (!role) 2039 2039 goto bad; 2040 2040 newc->role = role->value; 2041 2041 2042 2042 /* Convert the type. */ 2043 2043 rc = -EINVAL; 2044 - typdatum = hashtab_search(&args->newp->p_types.table, 2045 - sym_name(args->oldp, 2046 - SYM_TYPES, oldc->type - 1)); 2044 + typdatum = symtab_search(&args->newp->p_types, 2045 + sym_name(args->oldp, 2046 + SYM_TYPES, oldc->type - 1)); 2047 2047 if (!typdatum) 2048 2048 goto bad; 2049 2049 newc->type = typdatum->value; ··· 2623 2623 goto out_unlock; 2624 2624 2625 2625 rc = -EINVAL; 2626 - user = hashtab_search(&policydb->p_users.table, username); 2626 + user = symtab_search(&policydb->p_users, username); 2627 2627 if (!user) 2628 2628 goto out_unlock; 2629 2629 ··· 2979 2979 if (rc) 2980 2980 goto out; 2981 2981 for (i = 0; i < nbools; i++) { 2982 - booldatum = hashtab_search(&policydb->p_bools.table, bnames[i]); 2982 + booldatum = symtab_search(&policydb->p_bools, bnames[i]); 2983 2983 if (booldatum) 2984 2984 booldatum->state = bvalues[i]; 2985 2985 } ··· 3230 3230 read_lock(&state->ss->policy_rwlock); 3231 3231 3232 3232 rc = -EINVAL; 3233 - match = hashtab_search(&policydb->p_classes.table, class); 3233 + match = symtab_search(&policydb->p_classes, class); 3234 3234 if (!match) { 3235 3235 pr_err("SELinux: %s: unrecognized class %s\n", 3236 3236 __func__, class); ··· 3369 3369 case AUDIT_SUBJ_USER: 3370 3370 case AUDIT_OBJ_USER: 3371 3371 rc = -EINVAL; 3372 - userdatum = hashtab_search(&policydb->p_users.table, rulestr); 3372 + userdatum = symtab_search(&policydb->p_users, rulestr); 3373 3373 if (!userdatum) 3374 3374 goto out; 3375 3375 tmprule->au_ctxt.user = userdatum->value; ··· 3377 3377 case AUDIT_SUBJ_ROLE: 3378 3378 case AUDIT_OBJ_ROLE: 3379 3379 rc = -EINVAL; 3380 - roledatum = hashtab_search(&policydb->p_roles.table, rulestr); 3380 + roledatum = symtab_search(&policydb->p_roles, rulestr); 3381 3381 if (!roledatum) 3382 3382 goto out; 3383 3383 tmprule->au_ctxt.role = roledatum->value; ··· 3385 3385 case AUDIT_SUBJ_TYPE: 3386 3386 case AUDIT_OBJ_TYPE: 3387 3387 rc = -EINVAL; 3388 - typedatum = hashtab_search(&policydb->p_types.table, rulestr); 3388 + typedatum = symtab_search(&policydb->p_types, rulestr); 3389 3389 if (!typedatum) 3390 3390 goto out; 3391 3391 tmprule->au_ctxt.type = typedatum->value;
+17 -4
security/selinux/ss/symtab.c
··· 9 9 #include <linux/errno.h> 10 10 #include "symtab.h" 11 11 12 - static unsigned int symhash(struct hashtab *h, const void *key) 12 + static unsigned int symhash(const void *key) 13 13 { 14 14 const char *p, *keyp; 15 15 unsigned int size; ··· 20 20 size = strlen(keyp); 21 21 for (p = keyp; (p - keyp) < size; p++) 22 22 val = (val << 4 | (val >> (8*sizeof(unsigned int)-4))) ^ (*p); 23 - return val & (h->size - 1); 23 + return val; 24 24 } 25 25 26 - static int symcmp(struct hashtab *h, const void *key1, const void *key2) 26 + static int symcmp(const void *key1, const void *key2) 27 27 { 28 28 const char *keyp1, *keyp2; 29 29 ··· 32 32 return strcmp(keyp1, keyp2); 33 33 } 34 34 35 + static const struct hashtab_key_params symtab_key_params = { 36 + .hash = symhash, 37 + .cmp = symcmp, 38 + }; 35 39 36 40 int symtab_init(struct symtab *s, unsigned int size) 37 41 { 38 42 s->nprim = 0; 39 - return hashtab_init(&s->table, symhash, symcmp, size); 43 + return hashtab_init(&s->table, size); 40 44 } 41 45 46 + int symtab_insert(struct symtab *s, char *name, void *datum) 47 + { 48 + return hashtab_insert(&s->table, name, datum, symtab_key_params); 49 + } 50 + 51 + void *symtab_search(struct symtab *s, const char *name) 52 + { 53 + return hashtab_search(&s->table, name, symtab_key_params); 54 + }
+3
security/selinux/ss/symtab.h
··· 19 19 20 20 int symtab_init(struct symtab *s, unsigned int size); 21 21 22 + int symtab_insert(struct symtab *s, char *name, void *datum); 23 + void *symtab_search(struct symtab *s, const char *name); 24 + 22 25 #endif /* _SS_SYMTAB_H_ */ 23 26 24 27