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
Unified · Split
| @@ -67,8 +67,14 @@ int main(int argc, char *argv[]) · 66 unmodified lines | ||
| 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 */ |
| @@ -126,9 +132,16 @@ int main(int argc, char *argv[]) · 51 unmodified lines | ||
| 126 | 132 | #define OBJUSERROLETYPE "user_u:object_r:base_t" |
| 127 | 133 | |
| 128 | 134 | /* default sids */ |
| 129 | − for (i = 1; i < initial_sid_to_string_len; i++) | |
| 130 | − fprintf(fout, "sid %s " SUBJUSERROLETYPE "%s\n", | |
| 131 | − initial_sid_to_string[i], mls ? ":" SYSTEMLOW : ""); | |
| 135 | + for (i = 1; i < initial_sid_to_string_len; i++) { | |
| 136 | + const char *name = initial_sid_to_string[i]; | |
| 137 | + | |
| 138 | + if (name) | |
| 139 | + fprintf(fout, "sid %s ", name); | |
| 140 | + else | |
| 141 | + fprintf(fout, "sid unused%d\n", i); | |
| 142 | + fprintf(fout, SUBJUSERROLETYPE "%s\n", | |
| 143 | + mls ? ":" SYSTEMLOW : ""); | |
| 144 | + } | |
| 132 | 145 | fprintf(fout, "\n"); |
| 133 | 146 | |
| 134 | 147 | #define FS_USE(behavior, fstype) \ |
| @@ -3332,7 +3332,12 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void · 3331 unmodified lines | ||
| 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 | /* |
| @@ -124,7 +124,7 @@ static void sel_netif_destroy(struct sel_netif *netif) · 123 unmodified lines | ||
| 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. |
| @@ -181,7 +181,7 @@ static void sel_netnode_insert(struct sel_netnode *node) · 180 unmodified lines | ||
| 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. |
| @@ -130,7 +130,7 @@ static void sel_netport_insert(struct sel_netport *port) · 129 unmodified lines | ||
| 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 | * |
| @@ -203,7 +203,7 @@ static int bool_isvalid(struct cond_bool_datum *b) · 202 unmodified lines | ||
| 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,7 +215,7 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp) · 5 unmodified lines | ||
| 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,7 +238,7 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp) · 16 unmodified lines | ||
| 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,7 +416,7 @@ int cond_read_list(struct policydb *p, void *fp) · 171 unmodified lines | ||
| 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 | |
| @@ -69,7 +69,7 @@ int cond_destroy_bool(void *key, void *datum, void *p); · 68 unmodified lines | ||
| 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); |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | ||
| 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; |
| @@ -29,16 +28,10 @@ static u32 hashtab_compute_size(u32 nel) · 15 unmodified lines | ||
| 29 | 28 | return nel == 0 ? 0 : roundup_pow_of_two(nel); |
| 30 | 29 | } |
| 31 | 30 | |
| 32 | −int hashtab_init(struct hashtab *h, | |
| 33 | − u32 (*hash_value)(struct hashtab *h, const void *key), | |
| 34 | − int (*keycmp)(struct hashtab *h, const void *key1, | |
| 35 | − const void *key2), | |
| 36 | − u32 nel_hint) | |
| 31 | +int hashtab_init(struct hashtab *h, u32 nel_hint) | |
| 37 | 32 | { |
| 38 | 33 | h->size = hashtab_compute_size(nel_hint); |
| 39 | 34 | h->nel = 0; |
| 40 | − h->hash_value = hash_value; | |
| 41 | − h->keycmp = keycmp; | |
| 42 | 35 | if (!h->size) |
| 43 | 36 | return 0; |
| 44 | 37 | |
| @@ -46,63 +39,23 @@ int hashtab_init(struct hashtab *h, · 1 unmodified line | ||
| 46 | 39 | return h->htable ? 0 : -ENOMEM; |
| 47 | 40 | } |
| 48 | 41 | |
| 49 | −int hashtab_insert(struct hashtab *h, void *key, void *datum) | |
| 42 | +int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst, | |
| 43 | + void *key, void *datum) | |
| 50 | 44 | { |
| 51 | − u32 hvalue; | |
| 52 | − struct hashtab_node *prev, *cur, *newnode; | |
| 53 | − | |
| 54 | − cond_resched(); | |
| 55 | − | |
| 56 | − if (!h->size || h->nel == HASHTAB_MAX_NODES) | |
| 57 | − return -EINVAL; | |
| 58 | − | |
| 59 | − hvalue = h->hash_value(h, key); | |
| 60 | − prev = NULL; | |
| 61 | − cur = h->htable[hvalue]; | |
| 62 | − while (cur && h->keycmp(h, key, cur->key) > 0) { | |
| 63 | − prev = cur; | |
| 64 | − cur = cur->next; | |
| 65 | − } | |
| 66 | − | |
| 67 | − if (cur && (h->keycmp(h, key, cur->key) == 0)) | |
| 68 | − return -EEXIST; | |
| 45 | + struct hashtab_node *newnode; | |
| 69 | 46 | |
| 70 | 47 | newnode = kmem_cache_zalloc(hashtab_node_cachep, GFP_KERNEL); |
| 71 | 48 | if (!newnode) |
| 72 | 49 | return -ENOMEM; |
| 73 | 50 | newnode->key = key; |
| 74 | 51 | newnode->datum = datum; |
| 75 | − if (prev) { | |
| 76 | − newnode->next = prev->next; | |
| 77 | − prev->next = newnode; | |
| 78 | − } else { | |
| 79 | − newnode->next = h->htable[hvalue]; | |
| 80 | − h->htable[hvalue] = newnode; | |
| 81 | − } | |
| 52 | + newnode->next = *dst; | |
| 53 | + *dst = newnode; | |
| 82 | 54 | |
| 83 | 55 | h->nel++; |
| 84 | 56 | return 0; |
| 85 | 57 | } |
| 86 | 58 | |
| 87 | −void *hashtab_search(struct hashtab *h, const void *key) | |
| 88 | −{ | |
| 89 | − u32 hvalue; | |
| 90 | − struct hashtab_node *cur; | |
| 91 | − | |
| 92 | − if (!h->size) | |
| 93 | − return NULL; | |
| 94 | − | |
| 95 | − hvalue = h->hash_value(h, key); | |
| 96 | − cur = h->htable[hvalue]; | |
| 97 | − while (cur && h->keycmp(h, key, cur->key) > 0) | |
| 98 | − cur = cur->next; | |
| 99 | − | |
| 100 | − if (!cur || (h->keycmp(h, key, cur->key) != 0)) | |
| 101 | − return NULL; | |
| 102 | − | |
| 103 | − return cur->datum; | |
| 104 | −} | |
| 105 | − | |
| 106 | 59 | void hashtab_destroy(struct hashtab *h) |
| 107 | 60 | { |
| 108 | 61 | u32 i; |
| @@ -11,7 +11,17 @@ · 10 unmodified lines | ||
| 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; |
| @@ -23,10 +33,6 @@ struct hashtab { · 5 unmodified lines | ||
| 23 | 33 | struct hashtab_node **htable; /* hash table */ |
| 24 | 34 | u32 size; /* number of slots in hash table */ |
| 25 | 35 | u32 nel; /* number of elements in hash table */ |
| 26 | − u32 (*hash_value)(struct hashtab *h, const void *key); | |
| 27 | − /* hash function */ | |
| 28 | − int (*keycmp)(struct hashtab *h, const void *key1, const void *key2); | |
| 29 | − /* key comparison function */ | |
| 30 | 36 | }; |
| 31 | 37 | |
| 32 | 38 | struct hashtab_info { |
| @@ -39,11 +45,10 @@ struct hashtab_info { · 6 unmodified lines | ||
| 39 | 45 | * |
| 40 | 46 | * Returns -ENOMEM if insufficient space is available or 0 otherwise. |
| 41 | 47 | */ |
| 42 | −int hashtab_init(struct hashtab *h, | |
| 43 | − u32 (*hash_value)(struct hashtab *h, const void *key), | |
| 44 | − int (*keycmp)(struct hashtab *h, const void *key1, | |
| 45 | − const void *key2), | |
| 46 | − u32 nel_hint); | |
| 48 | +int hashtab_init(struct hashtab *h, u32 nel_hint); | |
| 49 | + | |
| 50 | +int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst, | |
| 51 | + void *key, void *datum); | |
| 47 | 52 | |
| 48 | 53 | /* |
| 49 | 54 | * Inserts the specified (key, datum) pair into the specified hash table. |
| @@ -53,7 +58,34 @@ int hashtab_init(struct hashtab *h, · 3 unmodified lines | ||
| 53 | 58 | * -EINVAL for general errors or |
| 54 | 59 | 0 otherwise. |
| 55 | 60 | */ |
| 56 | −int hashtab_insert(struct hashtab *h, void *k, void *d); | |
| 61 | +static inline int hashtab_insert(struct hashtab *h, void *key, void *datum, | |
| 62 | + struct hashtab_key_params key_params) | |
| 63 | +{ | |
| 64 | + u32 hvalue; | |
| 65 | + struct hashtab_node *prev, *cur; | |
| 66 | + | |
| 67 | + cond_resched(); | |
| 68 | + | |
| 69 | + if (!h->size || h->nel == HASHTAB_MAX_NODES) | |
| 70 | + return -EINVAL; | |
| 71 | + | |
| 72 | + hvalue = key_params.hash(key) & (h->size - 1); | |
| 73 | + prev = NULL; | |
| 74 | + cur = h->htable[hvalue]; | |
| 75 | + while (cur) { | |
| 76 | + int cmp = key_params.cmp(key, cur->key); | |
| 77 | + | |
| 78 | + if (cmp == 0) | |
| 79 | + return -EEXIST; | |
| 80 | + if (cmp < 0) | |
| 81 | + break; | |
| 82 | + prev = cur; | |
| 83 | + cur = cur->next; | |
| 84 | + } | |
| 85 | + | |
| 86 | + return __hashtab_insert(h, prev ? &prev->next : &h->htable[hvalue], | |
| 87 | + key, datum); | |
| 88 | +} | |
| 57 | 89 | |
| 58 | 90 | /* |
| 59 | 91 | * Searches for the entry with the specified key in the hash table. |
| @@ -61,7 +93,28 @@ int hashtab_insert(struct hashtab *h, void *k, void *d); · 1 unmodified line | ||
| 61 | 93 | * Returns NULL if no entry has the specified key or |
| 62 | 94 | * the datum of the entry otherwise. |
| 63 | 95 | */ |
| 64 | −void *hashtab_search(struct hashtab *h, const void *k); | |
| 96 | +static inline void *hashtab_search(struct hashtab *h, const void *key, | |
| 97 | + struct hashtab_key_params key_params) | |
| 98 | +{ | |
| 99 | + u32 hvalue; | |
| 100 | + struct hashtab_node *cur; | |
| 101 | + | |
| 102 | + if (!h->size) | |
| 103 | + return NULL; | |
| 104 | + | |
| 105 | + hvalue = key_params.hash(key) & (h->size - 1); | |
| 106 | + cur = h->htable[hvalue]; | |
| 107 | + while (cur) { | |
| 108 | + int cmp = key_params.cmp(key, cur->key); | |
| 109 | + | |
| 110 | + if (cmp == 0) | |
| 111 | + return cur->datum; | |
| 112 | + if (cmp < 0) | |
| 113 | + break; | |
| 114 | + cur = cur->next; | |
| 115 | + } | |
| 116 | + return NULL; | |
| 117 | +} | |
| 65 | 118 | |
| 66 | 119 | /* |
| 67 | 120 | * Destroys the specified hash table. |
| @@ -165,8 +165,8 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l) · 164 unmodified lines | ||
| 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,7 +293,7 @@ int mls_context_to_sid(struct policydb *pol, · 120 unmodified lines | ||
| 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,7 +312,7 @@ int mls_context_to_sid(struct policydb *pol, · 12 unmodified lines | ||
| 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,7 +325,7 @@ int mls_context_to_sid(struct policydb *pol, · 6 unmodified lines | ||
| 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,9 +458,10 @@ int mls_convert_context(struct policydb *oldp, · 126 unmodified lines | ||
| 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; |
| @@ -470,8 +471,8 @@ int mls_convert_context(struct policydb *oldp, · 3 unmodified lines | ||
| 470 | 471 | node, i) { |
| 471 | 472 | int rc; |
| 472 | 473 | |
| 473 | − catdatum = hashtab_search(&newp->p_cats.table, | |
| 474 | − sym_name(oldp, SYM_CATS, i)); | |
| 474 | + catdatum = symtab_search(&newp->p_cats, | |
| 475 | + sym_name(oldp, SYM_CATS, i)); | |
| 475 | 476 | if (!catdatum) |
| 476 | 477 | return -EINVAL; |
| 477 | 478 | rc = ebitmap_set_bit(&newc->range.level[l].cat, |
| @@ -506,7 +507,7 @@ int mls_compute_sid(struct policydb *p, · 28 unmodified lines | ||
| 506 | 507 | rtr.source_type = scontext->type; |
| 507 | 508 | rtr.target_type = tcontext->type; |
| 508 | 509 | rtr.target_class = tclass; |
| 509 | − r = hashtab_search(&p->range_tr, &rtr); | |
| 510 | + r = policydb_rangetr_search(p, &rtr); | |
| 510 | 511 | if (r) |
| 511 | 512 | return mls_range_set(newcontext, r); |
| 512 | 513 | |
| @@ -400,7 +400,7 @@ static int roles_init(struct policydb *p) · 399 unmodified lines | ||
| 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,7 +411,7 @@ out: · 4 unmodified lines | ||
| 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,10 +423,10 @@ static u32 filenametr_hash(struct hashtab *h, const void *k) · 5 unmodified lines | ||
| 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,15 +444,26 @@ static int filenametr_cmp(struct hashtab *h, const void *k1, const void *k2) · 11 unmodified lines | ||
| 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; |
| @@ -470,15 +481,25 @@ static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2) · 11 unmodified lines | ||
| 470 | 481 | return v; |
| 471 | 482 | } |
| 472 | 483 | |
| 473 | −static u32 role_trans_hash(struct hashtab *h, const void *k) | |
| 484 | +static const struct hashtab_key_params rangetr_key_params = { | |
| 485 | + .hash = rangetr_hash, | |
| 486 | + .cmp = rangetr_cmp, | |
| 487 | +}; | |
| 488 | + | |
| 489 | +struct mls_range *policydb_rangetr_search(struct policydb *p, | |
| 490 | + struct range_trans *key) | |
| 491 | +{ | |
| 492 | + return hashtab_search(&p->range_tr, key, rangetr_key_params); | |
| 493 | +} | |
| 494 | + | |
| 495 | +static u32 role_trans_hash(const void *k) | |
| 474 | 496 | { |
| 475 | 497 | const struct role_trans_key *key = k; |
| 476 | 498 | |
| 477 | − return (key->role + (key->type << 3) + (key->tclass << 5)) & | |
| 478 | − (h->size - 1); | |
| 499 | + return key->role + (key->type << 3) + (key->tclass << 5); | |
| 479 | 500 | } |
| 480 | 501 | |
| 481 | −static int role_trans_cmp(struct hashtab *h, const void *k1, const void *k2) | |
| 502 | +static int role_trans_cmp(const void *k1, const void *k2) | |
| 482 | 503 | { |
| 483 | 504 | const struct role_trans_key *key1 = k1, *key2 = k2; |
| 484 | 505 | int v; |
| @@ -494,6 +515,17 @@ static int role_trans_cmp(struct hashtab *h, const void *k1, const void *k2) · 9 unmodified lines | ||
| 494 | 515 | return key1->tclass - key2->tclass; |
| 495 | 516 | } |
| 496 | 517 | |
| 518 | +static const struct hashtab_key_params roletr_key_params = { | |
| 519 | + .hash = role_trans_hash, | |
| 520 | + .cmp = role_trans_cmp, | |
| 521 | +}; | |
| 522 | + | |
| 523 | +struct role_trans_datum *policydb_roletr_search(struct policydb *p, | |
| 524 | + struct role_trans_key *key) | |
| 525 | +{ | |
| 526 | + return hashtab_search(&p->role_tr, key, roletr_key_params); | |
| 527 | +} | |
| 528 | + | |
| 497 | 529 | /* |
| 498 | 530 | * Initialize a policy database structure. |
| 499 | 531 | */ |
| @@ -1065,7 +1097,7 @@ static int str_read(char **strp, gfp_t flags, void *fp, u32 len) · 565 unmodified lines | ||
| 1065 | 1097 | return 0; |
| 1066 | 1098 | } |
| 1067 | 1099 | |
| 1068 | −static int perm_read(struct policydb *p, struct hashtab *h, void *fp) | |
| 1100 | +static int perm_read(struct policydb *p, struct symtab *s, void *fp) | |
| 1069 | 1101 | { |
| 1070 | 1102 | char *key = NULL; |
| 1071 | 1103 | struct perm_datum *perdatum; |
| @@ -1088,7 +1120,7 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp) · 16 unmodified lines | ||
| 1088 | 1120 | if (rc) |
| 1089 | 1121 | goto bad; |
| 1090 | 1122 | |
| 1091 | − rc = hashtab_insert(h, key, perdatum); | |
| 1123 | + rc = symtab_insert(s, key, perdatum); | |
| 1092 | 1124 | if (rc) |
| 1093 | 1125 | goto bad; |
| 1094 | 1126 | |
| @@ -1098,7 +1130,7 @@ bad: · 3 unmodified lines | ||
| 1098 | 1130 | return rc; |
| 1099 | 1131 | } |
| 1100 | 1132 | |
| 1101 | −static int common_read(struct policydb *p, struct hashtab *h, void *fp) | |
| 1133 | +static int common_read(struct policydb *p, struct symtab *s, void *fp) | |
| 1102 | 1134 | { |
| 1103 | 1135 | char *key = NULL; |
| 1104 | 1136 | struct common_datum *comdatum; |
| @@ -1128,12 +1160,12 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) · 23 unmodified lines | ||
| 1128 | 1160 | goto bad; |
| 1129 | 1161 | |
| 1130 | 1162 | for (i = 0; i < nel; i++) { |
| 1131 | − rc = perm_read(p, &comdatum->permissions.table, fp); | |
| 1163 | + rc = perm_read(p, &comdatum->permissions, fp); | |
| 1132 | 1164 | if (rc) |
| 1133 | 1165 | goto bad; |
| 1134 | 1166 | } |
| 1135 | 1167 | |
| 1136 | − rc = hashtab_insert(h, key, comdatum); | |
| 1168 | + rc = symtab_insert(s, key, comdatum); | |
| 1137 | 1169 | if (rc) |
| 1138 | 1170 | goto bad; |
| 1139 | 1171 | return 0; |
| @@ -1262,7 +1294,7 @@ static int read_cons_helper(struct policydb *p, · 122 unmodified lines | ||
| 1262 | 1294 | return 0; |
| 1263 | 1295 | } |
| 1264 | 1296 | |
| 1265 | −static int class_read(struct policydb *p, struct hashtab *h, void *fp) | |
| 1297 | +static int class_read(struct policydb *p, struct symtab *s, void *fp) | |
| 1266 | 1298 | { |
| 1267 | 1299 | char *key = NULL; |
| 1268 | 1300 | struct class_datum *cladatum; |
| @@ -1300,8 +1332,8 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) · 31 unmodified lines | ||
| 1300 | 1332 | goto bad; |
| 1301 | 1333 | |
| 1302 | 1334 | rc = -EINVAL; |
| 1303 | − cladatum->comdatum = hashtab_search(&p->p_commons.table, | |
| 1304 | − cladatum->comkey); | |
| 1335 | + cladatum->comdatum = symtab_search(&p->p_commons, | |
| 1336 | + cladatum->comkey); | |
| 1305 | 1337 | if (!cladatum->comdatum) { |
| 1306 | 1338 | pr_err("SELinux: unknown common %s\n", |
| 1307 | 1339 | cladatum->comkey); |
| @@ -1309,7 +1341,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) · 1 unmodified line | ||
| 1309 | 1341 | } |
| 1310 | 1342 | } |
| 1311 | 1343 | for (i = 0; i < nel; i++) { |
| 1312 | − rc = perm_read(p, &cladatum->permissions.table, fp); | |
| 1344 | + rc = perm_read(p, &cladatum->permissions, fp); | |
| 1313 | 1345 | if (rc) |
| 1314 | 1346 | goto bad; |
| 1315 | 1347 | } |
| @@ -1347,7 +1379,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) · 31 unmodified lines | ||
| 1347 | 1379 | cladatum->default_type = le32_to_cpu(buf[0]); |
| 1348 | 1380 | } |
| 1349 | 1381 | |
| 1350 | − rc = hashtab_insert(h, key, cladatum); | |
| 1382 | + rc = symtab_insert(s, key, cladatum); | |
| 1351 | 1383 | if (rc) |
| 1352 | 1384 | goto bad; |
| 1353 | 1385 | |
| @@ -1357,7 +1389,7 @@ bad: · 3 unmodified lines | ||
| 1357 | 1389 | return rc; |
| 1358 | 1390 | } |
| 1359 | 1391 | |
| 1360 | −static int role_read(struct policydb *p, struct hashtab *h, void *fp) | |
| 1392 | +static int role_read(struct policydb *p, struct symtab *s, void *fp) | |
| 1361 | 1393 | { |
| 1362 | 1394 | char *key = NULL; |
| 1363 | 1395 | struct role_datum *role; |
| @@ -1404,7 +1436,7 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) · 40 unmodified lines | ||
| 1404 | 1436 | goto bad; |
| 1405 | 1437 | } |
| 1406 | 1438 | |
| 1407 | − rc = hashtab_insert(h, key, role); | |
| 1439 | + rc = symtab_insert(s, key, role); | |
| 1408 | 1440 | if (rc) |
| 1409 | 1441 | goto bad; |
| 1410 | 1442 | return 0; |
| @@ -1413,7 +1445,7 @@ bad: · 2 unmodified lines | ||
| 1413 | 1445 | return rc; |
| 1414 | 1446 | } |
| 1415 | 1447 | |
| 1416 | −static int type_read(struct policydb *p, struct hashtab *h, void *fp) | |
| 1448 | +static int type_read(struct policydb *p, struct symtab *s, void *fp) | |
| 1417 | 1449 | { |
| 1418 | 1450 | char *key = NULL; |
| 1419 | 1451 | struct type_datum *typdatum; |
| @@ -1451,7 +1483,7 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) · 31 unmodified lines | ||
| 1451 | 1483 | if (rc) |
| 1452 | 1484 | goto bad; |
| 1453 | 1485 | |
| 1454 | − rc = hashtab_insert(h, key, typdatum); | |
| 1486 | + rc = symtab_insert(s, key, typdatum); | |
| 1455 | 1487 | if (rc) |
| 1456 | 1488 | goto bad; |
| 1457 | 1489 | return 0; |
| @@ -1487,7 +1519,7 @@ static int mls_read_level(struct mls_level *lp, void *fp) · 29 unmodified lines | ||
| 1487 | 1519 | return 0; |
| 1488 | 1520 | } |
| 1489 | 1521 | |
| 1490 | −static int user_read(struct policydb *p, struct hashtab *h, void *fp) | |
| 1522 | +static int user_read(struct policydb *p, struct symtab *s, void *fp) | |
| 1491 | 1523 | { |
| 1492 | 1524 | char *key = NULL; |
| 1493 | 1525 | struct user_datum *usrdatum; |
| @@ -1528,7 +1560,7 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) · 34 unmodified lines | ||
| 1528 | 1560 | goto bad; |
| 1529 | 1561 | } |
| 1530 | 1562 | |
| 1531 | − rc = hashtab_insert(h, key, usrdatum); | |
| 1563 | + rc = symtab_insert(s, key, usrdatum); | |
| 1532 | 1564 | if (rc) |
| 1533 | 1565 | goto bad; |
| 1534 | 1566 | return 0; |
| @@ -1537,7 +1569,7 @@ bad: · 2 unmodified lines | ||
| 1537 | 1569 | return rc; |
| 1538 | 1570 | } |
| 1539 | 1571 | |
| 1540 | −static int sens_read(struct policydb *p, struct hashtab *h, void *fp) | |
| 1572 | +static int sens_read(struct policydb *p, struct symtab *s, void *fp) | |
| 1541 | 1573 | { |
| 1542 | 1574 | char *key = NULL; |
| 1543 | 1575 | struct level_datum *levdatum; |
| @@ -1569,7 +1601,7 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp) · 25 unmodified lines | ||
| 1569 | 1601 | if (rc) |
| 1570 | 1602 | goto bad; |
| 1571 | 1603 | |
| 1572 | − rc = hashtab_insert(h, key, levdatum); | |
| 1604 | + rc = symtab_insert(s, key, levdatum); | |
| 1573 | 1605 | if (rc) |
| 1574 | 1606 | goto bad; |
| 1575 | 1607 | return 0; |
| @@ -1578,7 +1610,7 @@ bad: · 2 unmodified lines | ||
| 1578 | 1610 | return rc; |
| 1579 | 1611 | } |
| 1580 | 1612 | |
| 1581 | −static int cat_read(struct policydb *p, struct hashtab *h, void *fp) | |
| 1613 | +static int cat_read(struct policydb *p, struct symtab *s, void *fp) | |
| 1582 | 1614 | { |
| 1583 | 1615 | char *key = NULL; |
| 1584 | 1616 | struct cat_datum *catdatum; |
| @@ -1602,7 +1634,7 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp) · 17 unmodified lines | ||
| 1602 | 1634 | if (rc) |
| 1603 | 1635 | goto bad; |
| 1604 | 1636 | |
| 1605 | − rc = hashtab_insert(h, key, catdatum); | |
| 1637 | + rc = symtab_insert(s, key, catdatum); | |
| 1606 | 1638 | if (rc) |
| 1607 | 1639 | goto bad; |
| 1608 | 1640 | return 0; |
| @@ -1611,7 +1643,7 @@ bad: · 2 unmodified lines | ||
| 1611 | 1643 | return rc; |
| 1612 | 1644 | } |
| 1613 | 1645 | |
| 1614 | −static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) = | |
| 1646 | +static int (*read_f[SYM_NUM]) (struct policydb *p, struct symtab *s, void *fp) = | |
| 1615 | 1647 | { |
| 1616 | 1648 | common_read, |
| 1617 | 1649 | class_read, |
| @@ -1751,7 +1783,7 @@ u16 string_to_security_class(struct policydb *p, const char *name) · 133 unmodified lines | ||
| 1751 | 1783 | { |
| 1752 | 1784 | struct class_datum *cladatum; |
| 1753 | 1785 | |
| 1754 | − cladatum = hashtab_search(&p->p_classes.table, name); | |
| 1786 | + cladatum = symtab_search(&p->p_classes, name); | |
| 1755 | 1787 | if (!cladatum) |
| 1756 | 1788 | return 0; |
| 1757 | 1789 | |
| @@ -1770,9 +1802,9 @@ u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name) · 12 unmodified lines | ||
| 1770 | 1802 | cladatum = p->class_val_to_struct[tclass-1]; |
| 1771 | 1803 | comdatum = cladatum->comdatum; |
| 1772 | 1804 | if (comdatum) |
| 1773 | − perdatum = hashtab_search(&comdatum->permissions.table, name); | |
| 1805 | + perdatum = symtab_search(&comdatum->permissions, name); | |
| 1774 | 1806 | if (!perdatum) |
| 1775 | − perdatum = hashtab_search(&cladatum->permissions.table, name); | |
| 1807 | + perdatum = symtab_search(&cladatum->permissions, name); | |
| 1776 | 1808 | if (!perdatum) |
| 1777 | 1809 | return 0; |
| 1778 | 1810 | |
| @@ -1796,7 +1828,7 @@ static int range_read(struct policydb *p, void *fp) · 17 unmodified lines | ||
| 1796 | 1828 | |
| 1797 | 1829 | nel = le32_to_cpu(buf[0]); |
| 1798 | 1830 | |
| 1799 | − rc = hashtab_init(&p->range_tr, rangetr_hash, rangetr_cmp, nel); | |
| 1831 | + rc = hashtab_init(&p->range_tr, nel); | |
| 1800 | 1832 | if (rc) |
| 1801 | 1833 | return rc; |
| 1802 | 1834 | |
| @@ -1841,7 +1873,7 @@ static int range_read(struct policydb *p, void *fp) · 38 unmodified lines | ||
| 1841 | 1873 | goto out; |
| 1842 | 1874 | } |
| 1843 | 1875 | |
| 1844 | − rc = hashtab_insert(&p->range_tr, rt, r); | |
| 1876 | + rc = hashtab_insert(&p->range_tr, rt, r, rangetr_key_params); | |
| 1845 | 1877 | if (rc) |
| 1846 | 1878 | goto out; |
| 1847 | 1879 | |
| @@ -1888,7 +1920,7 @@ static int filename_trans_read_helper_compat(struct policydb *p, void *fp) · 40 unmodified lines | ||
| 1888 | 1920 | otype = le32_to_cpu(buf[3]); |
| 1889 | 1921 | |
| 1890 | 1922 | last = NULL; |
| 1891 | − datum = hashtab_search(&p->filename_trans, &key); | |
| 1923 | + datum = policydb_filenametr_search(p, &key); | |
| 1892 | 1924 | while (datum) { |
| 1893 | 1925 | if (unlikely(ebitmap_get_bit(&datum->stypes, stype - 1))) { |
| 1894 | 1926 | /* conflicting/duplicate rules are ignored */ |
| @@ -1918,7 +1950,8 @@ static int filename_trans_read_helper_compat(struct policydb *p, void *fp) · 23 unmodified lines | ||
| 1918 | 1950 | if (!ft) |
| 1919 | 1951 | goto out; |
| 1920 | 1952 | |
| 1921 | − rc = hashtab_insert(&p->filename_trans, ft, datum); | |
| 1953 | + rc = hashtab_insert(&p->filename_trans, ft, datum, | |
| 1954 | + filenametr_key_params); | |
| 1922 | 1955 | if (rc) |
| 1923 | 1956 | goto out; |
| 1924 | 1957 | name = NULL; |
| @@ -2006,7 +2039,8 @@ static int filename_trans_read_helper(struct policydb *p, void *fp) · 81 unmodified lines | ||
| 2006 | 2039 | ft->tclass = tclass; |
| 2007 | 2040 | ft->name = name; |
| 2008 | 2041 | |
| 2009 | − rc = hashtab_insert(&p->filename_trans, ft, first); | |
| 2042 | + rc = hashtab_insert(&p->filename_trans, ft, first, | |
| 2043 | + filenametr_key_params); | |
| 2010 | 2044 | if (rc == -EEXIST) |
| 2011 | 2045 | pr_err("SELinux: Duplicate filename transition key\n"); |
| 2012 | 2046 | if (rc) |
| @@ -2044,8 +2078,7 @@ static int filename_trans_read(struct policydb *p, void *fp) · 31 unmodified lines | ||
| 2044 | 2078 | if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) { |
| 2045 | 2079 | p->compat_filename_trans_count = nel; |
| 2046 | 2080 | |
| 2047 | − rc = hashtab_init(&p->filename_trans, filenametr_hash, | |
| 2048 | − filenametr_cmp, (1 << 11)); | |
| 2081 | + rc = hashtab_init(&p->filename_trans, (1 << 11)); | |
| 2049 | 2082 | if (rc) |
| 2050 | 2083 | return rc; |
| 2051 | 2084 | |
| @@ -2055,8 +2088,7 @@ static int filename_trans_read(struct policydb *p, void *fp) · 3 unmodified lines | ||
| 2055 | 2088 | return rc; |
| 2056 | 2089 | } |
| 2057 | 2090 | } else { |
| 2058 | − rc = hashtab_init(&p->filename_trans, filenametr_hash, | |
| 2059 | − filenametr_cmp, nel); | |
| 2091 | + rc = hashtab_init(&p->filename_trans, nel); | |
| 2060 | 2092 | if (rc) |
| 2061 | 2093 | return rc; |
| 2062 | 2094 | |
| @@ -2376,7 +2408,7 @@ int policydb_read(struct policydb *p, void *fp) · 313 unmodified lines | ||
| 2376 | 2408 | struct role_trans_datum *rtd = NULL; |
| 2377 | 2409 | int i, j, rc; |
| 2378 | 2410 | __le32 buf[4]; |
| 2379 | − u32 len, nprim, nel; | |
| 2411 | + u32 len, nprim, nel, perm; | |
| 2380 | 2412 | |
| 2381 | 2413 | char *policydb_str; |
| 2382 | 2414 | struct policydb_compat_info *info; |
| @@ -2509,7 +2541,7 @@ int policydb_read(struct policydb *p, void *fp) · 126 unmodified lines | ||
| 2509 | 2541 | } |
| 2510 | 2542 | |
| 2511 | 2543 | for (j = 0; j < nel; j++) { |
| 2512 | − rc = read_f[i](p, &p->symtab[i].table, fp); | |
| 2544 | + rc = read_f[i](p, &p->symtab[i], fp); | |
| 2513 | 2545 | if (rc) |
| 2514 | 2546 | goto bad; |
| 2515 | 2547 | } |
| @@ -2519,8 +2551,10 @@ int policydb_read(struct policydb *p, void *fp) · 3 unmodified lines | ||
| 2519 | 2551 | |
| 2520 | 2552 | rc = -EINVAL; |
| 2521 | 2553 | p->process_class = string_to_security_class(p, "process"); |
| 2522 | − if (!p->process_class) | |
| 2554 | + if (!p->process_class) { | |
| 2555 | + pr_err("SELinux: process class is required, not defined in policy\n"); | |
| 2523 | 2556 | goto bad; |
| 2557 | + } | |
| 2524 | 2558 | |
| 2525 | 2559 | rc = avtab_read(&p->te_avtab, fp, p); |
| 2526 | 2560 | if (rc) |
| @@ -2537,7 +2571,7 @@ int policydb_read(struct policydb *p, void *fp) · 10 unmodified lines | ||
| 2537 | 2571 | goto bad; |
| 2538 | 2572 | nel = le32_to_cpu(buf[0]); |
| 2539 | 2573 | |
| 2540 | − rc = hashtab_init(&p->role_tr, role_trans_hash, role_trans_cmp, nel); | |
| 2574 | + rc = hashtab_init(&p->role_tr, nel); | |
| 2541 | 2575 | if (rc) |
| 2542 | 2576 | goto bad; |
| 2543 | 2577 | for (i = 0; i < nel; i++) { |
| @@ -2574,7 +2608,7 @@ int policydb_read(struct policydb *p, void *fp) · 30 unmodified lines | ||
| 2574 | 2608 | !policydb_role_isvalid(p, rtd->new_role)) |
| 2575 | 2609 | goto bad; |
| 2576 | 2610 | |
| 2577 | − rc = hashtab_insert(&p->role_tr, rtk, rtd); | |
| 2611 | + rc = hashtab_insert(&p->role_tr, rtk, rtd, roletr_key_params); | |
| 2578 | 2612 | if (rc) |
| 2579 | 2613 | goto bad; |
| 2580 | 2614 | |
| @@ -2618,10 +2652,18 @@ int policydb_read(struct policydb *p, void *fp) · 37 unmodified lines | ||
| 2618 | 2652 | goto bad; |
| 2619 | 2653 | |
| 2620 | 2654 | rc = -EINVAL; |
| 2621 | − p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition"); | |
| 2622 | − p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition"); | |
| 2623 | − if (!p->process_trans_perms) | |
| 2655 | + perm = string_to_av_perm(p, p->process_class, "transition"); | |
| 2656 | + if (!perm) { | |
| 2657 | + pr_err("SELinux: process transition permission is required, not defined in policy\n"); | |
| 2658 | + goto bad; | |
| 2659 | + } | |
| 2660 | + p->process_trans_perms = perm; | |
| 2661 | + perm = string_to_av_perm(p, p->process_class, "dyntransition"); | |
| 2662 | + if (!perm) { | |
| 2663 | + pr_err("SELinux: process dyntransition permission is required, not defined in policy\n"); | |
| 2624 | 2664 | goto bad; |
| 2665 | + } | |
| 2666 | + p->process_trans_perms |= perm; | |
| 2625 | 2667 | |
| 2626 | 2668 | rc = ocontext_read(p, info, fp); |
| 2627 | 2669 | if (rc) |
| @@ -324,6 +324,15 @@ extern int policydb_role_isvalid(struct policydb *p, unsigned int role); · 323 unmodified lines | ||
| 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 */ |
| @@ -1441,7 +1441,7 @@ static int string_to_context_struct(struct policydb *pol, · 1440 unmodified lines | ||
| 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,7 +1457,7 @@ static int string_to_context_struct(struct policydb *pol, · 9 unmodified lines | ||
| 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,7 +1469,7 @@ static int string_to_context_struct(struct policydb *pol, · 5 unmodified lines | ||
| 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,7 +1671,7 @@ static void filename_compute_type(struct policydb *policydb, · 195 unmodified lines | ||
| 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,7 +1834,7 @@ static int security_compute_sid(struct selinux_state *state, · 156 unmodified lines | ||
| 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,26 +2024,26 @@ static int convert_context(struct context *oldc, struct context *newc, void *p) · 183 unmodified lines | ||
| 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,7 +2623,7 @@ int security_get_user_sids(struct selinux_state *state, · 573 unmodified lines | ||
| 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,7 +2979,7 @@ static int security_preserve_bools(struct selinux_state *state, · 349 unmodified lines | ||
| 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,7 +3230,7 @@ int security_get_permissions(struct selinux_state *state, · 244 unmodified lines | ||
| 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,7 +3369,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) · 132 unmodified lines | ||
| 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,7 +3377,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) · 1 unmodified line | ||
| 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,7 +3385,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) · 1 unmodified line | ||
| 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; |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 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,10 +20,10 @@ static unsigned int symhash(struct hashtab *h, const void *key) · 4 unmodified lines | ||
| 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,10 +32,23 @@ static int symcmp(struct hashtab *h, const void *key1, const void *key2) · 2 unmodified lines | ||
| 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 | +} | |
| @@ -19,6 +19,9 @@ struct symtab { · 18 unmodified lines | ||
| 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 | |