History

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

Pull selinux updates from Paul Moore: "Beyond the usual smattering of bug fixes, we've got three small improvements worth highlighting: - improved SELinux policy symbol table performance due to a reworking of the insert and search functions - allow reading of SELinux labels before the policy is loaded, allowing for some more "exotic" initramfs approaches - improved checking an error reporting about process class/permissions during SELinux policy load" * tag 'selinux-pr-20200803' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: complete the inlining of hashtab functions selinux: prepare for inlining of hashtab functions selinux: specialize symtab insert and search functions selinux: Fix spelling mistakes in the comments selinux: fixed a checkpatch warning with the sizeof macro selinux: log error messages on required process class / permissions scripts/selinux/mdp: fix initial SID handling selinux: allow reading labels before policy is loaded

Linus Torvalds committed 6 years ago

Commit 49e917d2 parents 9ecc6ea 54b27f915 files · +258 −166Browse files

Unified · Split

15 files
  1. scripts/selinux/mdp/mdp.c +18 −5
  2. security/selinux/hooks.c +6 −1
  3. security/selinux/netif.c +1 −1
  4. security/selinux/netnode.c +1 −1
  5. security/selinux/netport.c +1 −1
  6. security/selinux/ss/conditional.c +4 −4
  7. security/selinux/ss/conditional.h +1 −1
  8. security/selinux/ss/hashtab.c +6 −53
  9. security/selinux/ss/hashtab.h +65 −12
  10. security/selinux/ss/mls.c +12 −11
  11. security/selinux/ss/policydb.c +95 −53
  12. security/selinux/ss/policydb.h +9 −0
  13. security/selinux/ss/services.c +19 −19
  14. security/selinux/ss/symtab.c +17 −4
  15. security/selinux/ss/symtab.h +3 −0
