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 | initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *); | 68 | initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *); |
| 69 | /* print out the sids */ | 69 | /* print out the sids */ |
| 70 | for (i = 1; i < initial_sid_to_string_len; i++) | 70 | for (i = 1; i < initial_sid_to_string_len; i++) { |
| 71 | fprintf(fout, "sid %s\n", initial_sid_to_string[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 | fprintf(fout, "\n"); | 78 | fprintf(fout, "\n"); |
| 73 | 79 | ||
| 74 | /* print out the class permissions */ | 80 | /* print out the class permissions */ |
| @@ -126,9 +132,16 @@ int main(int argc, char *argv[]) · 51 unmodified lines | |||
| 126 | #define OBJUSERROLETYPE "user_u:object_r:base_t" | 132 | #define OBJUSERROLETYPE "user_u:object_r:base_t" |
| 127 | 133 | ||
| 128 | /* default sids */ | 134 | /* default sids */ |
| 129 | for (i = 1; i < initial_sid_to_string_len; i++) | 135 | for (i = 1; i < initial_sid_to_string_len; i++) { |
| 130 | fprintf(fout, "sid %s " SUBJUSERROLETYPE "%s\n", | 136 | const char *name = initial_sid_to_string[i]; |
| 131 | initial_sid_to_string[i], mls ? ":" SYSTEMLOW : ""); | 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 | fprintf(fout, "\n"); | 145 | fprintf(fout, "\n"); |
| 133 | 146 | ||
| 134 | #define FS_USE(behavior, fstype) \ | 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 | char *context = NULL; | 3332 | char *context = NULL; |
| 3333 | struct inode_security_struct *isec; | 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 | return -EOPNOTSUPP; | 3341 | return -EOPNOTSUPP; |
| 3337 | 3342 | ||
| 3338 | /* | 3343 | /* |
| @@ -124,7 +124,7 @@ static void sel_netif_destroy(struct sel_netif *netif) · 123 unmodified lines | |||
| 124 | * @sid: interface SID | 124 | * @sid: interface SID |
| 125 | * | 125 | * |
| 126 | * Description: | 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 | * security policy. The result is added to the network interface table to | 128 | * security policy. The result is added to the network interface table to |
| 129 | * speedup future queries. Returns zero on success, negative values on | 129 | * speedup future queries. Returns zero on success, negative values on |
| 130 | * failure. | 130 | * failure. |
| @@ -181,7 +181,7 @@ static void sel_netnode_insert(struct sel_netnode *node) · 180 unmodified lines | |||
| 181 | * @sid: node SID | 181 | * @sid: node SID |
| 182 | * | 182 | * |
| 183 | * Description: | 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 | * security policy. The result is added to the network address table to | 185 | * security policy. The result is added to the network address table to |
| 186 | * speedup future queries. Returns zero on success, negative values on | 186 | * speedup future queries. Returns zero on success, negative values on |
| 187 | * failure. | 187 | * failure. |
| @@ -130,7 +130,7 @@ static void sel_netport_insert(struct sel_netport *port) · 129 unmodified lines | |||
| 130 | * @sid: port SID | 130 | * @sid: port SID |
| 131 | * | 131 | * |
| 132 | * Description: | 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 | * policy. The result is added to the network port table to speedup future | 134 | * policy. The result is added to the network port table to speedup future |
| 135 | * queries. Returns zero on success, negative values on failure. | 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 | return 1; | 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 | char *key = NULL; | 208 | char *key = NULL; |
| 209 | struct cond_bool_datum *booldatum; | 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 | if (!booldatum) | 215 | if (!booldatum) |
| 216 | return -ENOMEM; | 216 | return -ENOMEM; |
| 217 | 217 | ||
| 218 | rc = next_entry(buf, fp, sizeof buf); | 218 | rc = next_entry(buf, fp, sizeof(buf)); |
| 219 | if (rc) | 219 | if (rc) |
| 220 | goto err; | 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 | if (rc) | 238 | if (rc) |
| 239 | goto err; | 239 | goto err; |
| 240 | key[len] = '\0'; | 240 | key[len] = '\0'; |
| 241 | rc = hashtab_insert(h, key, booldatum); | 241 | rc = symtab_insert(s, key, booldatum); |
| 242 | if (rc) | 242 | if (rc) |
| 243 | goto err; | 243 | goto err; |
| 244 | 244 | ||
| @@ -416,7 +416,7 @@ int cond_read_list(struct policydb *p, void *fp) · 171 unmodified lines | |||
| 416 | u32 i, len; | 416 | u32 i, len; |
| 417 | int rc; | 417 | int rc; |
| 418 | 418 | ||
| 419 | rc = next_entry(buf, fp, sizeof buf); | 419 | rc = next_entry(buf, fp, sizeof(buf)); |
| 420 | if (rc) | 420 | if (rc) |
| 421 | return rc; | 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 | int cond_index_bool(void *key, void *datum, void *datap); | 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 | int cond_read_list(struct policydb *p, void *fp); | 73 | int cond_read_list(struct policydb *p, void *fp); |
| 74 | int cond_write_bool(void *key, void *datum, void *ptr); | 74 | int cond_write_bool(void *key, void *datum, void *ptr); |
| 75 | int cond_write_list(struct policydb *p, void *fp); | 75 | int cond_write_list(struct policydb *p, void *fp); |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | |||
| 7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
| 8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
| 9 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
| 10 | #include <linux/sched.h> | ||
| 11 | #include "hashtab.h" | 10 | #include "hashtab.h" |
| 12 | 11 | ||
| 13 | static struct kmem_cache *hashtab_node_cachep; | 12 | static struct kmem_cache *hashtab_node_cachep; |
| @@ -29,16 +28,10 @@ static u32 hashtab_compute_size(u32 nel) · 15 unmodified lines | |||
| 29 | return nel == 0 ? 0 : roundup_pow_of_two(nel); | 28 | return nel == 0 ? 0 : roundup_pow_of_two(nel); |
| 30 | } | 29 | } |
| 31 | 30 | ||
| 32 | int hashtab_init(struct hashtab *h, | 31 | int hashtab_init(struct hashtab *h, u32 nel_hint) |
| 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) | ||
| 37 | { | 32 | { |
| 38 | h->size = hashtab_compute_size(nel_hint); | 33 | h->size = hashtab_compute_size(nel_hint); |
| 39 | h->nel = 0; | 34 | h->nel = 0; |
| 40 | h->hash_value = hash_value; | ||
| 41 | h->keycmp = keycmp; | ||
| 42 | if (!h->size) | 35 | if (!h->size) |
| 43 | return 0; | 36 | return 0; |
| 44 | 37 | ||
| @@ -46,63 +39,23 @@ int hashtab_init(struct hashtab *h, · 1 unmodified line | |||
| 46 | return h->htable ? 0 : -ENOMEM; | 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; | 45 | struct hashtab_node *newnode; |
| 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; | ||
| 69 | 46 | ||
| 70 | newnode = kmem_cache_zalloc(hashtab_node_cachep, GFP_KERNEL); | 47 | newnode = kmem_cache_zalloc(hashtab_node_cachep, GFP_KERNEL); |
| 71 | if (!newnode) | 48 | if (!newnode) |
| 72 | return -ENOMEM; | 49 | return -ENOMEM; |
| 73 | newnode->key = key; | 50 | newnode->key = key; |
| 74 | newnode->datum = datum; | 51 | newnode->datum = datum; |
| 75 | if (prev) { | 52 | newnode->next = *dst; |
| 76 | newnode->next = prev->next; | 53 | *dst = newnode; |
| 77 | prev->next = newnode; | ||
| 78 | } else { | ||
| 79 | newnode->next = h->htable[hvalue]; | ||
| 80 | h->htable[hvalue] = newnode; | ||
| 81 | } | ||
| 82 | 54 | ||
| 83 | h->nel++; | 55 | h->nel++; |
| 84 | return 0; | 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 | void hashtab_destroy(struct hashtab *h) | 59 | void hashtab_destroy(struct hashtab *h) |
| 107 | { | 60 | { |
| 108 | u32 i; | 61 | u32 i; |
| @@ -11,7 +11,17 @@ · 10 unmodified lines | |||
| 11 | #ifndef _SS_HASHTAB_H_ | 11 | #ifndef _SS_HASHTAB_H_ |
| 12 | #define _SS_HASHTAB_H_ | 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 | struct hashtab_node { | 26 | struct hashtab_node { |
| 17 | void *key; | 27 | void *key; |
| @@ -23,10 +33,6 @@ struct hashtab { · 5 unmodified lines | |||
| 23 | struct hashtab_node **htable; /* hash table */ | 33 | struct hashtab_node **htable; /* hash table */ |
| 24 | u32 size; /* number of slots in hash table */ | 34 | u32 size; /* number of slots in hash table */ |
| 25 | u32 nel; /* number of elements in hash table */ | 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 | struct hashtab_info { | 38 | struct hashtab_info { |
| @@ -39,11 +45,10 @@ struct hashtab_info { · 6 unmodified lines | |||
| 39 | * | 45 | * |
| 40 | * Returns -ENOMEM if insufficient space is available or 0 otherwise. | 46 | * Returns -ENOMEM if insufficient space is available or 0 otherwise. |
| 41 | */ | 47 | */ |
| 42 | int hashtab_init(struct hashtab *h, | 48 | int hashtab_init(struct hashtab *h, u32 nel_hint); |
| 43 | u32 (*hash_value)(struct hashtab *h, const void *key), | 49 | |
| 44 | int (*keycmp)(struct hashtab *h, const void *key1, | 50 | int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst, |
| 45 | const void *key2), | 51 | void *key, void *datum); |
| 46 | u32 nel_hint); | ||
| 47 | 52 | ||
| 48 | /* | 53 | /* |
| 49 | * Inserts the specified (key, datum) pair into the specified hash table. | 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 | * -EINVAL for general errors or | 58 | * -EINVAL for general errors or |
| 54 | 0 otherwise. | 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 | * Searches for the entry with the specified key in the hash table. | 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 | * Returns NULL if no entry has the specified key or | 93 | * Returns NULL if no entry has the specified key or |
| 62 | * the datum of the entry otherwise. | 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 | * Destroys the specified hash table. | 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 | if (!l->sens || l->sens > p->p_levels.nprim) | 166 | if (!l->sens || l->sens > p->p_levels.nprim) |
| 167 | return 0; | 167 | return 0; |
| 168 | levdatum = hashtab_search(&p->p_levels.table, | 168 | levdatum = symtab_search(&p->p_levels, |
| 169 | sym_name(p, SYM_LEVELS, l->sens - 1)); | 169 | sym_name(p, SYM_LEVELS, l->sens - 1)); |
| 170 | if (!levdatum) | 170 | if (!levdatum) |
| 171 | return 0; | 171 | return 0; |
| 172 | 172 | ||
| @@ -293,7 +293,7 @@ int mls_context_to_sid(struct policydb *pol, · 120 unmodified lines | |||
| 293 | *(next_cat++) = '\0'; | 293 | *(next_cat++) = '\0'; |
| 294 | 294 | ||
| 295 | /* Parse sensitivity. */ | 295 | /* Parse sensitivity. */ |
| 296 | levdatum = hashtab_search(&pol->p_levels.table, sensitivity); | 296 | levdatum = symtab_search(&pol->p_levels, sensitivity); |
| 297 | if (!levdatum) | 297 | if (!levdatum) |
| 298 | return -EINVAL; | 298 | return -EINVAL; |
| 299 | context->range.level[l].sens = levdatum->level->sens; | 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 | *rngptr++ = '\0'; | 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 | if (!catdatum) | 316 | if (!catdatum) |
| 317 | return -EINVAL; | 317 | return -EINVAL; |
| 318 | 318 | ||
| @@ -325,7 +325,7 @@ int mls_context_to_sid(struct policydb *pol, · 6 unmodified lines | |||
| 325 | if (rngptr == NULL) | 325 | if (rngptr == NULL) |
| 326 | continue; | 326 | continue; |
| 327 | 327 | ||
| 328 | rngdatum = hashtab_search(&pol->p_cats.table, rngptr); | 328 | rngdatum = symtab_search(&pol->p_cats, rngptr); |
| 329 | if (!rngdatum) | 329 | if (!rngdatum) |
| 330 | return -EINVAL; | 330 | return -EINVAL; |
| 331 | 331 | ||
| @@ -458,9 +458,10 @@ int mls_convert_context(struct policydb *oldp, · 126 unmodified lines | |||
| 458 | return 0; | 458 | return 0; |
| 459 | 459 | ||
| 460 | for (l = 0; l < 2; l++) { | 460 | for (l = 0; l < 2; l++) { |
| 461 | levdatum = hashtab_search(&newp->p_levels.table, | 461 | char *name = sym_name(oldp, SYM_LEVELS, |
| 462 | sym_name(oldp, SYM_LEVELS, | 462 | oldc->range.level[l].sens - 1); |
| 463 | oldc->range.level[l].sens - 1)); | 463 | |
| 464 | levdatum = symtab_search(&newp->p_levels, name); | ||
| 464 | 465 | ||
| 465 | if (!levdatum) | 466 | if (!levdatum) |
| 466 | return -EINVAL; | 467 | return -EINVAL; |
| @@ -470,8 +471,8 @@ int mls_convert_context(struct policydb *oldp, · 3 unmodified lines | |||
| 470 | node, i) { | 471 | node, i) { |
| 471 | int rc; | 472 | int rc; |
| 472 | 473 | ||
| 473 | catdatum = hashtab_search(&newp->p_cats.table, | 474 | catdatum = symtab_search(&newp->p_cats, |
| 474 | sym_name(oldp, SYM_CATS, i)); | 475 | sym_name(oldp, SYM_CATS, i)); |
| 475 | if (!catdatum) | 476 | if (!catdatum) |
| 476 | return -EINVAL; | 477 | return -EINVAL; |
| 477 | rc = ebitmap_set_bit(&newc->range.level[l].cat, | 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 | rtr.source_type = scontext->type; | 507 | rtr.source_type = scontext->type; |
| 507 | rtr.target_type = tcontext->type; | 508 | rtr.target_type = tcontext->type; |
| 508 | rtr.target_class = tclass; | 509 | rtr.target_class = tclass; |
| 509 | r = hashtab_search(&p->range_tr, &rtr); | 510 | r = policydb_rangetr_search(p, &rtr); |
| 510 | if (r) | 511 | if (r) |
| 511 | return mls_range_set(newcontext, r); | 512 | return mls_range_set(newcontext, r); |
| 512 | 513 | ||
| @@ -400,7 +400,7 @@ static int roles_init(struct policydb *p) · 399 unmodified lines | |||
| 400 | if (!key) | 400 | if (!key) |
| 401 | goto out; | 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 | if (rc) | 404 | if (rc) |
| 405 | goto out; | 405 | goto out; |
| 406 | 406 | ||
| @@ -411,7 +411,7 @@ out: · 4 unmodified lines | |||
| 411 | return rc; | 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 | const struct filename_trans_key *ft = k; | 416 | const struct filename_trans_key *ft = k; |
| 417 | unsigned long hash; | 417 | unsigned long hash; |
| @@ -423,10 +423,10 @@ static u32 filenametr_hash(struct hashtab *h, const void *k) · 5 unmodified lines | |||
| 423 | byte_num = 0; | 423 | byte_num = 0; |
| 424 | while ((focus = ft->name[byte_num++])) | 424 | while ((focus = ft->name[byte_num++])) |
| 425 | hash = partial_name_hash(focus, hash); | 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 | const struct filename_trans_key *ft1 = k1; | 431 | const struct filename_trans_key *ft1 = k1; |
| 432 | const struct filename_trans_key *ft2 = k2; | 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 | const struct range_trans *key = k; | 460 | const struct range_trans *key = k; |
| 450 | 461 | ||
| 451 | return (key->source_type + (key->target_type << 3) + | 462 | return key->source_type + (key->target_type << 3) + |
| 452 | (key->target_class << 5)) & (h->size - 1); | 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 | const struct range_trans *key1 = k1, *key2 = k2; | 468 | const struct range_trans *key1 = k1, *key2 = k2; |
| 458 | int v; | 469 | int v; |
| @@ -470,15 +481,25 @@ static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2) · 11 unmodified lines | |||
| 470 | return v; | 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 | const struct role_trans_key *key = k; | 497 | const struct role_trans_key *key = k; |
| 476 | 498 | ||
| 477 | return (key->role + (key->type << 3) + (key->tclass << 5)) & | 499 | return key->role + (key->type << 3) + (key->tclass << 5); |
| 478 | (h->size - 1); | ||
| 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 | const struct role_trans_key *key1 = k1, *key2 = k2; | 504 | const struct role_trans_key *key1 = k1, *key2 = k2; |
| 484 | int v; | 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 | return key1->tclass - key2->tclass; | 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 | * Initialize a policy database structure. | 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 | return 0; | 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 | char *key = NULL; | 1102 | char *key = NULL; |
| 1071 | struct perm_datum *perdatum; | 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 | if (rc) | 1120 | if (rc) |
| 1089 | goto bad; | 1121 | goto bad; |
| 1090 | 1122 | ||
| 1091 | rc = hashtab_insert(h, key, perdatum); | 1123 | rc = symtab_insert(s, key, perdatum); |
| 1092 | if (rc) | 1124 | if (rc) |
| 1093 | goto bad; | 1125 | goto bad; |
| 1094 | 1126 | ||
| @@ -1098,7 +1130,7 @@ bad: · 3 unmodified lines | |||
| 1098 | return rc; | 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 | char *key = NULL; | 1135 | char *key = NULL; |
| 1104 | struct common_datum *comdatum; | 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 | goto bad; | 1160 | goto bad; |
| 1129 | 1161 | ||
| 1130 | for (i = 0; i < nel; i++) { | 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 | if (rc) | 1164 | if (rc) |
| 1133 | goto bad; | 1165 | goto bad; |
| 1134 | } | 1166 | } |
| 1135 | 1167 | ||
| 1136 | rc = hashtab_insert(h, key, comdatum); | 1168 | rc = symtab_insert(s, key, comdatum); |
| 1137 | if (rc) | 1169 | if (rc) |
| 1138 | goto bad; | 1170 | goto bad; |
| 1139 | return 0; | 1171 | return 0; |
| @@ -1262,7 +1294,7 @@ static int read_cons_helper(struct policydb *p, · 122 unmodified lines | |||
| 1262 | return 0; | 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 | char *key = NULL; | 1299 | char *key = NULL; |
| 1268 | struct class_datum *cladatum; | 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 | goto bad; | 1332 | goto bad; |
| 1301 | 1333 | ||
| 1302 | rc = -EINVAL; | 1334 | rc = -EINVAL; |
| 1303 | cladatum->comdatum = hashtab_search(&p->p_commons.table, | 1335 | cladatum->comdatum = symtab_search(&p->p_commons, |
| 1304 | cladatum->comkey); | 1336 | cladatum->comkey); |
| 1305 | if (!cladatum->comdatum) { | 1337 | if (!cladatum->comdatum) { |
| 1306 | pr_err("SELinux: unknown common %s\n", | 1338 | pr_err("SELinux: unknown common %s\n", |
| 1307 | cladatum->comkey); | 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 | for (i = 0; i < nel; i++) { | 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 | if (rc) | 1345 | if (rc) |
| 1314 | goto bad; | 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 | cladatum->default_type = le32_to_cpu(buf[0]); | 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 | if (rc) | 1383 | if (rc) |
| 1352 | goto bad; | 1384 | goto bad; |
| 1353 | 1385 | ||
| @@ -1357,7 +1389,7 @@ bad: · 3 unmodified lines | |||
| 1357 | return rc; | 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 | char *key = NULL; | 1394 | char *key = NULL; |
| 1363 | struct role_datum *role; | 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 | goto bad; | 1436 | goto bad; |
| 1405 | } | 1437 | } |
| 1406 | 1438 | ||
| 1407 | rc = hashtab_insert(h, key, role); | 1439 | rc = symtab_insert(s, key, role); |
| 1408 | if (rc) | 1440 | if (rc) |
| 1409 | goto bad; | 1441 | goto bad; |
| 1410 | return 0; | 1442 | return 0; |
| @@ -1413,7 +1445,7 @@ bad: · 2 unmodified lines | |||
| 1413 | return rc; | 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 | char *key = NULL; | 1450 | char *key = NULL; |
| 1419 | struct type_datum *typdatum; | 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 | if (rc) | 1483 | if (rc) |
| 1452 | goto bad; | 1484 | goto bad; |
| 1453 | 1485 | ||
| 1454 | rc = hashtab_insert(h, key, typdatum); | 1486 | rc = symtab_insert(s, key, typdatum); |
| 1455 | if (rc) | 1487 | if (rc) |
| 1456 | goto bad; | 1488 | goto bad; |
| 1457 | return 0; | 1489 | return 0; |
| @@ -1487,7 +1519,7 @@ static int mls_read_level(struct mls_level *lp, void *fp) · 29 unmodified lines | |||
| 1487 | return 0; | 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 | char *key = NULL; | 1524 | char *key = NULL; |
| 1493 | struct user_datum *usrdatum; | 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 | goto bad; | 1560 | goto bad; |
| 1529 | } | 1561 | } |
| 1530 | 1562 | ||
| 1531 | rc = hashtab_insert(h, key, usrdatum); | 1563 | rc = symtab_insert(s, key, usrdatum); |
| 1532 | if (rc) | 1564 | if (rc) |
| 1533 | goto bad; | 1565 | goto bad; |
| 1534 | return 0; | 1566 | return 0; |
| @@ -1537,7 +1569,7 @@ bad: · 2 unmodified lines | |||
| 1537 | return rc; | 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 | char *key = NULL; | 1574 | char *key = NULL; |
| 1543 | struct level_datum *levdatum; | 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 | if (rc) | 1601 | if (rc) |
| 1570 | goto bad; | 1602 | goto bad; |
| 1571 | 1603 | ||
| 1572 | rc = hashtab_insert(h, key, levdatum); | 1604 | rc = symtab_insert(s, key, levdatum); |
| 1573 | if (rc) | 1605 | if (rc) |
| 1574 | goto bad; | 1606 | goto bad; |
| 1575 | return 0; | 1607 | return 0; |
| @@ -1578,7 +1610,7 @@ bad: · 2 unmodified lines | |||
| 1578 | return rc; | 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 | char *key = NULL; | 1615 | char *key = NULL; |
| 1584 | struct cat_datum *catdatum; | 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 | if (rc) | 1634 | if (rc) |
| 1603 | goto bad; | 1635 | goto bad; |
| 1604 | 1636 | ||
| 1605 | rc = hashtab_insert(h, key, catdatum); | 1637 | rc = symtab_insert(s, key, catdatum); |
| 1606 | if (rc) | 1638 | if (rc) |
| 1607 | goto bad; | 1639 | goto bad; |
| 1608 | return 0; | 1640 | return 0; |
| @@ -1611,7 +1643,7 @@ bad: · 2 unmodified lines | |||
| 1611 | return rc; | 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 | common_read, | 1648 | common_read, |
| 1617 | class_read, | 1649 | class_read, |
| @@ -1751,7 +1783,7 @@ u16 string_to_security_class(struct policydb *p, const char *name) · 133 unmodified lines | |||
| 1751 | { | 1783 | { |
| 1752 | struct class_datum *cladatum; | 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 | if (!cladatum) | 1787 | if (!cladatum) |
| 1756 | return 0; | 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 | cladatum = p->class_val_to_struct[tclass-1]; | 1802 | cladatum = p->class_val_to_struct[tclass-1]; |
| 1771 | comdatum = cladatum->comdatum; | 1803 | comdatum = cladatum->comdatum; |
| 1772 | if (comdatum) | 1804 | if (comdatum) |
| 1773 | perdatum = hashtab_search(&comdatum->permissions.table, name); | 1805 | perdatum = symtab_search(&comdatum->permissions, name); |
| 1774 | if (!perdatum) | 1806 | if (!perdatum) |
| 1775 | perdatum = hashtab_search(&cladatum->permissions.table, name); | 1807 | perdatum = symtab_search(&cladatum->permissions, name); |
| 1776 | if (!perdatum) | 1808 | if (!perdatum) |
| 1777 | return 0; | 1809 | return 0; |
| 1778 | 1810 | ||
| @@ -1796,7 +1828,7 @@ static int range_read(struct policydb *p, void *fp) · 17 unmodified lines | |||
| 1796 | 1828 | ||
| 1797 | nel = le32_to_cpu(buf[0]); | 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 | if (rc) | 1832 | if (rc) |
| 1801 | return rc; | 1833 | return rc; |
| 1802 | 1834 | ||
| @@ -1841,7 +1873,7 @@ static int range_read(struct policydb *p, void *fp) · 38 unmodified lines | |||
| 1841 | goto out; | 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 | if (rc) | 1877 | if (rc) |
| 1846 | goto out; | 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 | otype = le32_to_cpu(buf[3]); | 1920 | otype = le32_to_cpu(buf[3]); |
| 1889 | 1921 | ||
| 1890 | last = NULL; | 1922 | last = NULL; |
| 1891 | datum = hashtab_search(&p->filename_trans, &key); | 1923 | datum = policydb_filenametr_search(p, &key); |
| 1892 | while (datum) { | 1924 | while (datum) { |
| 1893 | if (unlikely(ebitmap_get_bit(&datum->stypes, stype - 1))) { | 1925 | if (unlikely(ebitmap_get_bit(&datum->stypes, stype - 1))) { |
| 1894 | /* conflicting/duplicate rules are ignored */ | 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 | if (!ft) | 1950 | if (!ft) |
| 1919 | goto out; | 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 | if (rc) | 1955 | if (rc) |
| 1923 | goto out; | 1956 | goto out; |
| 1924 | name = NULL; | 1957 | name = NULL; |
| @@ -2006,7 +2039,8 @@ static int filename_trans_read_helper(struct policydb *p, void *fp) · 81 unmodified lines | |||
| 2006 | ft->tclass = tclass; | 2039 | ft->tclass = tclass; |
| 2007 | ft->name = name; | 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 | if (rc == -EEXIST) | 2044 | if (rc == -EEXIST) |
| 2011 | pr_err("SELinux: Duplicate filename transition key\n"); | 2045 | pr_err("SELinux: Duplicate filename transition key\n"); |
| 2012 | if (rc) | 2046 | if (rc) |
| @@ -2044,8 +2078,7 @@ static int filename_trans_read(struct policydb *p, void *fp) · 31 unmodified lines | |||
| 2044 | if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) { | 2078 | if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) { |
| 2045 | p->compat_filename_trans_count = nel; | 2079 | p->compat_filename_trans_count = nel; |
| 2046 | 2080 | ||
| 2047 | rc = hashtab_init(&p->filename_trans, filenametr_hash, | 2081 | rc = hashtab_init(&p->filename_trans, (1 << 11)); |
| 2048 | filenametr_cmp, (1 << 11)); | ||
| 2049 | if (rc) | 2082 | if (rc) |
| 2050 | return rc; | 2083 | return rc; |
| 2051 | 2084 | ||
| @@ -2055,8 +2088,7 @@ static int filename_trans_read(struct policydb *p, void *fp) · 3 unmodified lines | |||
| 2055 | return rc; | 2088 | return rc; |
| 2056 | } | 2089 | } |
| 2057 | } else { | 2090 | } else { |
| 2058 | rc = hashtab_init(&p->filename_trans, filenametr_hash, | 2091 | rc = hashtab_init(&p->filename_trans, nel); |
| 2059 | filenametr_cmp, nel); | ||
| 2060 | if (rc) | 2092 | if (rc) |
| 2061 | return rc; | 2093 | return rc; |
| 2062 | 2094 | ||
| @@ -2376,7 +2408,7 @@ int policydb_read(struct policydb *p, void *fp) · 313 unmodified lines | |||
| 2376 | struct role_trans_datum *rtd = NULL; | 2408 | struct role_trans_datum *rtd = NULL; |
| 2377 | int i, j, rc; | 2409 | int i, j, rc; |
| 2378 | __le32 buf[4]; | 2410 | __le32 buf[4]; |
| 2379 | u32 len, nprim, nel; | 2411 | u32 len, nprim, nel, perm; |
| 2380 | 2412 | ||
| 2381 | char *policydb_str; | 2413 | char *policydb_str; |
| 2382 | struct policydb_compat_info *info; | 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 | for (j = 0; j < nel; j++) { | 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 | if (rc) | 2545 | if (rc) |
| 2514 | goto bad; | 2546 | goto bad; |
| 2515 | } | 2547 | } |
| @@ -2519,8 +2551,10 @@ int policydb_read(struct policydb *p, void *fp) · 3 unmodified lines | |||
| 2519 | 2551 | ||
| 2520 | rc = -EINVAL; | 2552 | rc = -EINVAL; |
| 2521 | p->process_class = string_to_security_class(p, "process"); | 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 | goto bad; | 2556 | goto bad; |
| 2557 | } | ||
| 2524 | 2558 | ||
| 2525 | rc = avtab_read(&p->te_avtab, fp, p); | 2559 | rc = avtab_read(&p->te_avtab, fp, p); |
| 2526 | if (rc) | 2560 | if (rc) |
| @@ -2537,7 +2571,7 @@ int policydb_read(struct policydb *p, void *fp) · 10 unmodified lines | |||
| 2537 | goto bad; | 2571 | goto bad; |
| 2538 | nel = le32_to_cpu(buf[0]); | 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 | if (rc) | 2575 | if (rc) |
| 2542 | goto bad; | 2576 | goto bad; |
| 2543 | for (i = 0; i < nel; i++) { | 2577 | for (i = 0; i < nel; i++) { |
| @@ -2574,7 +2608,7 @@ int policydb_read(struct policydb *p, void *fp) · 30 unmodified lines | |||
| 2574 | !policydb_role_isvalid(p, rtd->new_role)) | 2608 | !policydb_role_isvalid(p, rtd->new_role)) |
| 2575 | goto bad; | 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 | if (rc) | 2612 | if (rc) |
| 2579 | goto bad; | 2613 | goto bad; |
| 2580 | 2614 | ||
| @@ -2618,10 +2652,18 @@ int policydb_read(struct policydb *p, void *fp) · 37 unmodified lines | |||
| 2618 | goto bad; | 2652 | goto bad; |
| 2619 | 2653 | ||
| 2620 | rc = -EINVAL; | 2654 | rc = -EINVAL; |
| 2621 | p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition"); | 2655 | perm = string_to_av_perm(p, p->process_class, "transition"); |
| 2622 | p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition"); | 2656 | if (!perm) { |
| 2623 | if (!p->process_trans_perms) | 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 | goto bad; | 2664 | goto bad; |
| 2665 | } | ||
| 2666 | p->process_trans_perms |= perm; | ||
| 2625 | 2667 | ||
| 2626 | rc = ocontext_read(p, info, fp); | 2668 | rc = ocontext_read(p, info, fp); |
| 2627 | if (rc) | 2669 | if (rc) |
| @@ -324,6 +324,15 @@ extern int policydb_role_isvalid(struct policydb *p, unsigned int role); · 323 unmodified lines | |||
| 324 | extern int policydb_read(struct policydb *p, void *fp); | 324 | extern int policydb_read(struct policydb *p, void *fp); |
| 325 | extern int policydb_write(struct policydb *p, void *fp); | 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 | #define POLICYDB_CONFIG_MLS 1 | 336 | #define POLICYDB_CONFIG_MLS 1 |
| 328 | 337 | ||
| 329 | /* the config flags related to unknown classes/perms are bits 2 and 3 */ | 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 | *p++ = 0; | 1442 | *p++ = 0; |
| 1443 | 1443 | ||
| 1444 | usrdatum = hashtab_search(&pol->p_users.table, scontextp); | 1444 | usrdatum = symtab_search(&pol->p_users, scontextp); |
| 1445 | if (!usrdatum) | 1445 | if (!usrdatum) |
| 1446 | goto out; | 1446 | goto out; |
| 1447 | 1447 | ||
| @@ -1457,7 +1457,7 @@ static int string_to_context_struct(struct policydb *pol, · 9 unmodified lines | |||
| 1457 | 1457 | ||
| 1458 | *p++ = 0; | 1458 | *p++ = 0; |
| 1459 | 1459 | ||
| 1460 | role = hashtab_search(&pol->p_roles.table, scontextp); | 1460 | role = symtab_search(&pol->p_roles, scontextp); |
| 1461 | if (!role) | 1461 | if (!role) |
| 1462 | goto out; | 1462 | goto out; |
| 1463 | ctx->role = role->value; | 1463 | ctx->role = role->value; |
| @@ -1469,7 +1469,7 @@ static int string_to_context_struct(struct policydb *pol, · 5 unmodified lines | |||
| 1469 | oldc = *p; | 1469 | oldc = *p; |
| 1470 | *p++ = 0; | 1470 | *p++ = 0; |
| 1471 | 1471 | ||
| 1472 | typdatum = hashtab_search(&pol->p_types.table, scontextp); | 1472 | typdatum = symtab_search(&pol->p_types, scontextp); |
| 1473 | if (!typdatum || typdatum->attribute) | 1473 | if (!typdatum || typdatum->attribute) |
| 1474 | goto out; | 1474 | goto out; |
| 1475 | 1475 | ||
| @@ -1671,7 +1671,7 @@ static void filename_compute_type(struct policydb *policydb, · 195 unmodified lines | |||
| 1671 | ft.tclass = tclass; | 1671 | ft.tclass = tclass; |
| 1672 | ft.name = objname; | 1672 | ft.name = objname; |
| 1673 | 1673 | ||
| 1674 | datum = hashtab_search(&policydb->filename_trans, &ft); | 1674 | datum = policydb_filenametr_search(policydb, &ft); |
| 1675 | while (datum) { | 1675 | while (datum) { |
| 1676 | if (ebitmap_get_bit(&datum->stypes, stype - 1)) { | 1676 | if (ebitmap_get_bit(&datum->stypes, stype - 1)) { |
| 1677 | newcontext->type = datum->otype; | 1677 | newcontext->type = datum->otype; |
| @@ -1834,7 +1834,7 @@ static int security_compute_sid(struct selinux_state *state, · 156 unmodified lines | |||
| 1834 | .tclass = tclass, | 1834 | .tclass = tclass, |
| 1835 | }; | 1835 | }; |
| 1836 | 1836 | ||
| 1837 | rtd = hashtab_search(&policydb->role_tr, &rtk); | 1837 | rtd = policydb_roletr_search(policydb, &rtk); |
| 1838 | if (rtd) | 1838 | if (rtd) |
| 1839 | newcontext.role = rtd->new_role; | 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 | /* Convert the user. */ | 2025 | /* Convert the user. */ |
| 2026 | rc = -EINVAL; | 2026 | rc = -EINVAL; |
| 2027 | usrdatum = hashtab_search(&args->newp->p_users.table, | 2027 | usrdatum = symtab_search(&args->newp->p_users, |
| 2028 | sym_name(args->oldp, | 2028 | sym_name(args->oldp, |
| 2029 | SYM_USERS, oldc->user - 1)); | 2029 | SYM_USERS, oldc->user - 1)); |
| 2030 | if (!usrdatum) | 2030 | if (!usrdatum) |
| 2031 | goto bad; | 2031 | goto bad; |
| 2032 | newc->user = usrdatum->value; | 2032 | newc->user = usrdatum->value; |
| 2033 | 2033 | ||
| 2034 | /* Convert the role. */ | 2034 | /* Convert the role. */ |
| 2035 | rc = -EINVAL; | 2035 | rc = -EINVAL; |
| 2036 | role = hashtab_search(&args->newp->p_roles.table, | 2036 | role = symtab_search(&args->newp->p_roles, |
| 2037 | sym_name(args->oldp, SYM_ROLES, oldc->role - 1)); | 2037 | sym_name(args->oldp, SYM_ROLES, oldc->role - 1)); |
| 2038 | if (!role) | 2038 | if (!role) |
| 2039 | goto bad; | 2039 | goto bad; |
| 2040 | newc->role = role->value; | 2040 | newc->role = role->value; |
| 2041 | 2041 | ||
| 2042 | /* Convert the type. */ | 2042 | /* Convert the type. */ |
| 2043 | rc = -EINVAL; | 2043 | rc = -EINVAL; |
| 2044 | typdatum = hashtab_search(&args->newp->p_types.table, | 2044 | typdatum = symtab_search(&args->newp->p_types, |
| 2045 | sym_name(args->oldp, | 2045 | sym_name(args->oldp, |
| 2046 | SYM_TYPES, oldc->type - 1)); | 2046 | SYM_TYPES, oldc->type - 1)); |
| 2047 | if (!typdatum) | 2047 | if (!typdatum) |
| 2048 | goto bad; | 2048 | goto bad; |
| 2049 | newc->type = typdatum->value; | 2049 | newc->type = typdatum->value; |
| @@ -2623,7 +2623,7 @@ int security_get_user_sids(struct selinux_state *state, · 573 unmodified lines | |||
| 2623 | goto out_unlock; | 2623 | goto out_unlock; |
| 2624 | 2624 | ||
| 2625 | rc = -EINVAL; | 2625 | rc = -EINVAL; |
| 2626 | user = hashtab_search(&policydb->p_users.table, username); | 2626 | user = symtab_search(&policydb->p_users, username); |
| 2627 | if (!user) | 2627 | if (!user) |
| 2628 | goto out_unlock; | 2628 | goto out_unlock; |
| 2629 | 2629 | ||
| @@ -2979,7 +2979,7 @@ static int security_preserve_bools(struct selinux_state *state, · 349 unmodified lines | |||
| 2979 | if (rc) | 2979 | if (rc) |
| 2980 | goto out; | 2980 | goto out; |
| 2981 | for (i = 0; i < nbools; i++) { | 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 | if (booldatum) | 2983 | if (booldatum) |
| 2984 | booldatum->state = bvalues[i]; | 2984 | booldatum->state = bvalues[i]; |
| 2985 | } | 2985 | } |
| @@ -3230,7 +3230,7 @@ int security_get_permissions(struct selinux_state *state, · 244 unmodified lines | |||
| 3230 | read_lock(&state->ss->policy_rwlock); | 3230 | read_lock(&state->ss->policy_rwlock); |
| 3231 | 3231 | ||
| 3232 | rc = -EINVAL; | 3232 | rc = -EINVAL; |
| 3233 | match = hashtab_search(&policydb->p_classes.table, class); | 3233 | match = symtab_search(&policydb->p_classes, class); |
| 3234 | if (!match) { | 3234 | if (!match) { |
| 3235 | pr_err("SELinux: %s: unrecognized class %s\n", | 3235 | pr_err("SELinux: %s: unrecognized class %s\n", |
| 3236 | __func__, class); | 3236 | __func__, class); |
| @@ -3369,7 +3369,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) · 132 unmodified lines | |||
| 3369 | case AUDIT_SUBJ_USER: | 3369 | case AUDIT_SUBJ_USER: |
| 3370 | case AUDIT_OBJ_USER: | 3370 | case AUDIT_OBJ_USER: |
| 3371 | rc = -EINVAL; | 3371 | rc = -EINVAL; |
| 3372 | userdatum = hashtab_search(&policydb->p_users.table, rulestr); | 3372 | userdatum = symtab_search(&policydb->p_users, rulestr); |
| 3373 | if (!userdatum) | 3373 | if (!userdatum) |
| 3374 | goto out; | 3374 | goto out; |
| 3375 | tmprule->au_ctxt.user = userdatum->value; | 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 | case AUDIT_SUBJ_ROLE: | 3377 | case AUDIT_SUBJ_ROLE: |
| 3378 | case AUDIT_OBJ_ROLE: | 3378 | case AUDIT_OBJ_ROLE: |
| 3379 | rc = -EINVAL; | 3379 | rc = -EINVAL; |
| 3380 | roledatum = hashtab_search(&policydb->p_roles.table, rulestr); | 3380 | roledatum = symtab_search(&policydb->p_roles, rulestr); |
| 3381 | if (!roledatum) | 3381 | if (!roledatum) |
| 3382 | goto out; | 3382 | goto out; |
| 3383 | tmprule->au_ctxt.role = roledatum->value; | 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 | case AUDIT_SUBJ_TYPE: | 3385 | case AUDIT_SUBJ_TYPE: |
| 3386 | case AUDIT_OBJ_TYPE: | 3386 | case AUDIT_OBJ_TYPE: |
| 3387 | rc = -EINVAL; | 3387 | rc = -EINVAL; |
| 3388 | typedatum = hashtab_search(&policydb->p_types.table, rulestr); | 3388 | typedatum = symtab_search(&policydb->p_types, rulestr); |
| 3389 | if (!typedatum) | 3389 | if (!typedatum) |
| 3390 | goto out; | 3390 | goto out; |
| 3391 | tmprule->au_ctxt.type = typedatum->value; | 3391 | tmprule->au_ctxt.type = typedatum->value; |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | |||
| 9 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
| 10 | #include "symtab.h" | 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 | const char *p, *keyp; | 14 | const char *p, *keyp; |
| 15 | unsigned int size; | 15 | unsigned int size; |
| @@ -20,10 +20,10 @@ static unsigned int symhash(struct hashtab *h, const void *key) · 4 unmodified lines | |||
| 20 | size = strlen(keyp); | 20 | size = strlen(keyp); |
| 21 | for (p = keyp; (p - keyp) < size; p++) | 21 | for (p = keyp; (p - keyp) < size; p++) |
| 22 | val = (val << 4 | (val >> (8*sizeof(unsigned int)-4))) ^ (*p); | 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 | const char *keyp1, *keyp2; | 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 | return strcmp(keyp1, keyp2); | 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 | int symtab_init(struct symtab *s, unsigned int size) | 40 | int symtab_init(struct symtab *s, unsigned int size) |
| 37 | { | 41 | { |
| 38 | s->nprim = 0; | 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 | int symtab_init(struct symtab *s, unsigned int size); | 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 | #endif /* _SS_SYMTAB_H_ */ | 25 | #endif /* _SS_SYMTAB_H_ */ |
| 23 | 26 | ||
| 24 | 27 | ||