aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/ss/avtab.c192
-rw-r--r--security/selinux/ss/avtab.h37
-rw-r--r--security/selinux/ss/conditional.c205
-rw-r--r--security/selinux/ss/ebitmap.h30
-rw-r--r--security/selinux/ss/mls.c42
-rw-r--r--security/selinux/ss/policydb.c47
-rw-r--r--security/selinux/ss/policydb.h3
-rw-r--r--security/selinux/ss/services.c76
9 files changed, 400 insertions, 235 deletions
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 71c0a19c9753..5f016c98056f 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -23,10 +23,11 @@
23#define POLICYDB_VERSION_NLCLASS 18 23#define POLICYDB_VERSION_NLCLASS 18
24#define POLICYDB_VERSION_VALIDATETRANS 19 24#define POLICYDB_VERSION_VALIDATETRANS 19
25#define POLICYDB_VERSION_MLS 19 25#define POLICYDB_VERSION_MLS 19
26#define POLICYDB_VERSION_AVTAB 20
26 27
27/* Range of policy versions we understand*/ 28/* Range of policy versions we understand*/
28#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 29#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
29#define POLICYDB_VERSION_MAX POLICYDB_VERSION_MLS 30#define POLICYDB_VERSION_MAX POLICYDB_VERSION_AVTAB
30 31
31#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM 32#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
32extern int selinux_enabled; 33extern int selinux_enabled;
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index f238c034c44e..2e71af67b5d8 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -58,6 +58,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
58{ 58{
59 int hvalue; 59 int hvalue;
60 struct avtab_node *prev, *cur, *newnode; 60 struct avtab_node *prev, *cur, *newnode;
61 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
61 62
62 if (!h) 63 if (!h)
63 return -EINVAL; 64 return -EINVAL;
@@ -69,7 +70,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
69 if (key->source_type == cur->key.source_type && 70 if (key->source_type == cur->key.source_type &&
70 key->target_type == cur->key.target_type && 71 key->target_type == cur->key.target_type &&
71 key->target_class == cur->key.target_class && 72 key->target_class == cur->key.target_class &&
72 (datum->specified & cur->datum.specified)) 73 (specified & cur->key.specified))
73 return -EEXIST; 74 return -EEXIST;
74 if (key->source_type < cur->key.source_type) 75 if (key->source_type < cur->key.source_type)
75 break; 76 break;
@@ -98,6 +99,7 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
98{ 99{
99 int hvalue; 100 int hvalue;
100 struct avtab_node *prev, *cur, *newnode; 101 struct avtab_node *prev, *cur, *newnode;
102 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
101 103
102 if (!h) 104 if (!h)
103 return NULL; 105 return NULL;
@@ -108,7 +110,7 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
108 if (key->source_type == cur->key.source_type && 110 if (key->source_type == cur->key.source_type &&
109 key->target_type == cur->key.target_type && 111 key->target_type == cur->key.target_type &&
110 key->target_class == cur->key.target_class && 112 key->target_class == cur->key.target_class &&
111 (datum->specified & cur->datum.specified)) 113 (specified & cur->key.specified))
112 break; 114 break;
113 if (key->source_type < cur->key.source_type) 115 if (key->source_type < cur->key.source_type)
114 break; 116 break;
@@ -125,10 +127,11 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
125 return newnode; 127 return newnode;
126} 128}
127 129
128struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int specified) 130struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
129{ 131{
130 int hvalue; 132 int hvalue;
131 struct avtab_node *cur; 133 struct avtab_node *cur;
134 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
132 135
133 if (!h) 136 if (!h)
134 return NULL; 137 return NULL;
@@ -138,7 +141,7 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int spe
138 if (key->source_type == cur->key.source_type && 141 if (key->source_type == cur->key.source_type &&
139 key->target_type == cur->key.target_type && 142 key->target_type == cur->key.target_type &&
140 key->target_class == cur->key.target_class && 143 key->target_class == cur->key.target_class &&
141 (specified & cur->datum.specified)) 144 (specified & cur->key.specified))
142 return &cur->datum; 145 return &cur->datum;
143 146
144 if (key->source_type < cur->key.source_type) 147 if (key->source_type < cur->key.source_type)
@@ -159,10 +162,11 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int spe
159 * conjunction with avtab_search_next_node() 162 * conjunction with avtab_search_next_node()
160 */ 163 */
161struct avtab_node* 164struct avtab_node*
162avtab_search_node(struct avtab *h, struct avtab_key *key, int specified) 165avtab_search_node(struct avtab *h, struct avtab_key *key)
163{ 166{
164 int hvalue; 167 int hvalue;
165 struct avtab_node *cur; 168 struct avtab_node *cur;
169 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
166 170
167 if (!h) 171 if (!h)
168 return NULL; 172 return NULL;
@@ -172,7 +176,7 @@ avtab_search_node(struct avtab *h, struct avtab_key *key, int specified)
172 if (key->source_type == cur->key.source_type && 176 if (key->source_type == cur->key.source_type &&
173 key->target_type == cur->key.target_type && 177 key->target_type == cur->key.target_type &&
174 key->target_class == cur->key.target_class && 178 key->target_class == cur->key.target_class &&
175 (specified & cur->datum.specified)) 179 (specified & cur->key.specified))
176 return cur; 180 return cur;
177 181
178 if (key->source_type < cur->key.source_type) 182 if (key->source_type < cur->key.source_type)
@@ -196,11 +200,12 @@ avtab_search_node_next(struct avtab_node *node, int specified)
196 if (!node) 200 if (!node)
197 return NULL; 201 return NULL;
198 202
203 specified &= ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
199 for (cur = node->next; cur; cur = cur->next) { 204 for (cur = node->next; cur; cur = cur->next) {
200 if (node->key.source_type == cur->key.source_type && 205 if (node->key.source_type == cur->key.source_type &&
201 node->key.target_type == cur->key.target_type && 206 node->key.target_type == cur->key.target_type &&
202 node->key.target_class == cur->key.target_class && 207 node->key.target_class == cur->key.target_class &&
203 (specified & cur->datum.specified)) 208 (specified & cur->key.specified))
204 return cur; 209 return cur;
205 210
206 if (node->key.source_type < cur->key.source_type) 211 if (node->key.source_type < cur->key.source_type)
@@ -278,75 +283,126 @@ void avtab_hash_eval(struct avtab *h, char *tag)
278 max_chain_len); 283 max_chain_len);
279} 284}
280 285
281int avtab_read_item(void *fp, struct avtab_datum *avdatum, struct avtab_key *avkey) 286static uint16_t spec_order[] = {
287 AVTAB_ALLOWED,
288 AVTAB_AUDITDENY,
289 AVTAB_AUDITALLOW,
290 AVTAB_TRANSITION,
291 AVTAB_CHANGE,
292 AVTAB_MEMBER
293};
294
295int avtab_read_item(void *fp, u32 vers, struct avtab *a,
296 int (*insertf)(struct avtab *a, struct avtab_key *k,
297 struct avtab_datum *d, void *p),
298 void *p)
282{ 299{
283 u32 buf[7]; 300 u16 buf16[4], enabled;
284 u32 items, items2; 301 u32 buf32[7], items, items2, val;
285 int rc; 302 struct avtab_key key;
303 struct avtab_datum datum;
304 int i, rc;
305
306 memset(&key, 0, sizeof(struct avtab_key));
307 memset(&datum, 0, sizeof(struct avtab_datum));
308
309 if (vers < POLICYDB_VERSION_AVTAB) {
310 rc = next_entry(buf32, fp, sizeof(u32));
311 if (rc < 0) {
312 printk(KERN_ERR "security: avtab: truncated entry\n");
313 return -1;
314 }
315 items2 = le32_to_cpu(buf32[0]);
316 if (items2 > ARRAY_SIZE(buf32)) {
317 printk(KERN_ERR "security: avtab: entry overflow\n");
318 return -1;
286 319
287 memset(avkey, 0, sizeof(struct avtab_key)); 320 }
288 memset(avdatum, 0, sizeof(struct avtab_datum)); 321 rc = next_entry(buf32, fp, sizeof(u32)*items2);
322 if (rc < 0) {
323 printk(KERN_ERR "security: avtab: truncated entry\n");
324 return -1;
325 }
326 items = 0;
289 327
290 rc = next_entry(buf, fp, sizeof(u32)); 328 val = le32_to_cpu(buf32[items++]);
291 if (rc < 0) { 329 key.source_type = (u16)val;
292 printk(KERN_ERR "security: avtab: truncated entry\n"); 330 if (key.source_type != val) {
293 goto bad; 331 printk("security: avtab: truncated source type\n");
294 } 332 return -1;
295 items2 = le32_to_cpu(buf[0]); 333 }
296 if (items2 > ARRAY_SIZE(buf)) { 334 val = le32_to_cpu(buf32[items++]);
297 printk(KERN_ERR "security: avtab: entry overflow\n"); 335 key.target_type = (u16)val;
298 goto bad; 336 if (key.target_type != val) {
337 printk("security: avtab: truncated target type\n");
338 return -1;
339 }
340 val = le32_to_cpu(buf32[items++]);
341 key.target_class = (u16)val;
342 if (key.target_class != val) {
343 printk("security: avtab: truncated target class\n");
344 return -1;
345 }
346
347 val = le32_to_cpu(buf32[items++]);
348 enabled = (val & AVTAB_ENABLED_OLD) ? AVTAB_ENABLED : 0;
349
350 if (!(val & (AVTAB_AV | AVTAB_TYPE))) {
351 printk("security: avtab: null entry\n");
352 return -1;
353 }
354 if ((val & AVTAB_AV) &&
355 (val & AVTAB_TYPE)) {
356 printk("security: avtab: entry has both access vectors and types\n");
357 return -1;
358 }
359
360 for (i = 0; i < sizeof(spec_order)/sizeof(u16); i++) {
361 if (val & spec_order[i]) {
362 key.specified = spec_order[i] | enabled;
363 datum.data = le32_to_cpu(buf32[items++]);
364 rc = insertf(a, &key, &datum, p);
365 if (rc) return rc;
366 }
367 }
368
369 if (items != items2) {
370 printk("security: avtab: entry only had %d items, expected %d\n", items2, items);
371 return -1;
372 }
373 return 0;
299 } 374 }
300 rc = next_entry(buf, fp, sizeof(u32)*items2); 375
376 rc = next_entry(buf16, fp, sizeof(u16)*4);
301 if (rc < 0) { 377 if (rc < 0) {
302 printk(KERN_ERR "security: avtab: truncated entry\n"); 378 printk("security: avtab: truncated entry\n");
303 goto bad; 379 return -1;
304 } 380 }
381
305 items = 0; 382 items = 0;
306 avkey->source_type = le32_to_cpu(buf[items++]); 383 key.source_type = le16_to_cpu(buf16[items++]);
307 avkey->target_type = le32_to_cpu(buf[items++]); 384 key.target_type = le16_to_cpu(buf16[items++]);
308 avkey->target_class = le32_to_cpu(buf[items++]); 385 key.target_class = le16_to_cpu(buf16[items++]);
309 avdatum->specified = le32_to_cpu(buf[items++]); 386 key.specified = le16_to_cpu(buf16[items++]);
310 if (!(avdatum->specified & (AVTAB_AV | AVTAB_TYPE))) { 387
311 printk(KERN_ERR "security: avtab: null entry\n"); 388 rc = next_entry(buf32, fp, sizeof(u32));
312 goto bad; 389 if (rc < 0) {
313 } 390 printk("security: avtab: truncated entry\n");
314 if ((avdatum->specified & AVTAB_AV) && 391 return -1;
315 (avdatum->specified & AVTAB_TYPE)) {
316 printk(KERN_ERR "security: avtab: entry has both access vectors and types\n");
317 goto bad;
318 }
319 if (avdatum->specified & AVTAB_AV) {
320 if (avdatum->specified & AVTAB_ALLOWED)
321 avtab_allowed(avdatum) = le32_to_cpu(buf[items++]);
322 if (avdatum->specified & AVTAB_AUDITDENY)
323 avtab_auditdeny(avdatum) = le32_to_cpu(buf[items++]);
324 if (avdatum->specified & AVTAB_AUDITALLOW)
325 avtab_auditallow(avdatum) = le32_to_cpu(buf[items++]);
326 } else {
327 if (avdatum->specified & AVTAB_TRANSITION)
328 avtab_transition(avdatum) = le32_to_cpu(buf[items++]);
329 if (avdatum->specified & AVTAB_CHANGE)
330 avtab_change(avdatum) = le32_to_cpu(buf[items++]);
331 if (avdatum->specified & AVTAB_MEMBER)
332 avtab_member(avdatum) = le32_to_cpu(buf[items++]);
333 }
334 if (items != items2) {
335 printk(KERN_ERR "security: avtab: entry only had %d items, expected %d\n",
336 items2, items);
337 goto bad;
338 } 392 }
393 datum.data = le32_to_cpu(*buf32);
394 return insertf(a, &key, &datum, p);
395}
339 396
340 return 0; 397static int avtab_insertf(struct avtab *a, struct avtab_key *k,
341bad: 398 struct avtab_datum *d, void *p)
342 return -1; 399{
400 return avtab_insert(a, k, d);
343} 401}
344 402
345int avtab_read(struct avtab *a, void *fp, u32 config) 403int avtab_read(struct avtab *a, void *fp, u32 vers)
346{ 404{
347 int rc; 405 int rc;
348 struct avtab_key avkey;
349 struct avtab_datum avdatum;
350 u32 buf[1]; 406 u32 buf[1];
351 u32 nel, i; 407 u32 nel, i;
352 408
@@ -363,16 +419,14 @@ int avtab_read(struct avtab *a, void *fp, u32 config)
363 goto bad; 419 goto bad;
364 } 420 }
365 for (i = 0; i < nel; i++) { 421 for (i = 0; i < nel; i++) {
366 if (avtab_read_item(fp, &avdatum, &avkey)) { 422 rc = avtab_read_item(fp,vers, a, avtab_insertf, NULL);
367 rc = -EINVAL;
368 goto bad;
369 }
370 rc = avtab_insert(a, &avkey, &avdatum);
371 if (rc) { 423 if (rc) {
372 if (rc == -ENOMEM) 424 if (rc == -ENOMEM)
373 printk(KERN_ERR "security: avtab: out of memory\n"); 425 printk(KERN_ERR "security: avtab: out of memory\n");
374 if (rc == -EEXIST) 426 else if (rc == -EEXIST)
375 printk(KERN_ERR "security: avtab: duplicate entry\n"); 427 printk(KERN_ERR "security: avtab: duplicate entry\n");
428 else
429 rc = -EINVAL;
376 goto bad; 430 goto bad;
377 } 431 }
378 } 432 }
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index 519d4f6dc655..0a90d939af93 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -21,12 +21,9 @@
21#define _SS_AVTAB_H_ 21#define _SS_AVTAB_H_
22 22
23struct avtab_key { 23struct avtab_key {
24 u32 source_type; /* source type */ 24 u16 source_type; /* source type */
25 u32 target_type; /* target type */ 25 u16 target_type; /* target type */
26 u32 target_class; /* target object class */ 26 u16 target_class; /* target object class */
27};
28
29struct avtab_datum {
30#define AVTAB_ALLOWED 1 27#define AVTAB_ALLOWED 1
31#define AVTAB_AUDITALLOW 2 28#define AVTAB_AUDITALLOW 2
32#define AVTAB_AUDITDENY 4 29#define AVTAB_AUDITDENY 4
@@ -35,15 +32,13 @@ struct avtab_datum {
35#define AVTAB_MEMBER 32 32#define AVTAB_MEMBER 32
36#define AVTAB_CHANGE 64 33#define AVTAB_CHANGE 64
37#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) 34#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)
38#define AVTAB_ENABLED 0x80000000 /* reserved for used in cond_avtab */ 35#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */
39 u32 specified; /* what fields are specified */ 36#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */
40 u32 data[3]; /* access vectors or types */ 37 u16 specified; /* what field is specified */
41#define avtab_allowed(x) (x)->data[0] 38};
42#define avtab_auditdeny(x) (x)->data[1] 39
43#define avtab_auditallow(x) (x)->data[2] 40struct avtab_datum {
44#define avtab_transition(x) (x)->data[0] 41 u32 data; /* access vector or type value */
45#define avtab_change(x) (x)->data[1]
46#define avtab_member(x) (x)->data[2]
47}; 42};
48 43
49struct avtab_node { 44struct avtab_node {
@@ -58,17 +53,21 @@ struct avtab {
58}; 53};
59 54
60int avtab_init(struct avtab *); 55int avtab_init(struct avtab *);
61struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k, int specified); 56struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k);
62void avtab_destroy(struct avtab *h); 57void avtab_destroy(struct avtab *h);
63void avtab_hash_eval(struct avtab *h, char *tag); 58void avtab_hash_eval(struct avtab *h, char *tag);
64 59
65int avtab_read_item(void *fp, struct avtab_datum *avdatum, struct avtab_key *avkey); 60int avtab_read_item(void *fp, uint32_t vers, struct avtab *a,
66int avtab_read(struct avtab *a, void *fp, u32 config); 61 int (*insert)(struct avtab *a, struct avtab_key *k,
62 struct avtab_datum *d, void *p),
63 void *p);
64
65int avtab_read(struct avtab *a, void *fp, u32 vers);
67 66
68struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, 67struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key,
69 struct avtab_datum *datum); 68 struct avtab_datum *datum);
70 69
71struct avtab_node *avtab_search_node(struct avtab *h, struct avtab_key *key, int specified); 70struct avtab_node *avtab_search_node(struct avtab *h, struct avtab_key *key);
72 71
73struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified); 72struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified);
74 73
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index e2057f5a411a..b81cd6688978 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -100,18 +100,18 @@ int evaluate_cond_node(struct policydb *p, struct cond_node *node)
100 /* turn the rules on or off */ 100 /* turn the rules on or off */
101 for (cur = node->true_list; cur != NULL; cur = cur->next) { 101 for (cur = node->true_list; cur != NULL; cur = cur->next) {
102 if (new_state <= 0) { 102 if (new_state <= 0) {
103 cur->node->datum.specified &= ~AVTAB_ENABLED; 103 cur->node->key.specified &= ~AVTAB_ENABLED;
104 } else { 104 } else {
105 cur->node->datum.specified |= AVTAB_ENABLED; 105 cur->node->key.specified |= AVTAB_ENABLED;
106 } 106 }
107 } 107 }
108 108
109 for (cur = node->false_list; cur != NULL; cur = cur->next) { 109 for (cur = node->false_list; cur != NULL; cur = cur->next) {
110 /* -1 or 1 */ 110 /* -1 or 1 */
111 if (new_state) { 111 if (new_state) {
112 cur->node->datum.specified &= ~AVTAB_ENABLED; 112 cur->node->key.specified &= ~AVTAB_ENABLED;
113 } else { 113 } else {
114 cur->node->datum.specified |= AVTAB_ENABLED; 114 cur->node->key.specified |= AVTAB_ENABLED;
115 } 115 }
116 } 116 }
117 } 117 }
@@ -252,104 +252,126 @@ err:
252 return -1; 252 return -1;
253} 253}
254 254
255static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list **ret_list, 255struct cond_insertf_data
256 struct cond_av_list *other)
257{ 256{
258 struct cond_av_list *list, *last = NULL, *cur; 257 struct policydb *p;
259 struct avtab_key key; 258 struct cond_av_list *other;
260 struct avtab_datum datum; 259 struct cond_av_list *head;
260 struct cond_av_list *tail;
261};
262
263static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum *d, void *ptr)
264{
265 struct cond_insertf_data *data = ptr;
266 struct policydb *p = data->p;
267 struct cond_av_list *other = data->other, *list, *cur;
261 struct avtab_node *node_ptr; 268 struct avtab_node *node_ptr;
262 int rc;
263 u32 buf[1], i, len;
264 u8 found; 269 u8 found;
265 270
266 *ret_list = NULL;
267
268 len = 0;
269 rc = next_entry(buf, fp, sizeof buf);
270 if (rc < 0)
271 return -1;
272
273 len = le32_to_cpu(buf[0]);
274 if (len == 0) {
275 return 0;
276 }
277 271
278 for (i = 0; i < len; i++) { 272 /*
279 if (avtab_read_item(fp, &datum, &key)) 273 * For type rules we have to make certain there aren't any
274 * conflicting rules by searching the te_avtab and the
275 * cond_te_avtab.
276 */
277 if (k->specified & AVTAB_TYPE) {
278 if (avtab_search(&p->te_avtab, k)) {
279 printk("security: type rule already exists outside of a conditional.");
280 goto err; 280 goto err;
281 281 }
282 /* 282 /*
283 * For type rules we have to make certain there aren't any 283 * If we are reading the false list other will be a pointer to
284 * conflicting rules by searching the te_avtab and the 284 * the true list. We can have duplicate entries if there is only
285 * cond_te_avtab. 285 * 1 other entry and it is in our true list.
286 *
287 * If we are reading the true list (other == NULL) there shouldn't
288 * be any other entries.
286 */ 289 */
287 if (datum.specified & AVTAB_TYPE) { 290 if (other) {
288 if (avtab_search(&p->te_avtab, &key, AVTAB_TYPE)) { 291 node_ptr = avtab_search_node(&p->te_cond_avtab, k);
289 printk("security: type rule already exists outside of a conditional."); 292 if (node_ptr) {
290 goto err; 293 if (avtab_search_node_next(node_ptr, k->specified)) {
291 } 294 printk("security: too many conflicting type rules.");
292 /* 295 goto err;
293 * If we are reading the false list other will be a pointer to 296 }
294 * the true list. We can have duplicate entries if there is only 297 found = 0;
295 * 1 other entry and it is in our true list. 298 for (cur = other; cur != NULL; cur = cur->next) {
296 * 299 if (cur->node == node_ptr) {
297 * If we are reading the true list (other == NULL) there shouldn't 300 found = 1;
298 * be any other entries. 301 break;
299 */
300 if (other) {
301 node_ptr = avtab_search_node(&p->te_cond_avtab, &key, AVTAB_TYPE);
302 if (node_ptr) {
303 if (avtab_search_node_next(node_ptr, AVTAB_TYPE)) {
304 printk("security: too many conflicting type rules.");
305 goto err;
306 }
307 found = 0;
308 for (cur = other; cur != NULL; cur = cur->next) {
309 if (cur->node == node_ptr) {
310 found = 1;
311 break;
312 }
313 }
314 if (!found) {
315 printk("security: conflicting type rules.");
316 goto err;
317 } 302 }
318 } 303 }
319 } else { 304 if (!found) {
320 if (avtab_search(&p->te_cond_avtab, &key, AVTAB_TYPE)) { 305 printk("security: conflicting type rules.\n");
321 printk("security: conflicting type rules when adding type rule for true.");
322 goto err; 306 goto err;
323 } 307 }
324 } 308 }
309 } else {
310 if (avtab_search(&p->te_cond_avtab, k)) {
311 printk("security: conflicting type rules when adding type rule for true.\n");
312 goto err;
313 }
325 } 314 }
326 node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, &key, &datum); 315 }
327 if (!node_ptr) {
328 printk("security: could not insert rule.");
329 goto err;
330 }
331
332 list = kmalloc(sizeof(struct cond_av_list), GFP_KERNEL);
333 if (!list)
334 goto err;
335 memset(list, 0, sizeof(struct cond_av_list));
336
337 list->node = node_ptr;
338 if (i == 0)
339 *ret_list = list;
340 else
341 last->next = list;
342 last = list;
343 316
317 node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, k, d);
318 if (!node_ptr) {
319 printk("security: could not insert rule.");
320 goto err;
344 } 321 }
345 322
323 list = kmalloc(sizeof(struct cond_av_list), GFP_KERNEL);
324 if (!list)
325 goto err;
326 memset(list, 0, sizeof(*list));
327
328 list->node = node_ptr;
329 if (!data->head)
330 data->head = list;
331 else
332 data->tail->next = list;
333 data->tail = list;
346 return 0; 334 return 0;
335
347err: 336err:
348 cond_av_list_destroy(*ret_list); 337 cond_av_list_destroy(data->head);
349 *ret_list = NULL; 338 data->head = NULL;
350 return -1; 339 return -1;
351} 340}
352 341
342static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list **ret_list, struct cond_av_list *other)
343{
344 int i, rc;
345 u32 buf[1], len;
346 struct cond_insertf_data data;
347
348 *ret_list = NULL;
349
350 len = 0;
351 rc = next_entry(buf, fp, sizeof(u32));
352 if (rc < 0)
353 return -1;
354
355 len = le32_to_cpu(buf[0]);
356 if (len == 0) {
357 return 0;
358 }
359
360 data.p = p;
361 data.other = other;
362 data.head = NULL;
363 data.tail = NULL;
364 for (i = 0; i < len; i++) {
365 rc = avtab_read_item(fp, p->policyvers, &p->te_cond_avtab, cond_insertf, &data);
366 if (rc)
367 return rc;
368
369 }
370
371 *ret_list = data.head;
372 return 0;
373}
374
353static int expr_isvalid(struct policydb *p, struct cond_expr *expr) 375static int expr_isvalid(struct policydb *p, struct cond_expr *expr)
354{ 376{
355 if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) { 377 if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) {
@@ -452,6 +474,7 @@ int cond_read_list(struct policydb *p, void *fp)
452 return 0; 474 return 0;
453err: 475err:
454 cond_list_destroy(p->cond_list); 476 cond_list_destroy(p->cond_list);
477 p->cond_list = NULL;
455 return -1; 478 return -1;
456} 479}
457 480
@@ -465,22 +488,22 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decisi
465 if(!ctab || !key || !avd) 488 if(!ctab || !key || !avd)
466 return; 489 return;
467 490
468 for(node = avtab_search_node(ctab, key, AVTAB_AV); node != NULL; 491 for(node = avtab_search_node(ctab, key); node != NULL;
469 node = avtab_search_node_next(node, AVTAB_AV)) { 492 node = avtab_search_node_next(node, key->specified)) {
470 if ( (__u32) (AVTAB_ALLOWED|AVTAB_ENABLED) == 493 if ( (u16) (AVTAB_ALLOWED|AVTAB_ENABLED) ==
471 (node->datum.specified & (AVTAB_ALLOWED|AVTAB_ENABLED))) 494 (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED)))
472 avd->allowed |= avtab_allowed(&node->datum); 495 avd->allowed |= node->datum.data;
473 if ( (__u32) (AVTAB_AUDITDENY|AVTAB_ENABLED) == 496 if ( (u16) (AVTAB_AUDITDENY|AVTAB_ENABLED) ==
474 (node->datum.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED))) 497 (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED)))
475 /* Since a '0' in an auditdeny mask represents a 498 /* Since a '0' in an auditdeny mask represents a
476 * permission we do NOT want to audit (dontaudit), we use 499 * permission we do NOT want to audit (dontaudit), we use
477 * the '&' operand to ensure that all '0's in the mask 500 * the '&' operand to ensure that all '0's in the mask
478 * are retained (much unlike the allow and auditallow cases). 501 * are retained (much unlike the allow and auditallow cases).
479 */ 502 */
480 avd->auditdeny &= avtab_auditdeny(&node->datum); 503 avd->auditdeny &= node->datum.data;
481 if ( (__u32) (AVTAB_AUDITALLOW|AVTAB_ENABLED) == 504 if ( (u16) (AVTAB_AUDITALLOW|AVTAB_ENABLED) ==
482 (node->datum.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED))) 505 (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED)))
483 avd->auditallow |= avtab_auditallow(&node->datum); 506 avd->auditallow |= node->datum.data;
484 } 507 }
485 return; 508 return;
486} 509}
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 471370233fd9..8bf41055a6cb 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -32,11 +32,41 @@ struct ebitmap {
32#define ebitmap_length(e) ((e)->highbit) 32#define ebitmap_length(e) ((e)->highbit)
33#define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0) 33#define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0)
34 34
35static inline unsigned int ebitmap_start(struct ebitmap *e,
36 struct ebitmap_node **n)
37{
38 *n = e->node;
39 return ebitmap_startbit(e);
40}
41
35static inline void ebitmap_init(struct ebitmap *e) 42static inline void ebitmap_init(struct ebitmap *e)
36{ 43{
37 memset(e, 0, sizeof(*e)); 44 memset(e, 0, sizeof(*e));
38} 45}
39 46
47static inline unsigned int ebitmap_next(struct ebitmap_node **n,
48 unsigned int bit)
49{
50 if ((bit == ((*n)->startbit + MAPSIZE - 1)) &&
51 (*n)->next) {
52 *n = (*n)->next;
53 return (*n)->startbit;
54 }
55
56 return (bit+1);
57}
58
59static inline int ebitmap_node_get_bit(struct ebitmap_node * n,
60 unsigned int bit)
61{
62 if (n->map & (MAPBIT << (bit - n->startbit)))
63 return 1;
64 return 0;
65}
66
67#define ebitmap_for_each_bit(e, n, bit) \
68 for (bit = ebitmap_start(e, &n); bit < ebitmap_length(e); bit = ebitmap_next(&n, bit)) \
69
40int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); 70int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2);
41int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); 71int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src);
42int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2); 72int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2);
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index d4c32c39ccc9..aaefac2921f1 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -27,6 +27,7 @@
27int mls_compute_context_len(struct context * context) 27int mls_compute_context_len(struct context * context)
28{ 28{
29 int i, l, len, range; 29 int i, l, len, range;
30 struct ebitmap_node *node;
30 31
31 if (!selinux_mls_enabled) 32 if (!selinux_mls_enabled)
32 return 0; 33 return 0;
@@ -36,24 +37,24 @@ int mls_compute_context_len(struct context * context)
36 range = 0; 37 range = 0;
37 len += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); 38 len += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]);
38 39
39 for (i = 1; i <= ebitmap_length(&context->range.level[l].cat); i++) { 40 ebitmap_for_each_bit(&context->range.level[l].cat, node, i) {
40 if (ebitmap_get_bit(&context->range.level[l].cat, i - 1)) { 41 if (ebitmap_node_get_bit(node, i)) {
41 if (range) { 42 if (range) {
42 range++; 43 range++;
43 continue; 44 continue;
44 } 45 }
45 46
46 len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1; 47 len += strlen(policydb.p_cat_val_to_name[i]) + 1;
47 range++; 48 range++;
48 } else { 49 } else {
49 if (range > 1) 50 if (range > 1)
50 len += strlen(policydb.p_cat_val_to_name[i - 2]) + 1; 51 len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1;
51 range = 0; 52 range = 0;
52 } 53 }
53 } 54 }
54 /* Handle case where last category is the end of range */ 55 /* Handle case where last category is the end of range */
55 if (range > 1) 56 if (range > 1)
56 len += strlen(policydb.p_cat_val_to_name[i - 2]) + 1; 57 len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1;
57 58
58 if (l == 0) { 59 if (l == 0) {
59 if (mls_level_eq(&context->range.level[0], 60 if (mls_level_eq(&context->range.level[0],
@@ -77,6 +78,7 @@ void mls_sid_to_context(struct context *context,
77{ 78{
78 char *scontextp; 79 char *scontextp;
79 int i, l, range, wrote_sep; 80 int i, l, range, wrote_sep;
81 struct ebitmap_node *node;
80 82
81 if (!selinux_mls_enabled) 83 if (!selinux_mls_enabled)
82 return; 84 return;
@@ -94,8 +96,8 @@ void mls_sid_to_context(struct context *context,
94 scontextp += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); 96 scontextp += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]);
95 97
96 /* categories */ 98 /* categories */
97 for (i = 1; i <= ebitmap_length(&context->range.level[l].cat); i++) { 99 ebitmap_for_each_bit(&context->range.level[l].cat, node, i) {
98 if (ebitmap_get_bit(&context->range.level[l].cat, i - 1)) { 100 if (ebitmap_node_get_bit(node, i)) {
99 if (range) { 101 if (range) {
100 range++; 102 range++;
101 continue; 103 continue;
@@ -106,8 +108,8 @@ void mls_sid_to_context(struct context *context,
106 wrote_sep = 1; 108 wrote_sep = 1;
107 } else 109 } else
108 *scontextp++ = ','; 110 *scontextp++ = ',';
109 strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]); 111 strcpy(scontextp, policydb.p_cat_val_to_name[i]);
110 scontextp += strlen(policydb.p_cat_val_to_name[i - 1]); 112 scontextp += strlen(policydb.p_cat_val_to_name[i]);
111 range++; 113 range++;
112 } else { 114 } else {
113 if (range > 1) { 115 if (range > 1) {
@@ -116,8 +118,8 @@ void mls_sid_to_context(struct context *context,
116 else 118 else
117 *scontextp++ = ','; 119 *scontextp++ = ',';
118 120
119 strcpy(scontextp, policydb.p_cat_val_to_name[i - 2]); 121 strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]);
120 scontextp += strlen(policydb.p_cat_val_to_name[i - 2]); 122 scontextp += strlen(policydb.p_cat_val_to_name[i - 1]);
121 } 123 }
122 range = 0; 124 range = 0;
123 } 125 }
@@ -130,8 +132,8 @@ void mls_sid_to_context(struct context *context,
130 else 132 else
131 *scontextp++ = ','; 133 *scontextp++ = ',';
132 134
133 strcpy(scontextp, policydb.p_cat_val_to_name[i - 2]); 135 strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]);
134 scontextp += strlen(policydb.p_cat_val_to_name[i - 2]); 136 scontextp += strlen(policydb.p_cat_val_to_name[i - 1]);
135 } 137 }
136 138
137 if (l == 0) { 139 if (l == 0) {
@@ -157,6 +159,7 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
157{ 159{
158 struct level_datum *levdatum; 160 struct level_datum *levdatum;
159 struct user_datum *usrdatum; 161 struct user_datum *usrdatum;
162 struct ebitmap_node *node;
160 int i, l; 163 int i, l;
161 164
162 if (!selinux_mls_enabled) 165 if (!selinux_mls_enabled)
@@ -179,11 +182,11 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
179 if (!levdatum) 182 if (!levdatum)
180 return 0; 183 return 0;
181 184
182 for (i = 1; i <= ebitmap_length(&c->range.level[l].cat); i++) { 185 ebitmap_for_each_bit(&c->range.level[l].cat, node, i) {
183 if (ebitmap_get_bit(&c->range.level[l].cat, i - 1)) { 186 if (ebitmap_node_get_bit(node, i)) {
184 if (i > p->p_cats.nprim) 187 if (i > p->p_cats.nprim)
185 return 0; 188 return 0;
186 if (!ebitmap_get_bit(&levdatum->level->cat, i - 1)) 189 if (!ebitmap_get_bit(&levdatum->level->cat, i))
187 /* 190 /*
188 * Category may not be associated with 191 * Category may not be associated with
189 * sensitivity in low level. 192 * sensitivity in low level.
@@ -468,6 +471,7 @@ int mls_convert_context(struct policydb *oldp,
468 struct level_datum *levdatum; 471 struct level_datum *levdatum;
469 struct cat_datum *catdatum; 472 struct cat_datum *catdatum;
470 struct ebitmap bitmap; 473 struct ebitmap bitmap;
474 struct ebitmap_node *node;
471 int l, i; 475 int l, i;
472 476
473 if (!selinux_mls_enabled) 477 if (!selinux_mls_enabled)
@@ -482,12 +486,12 @@ int mls_convert_context(struct policydb *oldp,
482 c->range.level[l].sens = levdatum->level->sens; 486 c->range.level[l].sens = levdatum->level->sens;
483 487
484 ebitmap_init(&bitmap); 488 ebitmap_init(&bitmap);
485 for (i = 1; i <= ebitmap_length(&c->range.level[l].cat); i++) { 489 ebitmap_for_each_bit(&c->range.level[l].cat, node, i) {
486 if (ebitmap_get_bit(&c->range.level[l].cat, i - 1)) { 490 if (ebitmap_node_get_bit(node, i)) {
487 int rc; 491 int rc;
488 492
489 catdatum = hashtab_search(newp->p_cats.table, 493 catdatum = hashtab_search(newp->p_cats.table,
490 oldp->p_cat_val_to_name[i - 1]); 494 oldp->p_cat_val_to_name[i]);
491 if (!catdatum) 495 if (!catdatum)
492 return -EINVAL; 496 return -EINVAL;
493 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); 497 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 785c33cf4864..7b03fa0f92b0 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -91,6 +91,11 @@ static struct policydb_compat_info policydb_compat[] = {
91 .sym_num = SYM_NUM, 91 .sym_num = SYM_NUM,
92 .ocon_num = OCON_NUM, 92 .ocon_num = OCON_NUM,
93 }, 93 },
94 {
95 .version = POLICYDB_VERSION_AVTAB,
96 .sym_num = SYM_NUM,
97 .ocon_num = OCON_NUM,
98 },
94}; 99};
95 100
96static struct policydb_compat_info *policydb_lookup_compat(int version) 101static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -584,6 +589,9 @@ void policydb_destroy(struct policydb *p)
584 struct ocontext *c, *ctmp; 589 struct ocontext *c, *ctmp;
585 struct genfs *g, *gtmp; 590 struct genfs *g, *gtmp;
586 int i; 591 int i;
592 struct role_allow *ra, *lra = NULL;
593 struct role_trans *tr, *ltr = NULL;
594 struct range_trans *rt, *lrt = NULL;
587 595
588 for (i = 0; i < SYM_NUM; i++) { 596 for (i = 0; i < SYM_NUM; i++) {
589 hashtab_map(p->symtab[i].table, destroy_f[i], NULL); 597 hashtab_map(p->symtab[i].table, destroy_f[i], NULL);
@@ -624,6 +632,28 @@ void policydb_destroy(struct policydb *p)
624 632
625 cond_policydb_destroy(p); 633 cond_policydb_destroy(p);
626 634
635 for (tr = p->role_tr; tr; tr = tr->next) {
636 if (ltr) kfree(ltr);
637 ltr = tr;
638 }
639 if (ltr) kfree(ltr);
640
641 for (ra = p->role_allow; ra; ra = ra -> next) {
642 if (lra) kfree(lra);
643 lra = ra;
644 }
645 if (lra) kfree(lra);
646
647 for (rt = p->range_tr; rt; rt = rt -> next) {
648 if (lrt) kfree(lrt);
649 lrt = rt;
650 }
651 if (lrt) kfree(lrt);
652
653 for (i = 0; i < p->p_types.nprim; i++)
654 ebitmap_destroy(&p->type_attr_map[i]);
655 kfree(p->type_attr_map);
656
627 return; 657 return;
628} 658}
629 659
@@ -1511,7 +1541,7 @@ int policydb_read(struct policydb *p, void *fp)
1511 p->symtab[i].nprim = nprim; 1541 p->symtab[i].nprim = nprim;
1512 } 1542 }
1513 1543
1514 rc = avtab_read(&p->te_avtab, fp, config); 1544 rc = avtab_read(&p->te_avtab, fp, p->policyvers);
1515 if (rc) 1545 if (rc)
1516 goto bad; 1546 goto bad;
1517 1547
@@ -1825,6 +1855,21 @@ int policydb_read(struct policydb *p, void *fp)
1825 } 1855 }
1826 } 1856 }
1827 1857
1858 p->type_attr_map = kmalloc(p->p_types.nprim*sizeof(struct ebitmap), GFP_KERNEL);
1859 if (!p->type_attr_map)
1860 goto bad;
1861
1862 for (i = 0; i < p->p_types.nprim; i++) {
1863 ebitmap_init(&p->type_attr_map[i]);
1864 if (p->policyvers >= POLICYDB_VERSION_AVTAB) {
1865 if (ebitmap_read(&p->type_attr_map[i], fp))
1866 goto bad;
1867 }
1868 /* add the type itself as the degenerate case */
1869 if (ebitmap_set_bit(&p->type_attr_map[i], i, 1))
1870 goto bad;
1871 }
1872
1828 rc = 0; 1873 rc = 0;
1829out: 1874out:
1830 return rc; 1875 return rc;
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 2470e2a1a1c3..b1340711f721 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -237,6 +237,9 @@ struct policydb {
237 /* range transitions */ 237 /* range transitions */
238 struct range_trans *range_tr; 238 struct range_trans *range_tr;
239 239
240 /* type -> attribute reverse mapping */
241 struct ebitmap *type_attr_map;
242
240 unsigned int policyvers; 243 unsigned int policyvers;
241}; 244};
242 245
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 014120474e69..92b89dc99bcd 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -266,8 +266,11 @@ static int context_struct_compute_av(struct context *scontext,
266 struct constraint_node *constraint; 266 struct constraint_node *constraint;
267 struct role_allow *ra; 267 struct role_allow *ra;
268 struct avtab_key avkey; 268 struct avtab_key avkey;
269 struct avtab_datum *avdatum; 269 struct avtab_node *node;
270 struct class_datum *tclass_datum; 270 struct class_datum *tclass_datum;
271 struct ebitmap *sattr, *tattr;
272 struct ebitmap_node *snode, *tnode;
273 unsigned int i, j;
271 274
272 /* 275 /*
273 * Remap extended Netlink classes for old policy versions. 276 * Remap extended Netlink classes for old policy versions.
@@ -300,21 +303,34 @@ static int context_struct_compute_av(struct context *scontext,
300 * If a specific type enforcement rule was defined for 303 * If a specific type enforcement rule was defined for
301 * this permission check, then use it. 304 * this permission check, then use it.
302 */ 305 */
303 avkey.source_type = scontext->type;
304 avkey.target_type = tcontext->type;
305 avkey.target_class = tclass; 306 avkey.target_class = tclass;
306 avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_AV); 307 avkey.specified = AVTAB_AV;
307 if (avdatum) { 308 sattr = &policydb.type_attr_map[scontext->type - 1];
308 if (avdatum->specified & AVTAB_ALLOWED) 309 tattr = &policydb.type_attr_map[tcontext->type - 1];
309 avd->allowed = avtab_allowed(avdatum); 310 ebitmap_for_each_bit(sattr, snode, i) {
310 if (avdatum->specified & AVTAB_AUDITDENY) 311 if (!ebitmap_node_get_bit(snode, i))
311 avd->auditdeny = avtab_auditdeny(avdatum); 312 continue;
312 if (avdatum->specified & AVTAB_AUDITALLOW) 313 ebitmap_for_each_bit(tattr, tnode, j) {
313 avd->auditallow = avtab_auditallow(avdatum); 314 if (!ebitmap_node_get_bit(tnode, j))
314 } 315 continue;
316 avkey.source_type = i + 1;
317 avkey.target_type = j + 1;
318 for (node = avtab_search_node(&policydb.te_avtab, &avkey);
319 node != NULL;
320 node = avtab_search_node_next(node, avkey.specified)) {
321 if (node->key.specified == AVTAB_ALLOWED)
322 avd->allowed |= node->datum.data;
323 else if (node->key.specified == AVTAB_AUDITALLOW)
324 avd->auditallow |= node->datum.data;
325 else if (node->key.specified == AVTAB_AUDITDENY)
326 avd->auditdeny &= node->datum.data;
327 }
315 328
316 /* Check conditional av table for additional permissions */ 329 /* Check conditional av table for additional permissions */
317 cond_compute_av(&policydb.te_cond_avtab, &avkey, avd); 330 cond_compute_av(&policydb.te_cond_avtab, &avkey, avd);
331
332 }
333 }
318 334
319 /* 335 /*
320 * Remove any permissions prohibited by a constraint (this includes 336 * Remove any permissions prohibited by a constraint (this includes
@@ -797,7 +813,6 @@ static int security_compute_sid(u32 ssid,
797 struct avtab_key avkey; 813 struct avtab_key avkey;
798 struct avtab_datum *avdatum; 814 struct avtab_datum *avdatum;
799 struct avtab_node *node; 815 struct avtab_node *node;
800 unsigned int type_change = 0;
801 int rc = 0; 816 int rc = 0;
802 817
803 if (!ss_initialized) { 818 if (!ss_initialized) {
@@ -862,33 +877,23 @@ static int security_compute_sid(u32 ssid,
862 avkey.source_type = scontext->type; 877 avkey.source_type = scontext->type;
863 avkey.target_type = tcontext->type; 878 avkey.target_type = tcontext->type;
864 avkey.target_class = tclass; 879 avkey.target_class = tclass;
865 avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_TYPE); 880 avkey.specified = specified;
881 avdatum = avtab_search(&policydb.te_avtab, &avkey);
866 882
867 /* If no permanent rule, also check for enabled conditional rules */ 883 /* If no permanent rule, also check for enabled conditional rules */
868 if(!avdatum) { 884 if(!avdatum) {
869 node = avtab_search_node(&policydb.te_cond_avtab, &avkey, specified); 885 node = avtab_search_node(&policydb.te_cond_avtab, &avkey);
870 for (; node != NULL; node = avtab_search_node_next(node, specified)) { 886 for (; node != NULL; node = avtab_search_node_next(node, specified)) {
871 if (node->datum.specified & AVTAB_ENABLED) { 887 if (node->key.specified & AVTAB_ENABLED) {
872 avdatum = &node->datum; 888 avdatum = &node->datum;
873 break; 889 break;
874 } 890 }
875 } 891 }
876 } 892 }
877 893
878 type_change = (avdatum && (avdatum->specified & specified)); 894 if (avdatum) {
879 if (type_change) {
880 /* Use the type from the type transition/member/change rule. */ 895 /* Use the type from the type transition/member/change rule. */
881 switch (specified) { 896 newcontext.type = avdatum->data;
882 case AVTAB_TRANSITION:
883 newcontext.type = avtab_transition(avdatum);
884 break;
885 case AVTAB_MEMBER:
886 newcontext.type = avtab_member(avdatum);
887 break;
888 case AVTAB_CHANGE:
889 newcontext.type = avtab_change(avdatum);
890 break;
891 }
892 } 897 }
893 898
894 /* Check for class-specific changes. */ 899 /* Check for class-specific changes. */
@@ -1502,6 +1507,7 @@ int security_get_user_sids(u32 fromsid,
1502 struct user_datum *user; 1507 struct user_datum *user;
1503 struct role_datum *role; 1508 struct role_datum *role;
1504 struct av_decision avd; 1509 struct av_decision avd;
1510 struct ebitmap_node *rnode, *tnode;
1505 int rc = 0, i, j; 1511 int rc = 0, i, j;
1506 1512
1507 if (!ss_initialized) { 1513 if (!ss_initialized) {
@@ -1532,13 +1538,13 @@ int security_get_user_sids(u32 fromsid,
1532 } 1538 }
1533 memset(mysids, 0, maxnel*sizeof(*mysids)); 1539 memset(mysids, 0, maxnel*sizeof(*mysids));
1534 1540
1535 for (i = ebitmap_startbit(&user->roles); i < ebitmap_length(&user->roles); i++) { 1541 ebitmap_for_each_bit(&user->roles, rnode, i) {
1536 if (!ebitmap_get_bit(&user->roles, i)) 1542 if (!ebitmap_node_get_bit(rnode, i))
1537 continue; 1543 continue;
1538 role = policydb.role_val_to_struct[i]; 1544 role = policydb.role_val_to_struct[i];
1539 usercon.role = i+1; 1545 usercon.role = i+1;
1540 for (j = ebitmap_startbit(&role->types); j < ebitmap_length(&role->types); j++) { 1546 ebitmap_for_each_bit(&role->types, tnode, j) {
1541 if (!ebitmap_get_bit(&role->types, j)) 1547 if (!ebitmap_node_get_bit(tnode, j))
1542 continue; 1548 continue;
1543 usercon.type = j+1; 1549 usercon.type = j+1;
1544 1550