scripts/selinux/mdp/mdp.c+18−5
@@ -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) \
security/selinux/hooks.c+6−1
@@ -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 /*
security/selinux/netif.c+1−1
@@ -124,7 +124,7 @@ static void sel_netif_destroy(struct sel_netif *netif) · 123 unmodified lines
124 * @sid: interface SID124 * @sid: interface SID
125 *125 *
126 * Description:126 * Description:
127 * This function determines the SID of a network interface by quering the127 * This function determines the SID of a network interface by querying the
128 * security policy. The result is added to the network interface table to128 * security policy. The result is added to the network interface table to
129 * speedup future queries. Returns zero on success, negative values on129 * speedup future queries. Returns zero on success, negative values on
130 * failure.130 * failure.
security/selinux/netnode.c+1−1
@@ -181,7 +181,7 @@ static void sel_netnode_insert(struct sel_netnode *node) · 180 unmodified lines
181 * @sid: node SID181 * @sid: node SID
182 *182 *
183 * Description:183 * Description:
184 * This function determines the SID of a network address by quering the184 * This function determines the SID of a network address by querying the
185 * security policy. The result is added to the network address table to185 * security policy. The result is added to the network address table to
186 * speedup future queries. Returns zero on success, negative values on186 * speedup future queries. Returns zero on success, negative values on
187 * failure.187 * failure.
security/selinux/netport.c+1−1
@@ -130,7 +130,7 @@ static void sel_netport_insert(struct sel_netport *port) · 129 unmodified lines
130 * @sid: port SID130 * @sid: port SID
131 *131 *
132 * Description:132 * Description:
133 * This function determines the SID of a network port by quering the security133 * 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 future134 * 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 *
security/selinux/ss/conditional.c+4−4
@@ -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
206int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)206int 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
security/selinux/ss/conditional.h+1−1
@@ -69,7 +69,7 @@ int cond_destroy_bool(void *key, void *datum, void *p); · 68 unmodified lines
69 69
70int cond_index_bool(void *key, void *datum, void *datap);70int cond_index_bool(void *key, void *datum, void *datap);
71 71
72int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp);72int cond_read_bool(struct policydb *p, struct symtab *s, void *fp);
73int cond_read_list(struct policydb *p, void *fp);73int cond_read_list(struct policydb *p, void *fp);
74int cond_write_bool(void *key, void *datum, void *ptr);74int cond_write_bool(void *key, void *datum, void *ptr);
75int cond_write_list(struct policydb *p, void *fp);75int cond_write_list(struct policydb *p, void *fp);
security/selinux/ss/hashtab.c+6−53
@@ -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
13static struct kmem_cache *hashtab_node_cachep;12static 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
32int hashtab_init(struct hashtab *h,31int 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
49int hashtab_insert(struct hashtab *h, void *key, void *datum)42int __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
87void *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
106void hashtab_destroy(struct hashtab *h)59void hashtab_destroy(struct hashtab *h)
107{60{
108 u32 i;61 u32 i;
security/selinux/ss/hashtab.h+65−12
@@ -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 0xffffffff14#include <linux/types.h>
15#include <linux/errno.h>
16#include <linux/sched.h>
17
18#define HASHTAB_MAX_NODES U32_MAX
19
20struct 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
16struct hashtab_node {26struct 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
32struct hashtab_info {38struct 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 */
42int hashtab_init(struct hashtab *h,48int 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,50int __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 or58 * -EINVAL for general errors or
54 0 otherwise.59 0 otherwise.
55 */60 */
56int hashtab_insert(struct hashtab *h, void *k, void *d);61static 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 or93 * 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 */
64void *hashtab_search(struct hashtab *h, const void *k);96static 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.
security/selinux/ss/mls.c+12−11
@@ -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
security/selinux/ss/policydb.c+95−53
@@ -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
414static u32 filenametr_hash(struct hashtab *h, const void *k)414static 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
429static int filenametr_cmp(struct hashtab *h, const void *k1, const void *k2)429static 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
447static u32 rangetr_hash(struct hashtab *h, const void *k)447static const struct hashtab_key_params filenametr_key_params = {
448 .hash = filenametr_hash,
449 .cmp = filenametr_cmp,
450};
451
452struct 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
458static 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
455static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2)466static 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
473static u32 role_trans_hash(struct hashtab *h, const void *k)484static const struct hashtab_key_params rangetr_key_params = {
485 .hash = rangetr_hash,
486 .cmp = rangetr_cmp,
487};
488
489struct 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
495static 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
481static int role_trans_cmp(struct hashtab *h, const void *k1, const void *k2)502static 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
518static const struct hashtab_key_params roletr_key_params = {
519 .hash = role_trans_hash,
520 .cmp = role_trans_cmp,
521};
522
523struct 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
1068static int perm_read(struct policydb *p, struct hashtab *h, void *fp)1100static 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
1101static int common_read(struct policydb *p, struct hashtab *h, void *fp)1133static 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
1265static int class_read(struct policydb *p, struct hashtab *h, void *fp)1297static 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
1360static int role_read(struct policydb *p, struct hashtab *h, void *fp)1392static 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
1416static int type_read(struct policydb *p, struct hashtab *h, void *fp)1448static 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
1490static int user_read(struct policydb *p, struct hashtab *h, void *fp)1522static 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
1540static int sens_read(struct policydb *p, struct hashtab *h, void *fp)1572static 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
1581static int cat_read(struct policydb *p, struct hashtab *h, void *fp)1613static 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
1614static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) =1646static 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)
security/selinux/ss/policydb.h+9−0
@@ -324,6 +324,15 @@ extern int policydb_role_isvalid(struct policydb *p, unsigned int role); · 323 unmodified lines
324extern int policydb_read(struct policydb *p, void *fp);324extern int policydb_read(struct policydb *p, void *fp);
325extern int policydb_write(struct policydb *p, void *fp);325extern int policydb_write(struct policydb *p, void *fp);
326 326
327extern struct filename_trans_datum *policydb_filenametr_search(
328 struct policydb *p, struct filename_trans_key *key);
329
330extern struct mls_range *policydb_rangetr_search(
331 struct policydb *p, struct range_trans *key);
332
333extern struct role_trans_datum *policydb_roletr_search(
334 struct policydb *p, struct role_trans_key *key);
335
327#define POLICYDB_CONFIG_MLS 1336#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 */
security/selinux/ss/services.c+19−19
@@ -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;
security/selinux/ss/symtab.c+17−4
@@ -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
12static unsigned int symhash(struct hashtab *h, const void *key)12static 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
26static int symcmp(struct hashtab *h, const void *key1, const void *key2)26static 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
35static const struct hashtab_key_params symtab_key_params = {
36 .hash = symhash,
37 .cmp = symcmp,
38};
35 39
36int symtab_init(struct symtab *s, unsigned int size)40int 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
46int symtab_insert(struct symtab *s, char *name, void *datum)
47{
48 return hashtab_insert(&s->table, name, datum, symtab_key_params);
49}
50
51void *symtab_search(struct symtab *s, const char *name)
52{
53 return hashtab_search(&s->table, name, symtab_key_params);
54}
security/selinux/ss/symtab.h+3−0
@@ -19,6 +19,9 @@ struct symtab { · 18 unmodified lines
19 19
20int symtab_init(struct symtab *s, unsigned int size);20int symtab_init(struct symtab *s, unsigned int size);
21 21
22int symtab_insert(struct symtab *s, char *name, void *datum);
23void *symtab_search(struct symtab *s, const char *name);
24
22#endif /* _SS_SYMTAB_H_ */25#endif /* _SS_SYMTAB_H_ */
23 26
24 27