aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss')
-rw-r--r--security/selinux/ss/Makefile9
-rw-r--r--security/selinux/ss/avtab.c46
-rw-r--r--security/selinux/ss/avtab.h26
-rw-r--r--security/selinux/ss/conditional.c131
-rw-r--r--security/selinux/ss/conditional.h2
-rw-r--r--security/selinux/ss/ebitmap.c81
-rw-r--r--security/selinux/ss/ebitmap.h2
-rw-r--r--security/selinux/ss/mls.c30
-rw-r--r--security/selinux/ss/mls.h3
-rw-r--r--security/selinux/ss/policydb.c1817
-rw-r--r--security/selinux/ss/policydb.h59
-rw-r--r--security/selinux/ss/services.c596
-rw-r--r--security/selinux/ss/sidtab.c39
-rw-r--r--security/selinux/ss/sidtab.h2
-rw-r--r--security/selinux/ss/status.c126
15 files changed, 2291 insertions, 678 deletions
diff --git a/security/selinux/ss/Makefile b/security/selinux/ss/Makefile
deleted file mode 100644
index 15d4e62917de..000000000000
--- a/security/selinux/ss/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
1#
2# Makefile for building the SELinux security server as part of the kernel tree.
3#
4
5EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
6obj-y := ss.o
7
8ss-y := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o
9
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index 929480c6c430..a3dd9faa19c0 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -266,8 +266,8 @@ int avtab_alloc(struct avtab *h, u32 nrules)
266 if (shift > 2) 266 if (shift > 2)
267 shift = shift - 2; 267 shift = shift - 2;
268 nslot = 1 << shift; 268 nslot = 1 << shift;
269 if (nslot > MAX_AVTAB_SIZE) 269 if (nslot > MAX_AVTAB_HASH_BUCKETS)
270 nslot = MAX_AVTAB_SIZE; 270 nslot = MAX_AVTAB_HASH_BUCKETS;
271 mask = nslot - 1; 271 mask = nslot - 1;
272 272
273 h->htable = kcalloc(nslot, sizeof(*(h->htable)), GFP_KERNEL); 273 h->htable = kcalloc(nslot, sizeof(*(h->htable)), GFP_KERNEL);
@@ -501,6 +501,48 @@ bad:
501 goto out; 501 goto out;
502} 502}
503 503
504int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp)
505{
506 __le16 buf16[4];
507 __le32 buf32[1];
508 int rc;
509
510 buf16[0] = cpu_to_le16(cur->key.source_type);
511 buf16[1] = cpu_to_le16(cur->key.target_type);
512 buf16[2] = cpu_to_le16(cur->key.target_class);
513 buf16[3] = cpu_to_le16(cur->key.specified);
514 rc = put_entry(buf16, sizeof(u16), 4, fp);
515 if (rc)
516 return rc;
517 buf32[0] = cpu_to_le32(cur->datum.data);
518 rc = put_entry(buf32, sizeof(u32), 1, fp);
519 if (rc)
520 return rc;
521 return 0;
522}
523
524int avtab_write(struct policydb *p, struct avtab *a, void *fp)
525{
526 unsigned int i;
527 int rc = 0;
528 struct avtab_node *cur;
529 __le32 buf[1];
530
531 buf[0] = cpu_to_le32(a->nel);
532 rc = put_entry(buf, sizeof(u32), 1, fp);
533 if (rc)
534 return rc;
535
536 for (i = 0; i < a->nslot; i++) {
537 for (cur = a->htable[i]; cur; cur = cur->next) {
538 rc = avtab_write_item(p, cur, fp);
539 if (rc)
540 return rc;
541 }
542 }
543
544 return rc;
545}
504void avtab_cache_init(void) 546void avtab_cache_init(void)
505{ 547{
506 avtab_node_cachep = kmem_cache_create("avtab_node", 548 avtab_node_cachep = kmem_cache_create("avtab_node",
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index cd4f734e2749..63ce2f9e441d 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -14,7 +14,7 @@
14 * 14 *
15 * Copyright (C) 2003 Tresys Technology, LLC 15 * Copyright (C) 2003 Tresys Technology, LLC
16 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, version 2. 18 * the Free Software Foundation, version 2.
19 * 19 *
20 * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp> 20 * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp>
@@ -27,16 +27,16 @@ struct avtab_key {
27 u16 source_type; /* source type */ 27 u16 source_type; /* source type */
28 u16 target_type; /* target type */ 28 u16 target_type; /* target type */
29 u16 target_class; /* target object class */ 29 u16 target_class; /* target object class */
30#define AVTAB_ALLOWED 1 30#define AVTAB_ALLOWED 0x0001
31#define AVTAB_AUDITALLOW 2 31#define AVTAB_AUDITALLOW 0x0002
32#define AVTAB_AUDITDENY 4 32#define AVTAB_AUDITDENY 0x0004
33#define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY) 33#define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY)
34#define AVTAB_TRANSITION 16 34#define AVTAB_TRANSITION 0x0010
35#define AVTAB_MEMBER 32 35#define AVTAB_MEMBER 0x0020
36#define AVTAB_CHANGE 64 36#define AVTAB_CHANGE 0x0040
37#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) 37#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)
38#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */ 38#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */
39#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ 39#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */
40 u16 specified; /* what field is specified */ 40 u16 specified; /* what field is specified */
41}; 41};
42 42
@@ -71,6 +71,8 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
71 void *p); 71 void *p);
72 72
73int avtab_read(struct avtab *a, void *fp, struct policydb *pol); 73int avtab_read(struct avtab *a, void *fp, struct policydb *pol);
74int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp);
75int avtab_write(struct policydb *p, struct avtab *a, void *fp);
74 76
75struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, 77struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key,
76 struct avtab_datum *datum); 78 struct avtab_datum *datum);
@@ -84,8 +86,6 @@ void avtab_cache_destroy(void);
84 86
85#define MAX_AVTAB_HASH_BITS 11 87#define MAX_AVTAB_HASH_BITS 11
86#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) 88#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
87#define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1)
88#define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS
89 89
90#endif /* _SS_AVTAB_H_ */ 90#endif /* _SS_AVTAB_H_ */
91 91
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index c91e150c3087..a53373207fb4 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -178,7 +178,7 @@ int cond_init_bool_indexes(struct policydb *p)
178 p->bool_val_to_struct = (struct cond_bool_datum **) 178 p->bool_val_to_struct = (struct cond_bool_datum **)
179 kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum *), GFP_KERNEL); 179 kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum *), GFP_KERNEL);
180 if (!p->bool_val_to_struct) 180 if (!p->bool_val_to_struct)
181 return -1; 181 return -ENOMEM;
182 return 0; 182 return 0;
183} 183}
184 184
@@ -193,6 +193,7 @@ int cond_index_bool(void *key, void *datum, void *datap)
193{ 193{
194 struct policydb *p; 194 struct policydb *p;
195 struct cond_bool_datum *booldatum; 195 struct cond_bool_datum *booldatum;
196 struct flex_array *fa;
196 197
197 booldatum = datum; 198 booldatum = datum;
198 p = datap; 199 p = datap;
@@ -200,7 +201,10 @@ int cond_index_bool(void *key, void *datum, void *datap)
200 if (!booldatum->value || booldatum->value > p->p_bools.nprim) 201 if (!booldatum->value || booldatum->value > p->p_bools.nprim)
201 return -EINVAL; 202 return -EINVAL;
202 203
203 p->p_bool_val_to_name[booldatum->value - 1] = key; 204 fa = p->sym_val_to_name[SYM_BOOLS];
205 if (flex_array_put_ptr(fa, booldatum->value - 1, key,
206 GFP_KERNEL | __GFP_ZERO))
207 BUG();
204 p->bool_val_to_struct[booldatum->value - 1] = booldatum; 208 p->bool_val_to_struct[booldatum->value - 1] = booldatum;
205 209
206 return 0; 210 return 0;
@@ -490,6 +494,129 @@ err:
490 return rc; 494 return rc;
491} 495}
492 496
497int cond_write_bool(void *vkey, void *datum, void *ptr)
498{
499 char *key = vkey;
500 struct cond_bool_datum *booldatum = datum;
501 struct policy_data *pd = ptr;
502 void *fp = pd->fp;
503 __le32 buf[3];
504 u32 len;
505 int rc;
506
507 len = strlen(key);
508 buf[0] = cpu_to_le32(booldatum->value);
509 buf[1] = cpu_to_le32(booldatum->state);
510 buf[2] = cpu_to_le32(len);
511 rc = put_entry(buf, sizeof(u32), 3, fp);
512 if (rc)
513 return rc;
514 rc = put_entry(key, 1, len, fp);
515 if (rc)
516 return rc;
517 return 0;
518}
519
520/*
521 * cond_write_cond_av_list doesn't write out the av_list nodes.
522 * Instead it writes out the key/value pairs from the avtab. This
523 * is necessary because there is no way to uniquely identifying rules
524 * in the avtab so it is not possible to associate individual rules
525 * in the avtab with a conditional without saving them as part of
526 * the conditional. This means that the avtab with the conditional
527 * rules will not be saved but will be rebuilt on policy load.
528 */
529static int cond_write_av_list(struct policydb *p,
530 struct cond_av_list *list, struct policy_file *fp)
531{
532 __le32 buf[1];
533 struct cond_av_list *cur_list;
534 u32 len;
535 int rc;
536
537 len = 0;
538 for (cur_list = list; cur_list != NULL; cur_list = cur_list->next)
539 len++;
540
541 buf[0] = cpu_to_le32(len);
542 rc = put_entry(buf, sizeof(u32), 1, fp);
543 if (rc)
544 return rc;
545
546 if (len == 0)
547 return 0;
548
549 for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) {
550 rc = avtab_write_item(p, cur_list->node, fp);
551 if (rc)
552 return rc;
553 }
554
555 return 0;
556}
557
558int cond_write_node(struct policydb *p, struct cond_node *node,
559 struct policy_file *fp)
560{
561 struct cond_expr *cur_expr;
562 __le32 buf[2];
563 int rc;
564 u32 len = 0;
565
566 buf[0] = cpu_to_le32(node->cur_state);
567 rc = put_entry(buf, sizeof(u32), 1, fp);
568 if (rc)
569 return rc;
570
571 for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next)
572 len++;
573
574 buf[0] = cpu_to_le32(len);
575 rc = put_entry(buf, sizeof(u32), 1, fp);
576 if (rc)
577 return rc;
578
579 for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) {
580 buf[0] = cpu_to_le32(cur_expr->expr_type);
581 buf[1] = cpu_to_le32(cur_expr->bool);
582 rc = put_entry(buf, sizeof(u32), 2, fp);
583 if (rc)
584 return rc;
585 }
586
587 rc = cond_write_av_list(p, node->true_list, fp);
588 if (rc)
589 return rc;
590 rc = cond_write_av_list(p, node->false_list, fp);
591 if (rc)
592 return rc;
593
594 return 0;
595}
596
597int cond_write_list(struct policydb *p, struct cond_node *list, void *fp)
598{
599 struct cond_node *cur;
600 u32 len;
601 __le32 buf[1];
602 int rc;
603
604 len = 0;
605 for (cur = list; cur != NULL; cur = cur->next)
606 len++;
607 buf[0] = cpu_to_le32(len);
608 rc = put_entry(buf, sizeof(u32), 1, fp);
609 if (rc)
610 return rc;
611
612 for (cur = list; cur != NULL; cur = cur->next) {
613 rc = cond_write_node(p, cur, fp);
614 if (rc)
615 return rc;
616 }
617
618 return 0;
619}
493/* Determine whether additional permissions are granted by the conditional 620/* Determine whether additional permissions are granted by the conditional
494 * av table, and if so, add them to the result 621 * av table, and if so, add them to the result
495 */ 622 */
diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h
index 53ddb013ae57..3f209c635295 100644
--- a/security/selinux/ss/conditional.h
+++ b/security/selinux/ss/conditional.h
@@ -69,6 +69,8 @@ int cond_index_bool(void *key, void *datum, void *datap);
69 69
70int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp); 70int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp);
71int cond_read_list(struct policydb *p, void *fp); 71int cond_read_list(struct policydb *p, void *fp);
72int cond_write_bool(void *key, void *datum, void *ptr);
73int cond_write_list(struct policydb *p, struct cond_node *list, void *fp);
72 74
73void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decision *avd); 75void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decision *avd);
74 76
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 04b6145d767f..d42951fcbe87 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -22,6 +22,8 @@
22#include "ebitmap.h" 22#include "ebitmap.h"
23#include "policydb.h" 23#include "policydb.h"
24 24
25#define BITS_PER_U64 (sizeof(u64) * 8)
26
25int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2) 27int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2)
26{ 28{
27 struct ebitmap_node *n1, *n2; 29 struct ebitmap_node *n1, *n2;
@@ -363,10 +365,10 @@ int ebitmap_read(struct ebitmap *e, void *fp)
363 e->highbit = le32_to_cpu(buf[1]); 365 e->highbit = le32_to_cpu(buf[1]);
364 count = le32_to_cpu(buf[2]); 366 count = le32_to_cpu(buf[2]);
365 367
366 if (mapunit != sizeof(u64) * 8) { 368 if (mapunit != BITS_PER_U64) {
367 printk(KERN_ERR "SELinux: ebitmap: map size %u does not " 369 printk(KERN_ERR "SELinux: ebitmap: map size %u does not "
368 "match my size %Zd (high bit was %d)\n", 370 "match my size %Zd (high bit was %d)\n",
369 mapunit, sizeof(u64) * 8, e->highbit); 371 mapunit, BITS_PER_U64, e->highbit);
370 goto bad; 372 goto bad;
371 } 373 }
372 374
@@ -446,3 +448,78 @@ bad:
446 ebitmap_destroy(e); 448 ebitmap_destroy(e);
447 goto out; 449 goto out;
448} 450}
451
452int ebitmap_write(struct ebitmap *e, void *fp)
453{
454 struct ebitmap_node *n;
455 u32 count;
456 __le32 buf[3];
457 u64 map;
458 int bit, last_bit, last_startbit, rc;
459
460 buf[0] = cpu_to_le32(BITS_PER_U64);
461
462 count = 0;
463 last_bit = 0;
464 last_startbit = -1;
465 ebitmap_for_each_positive_bit(e, n, bit) {
466 if (rounddown(bit, (int)BITS_PER_U64) > last_startbit) {
467 count++;
468 last_startbit = rounddown(bit, BITS_PER_U64);
469 }
470 last_bit = roundup(bit + 1, BITS_PER_U64);
471 }
472 buf[1] = cpu_to_le32(last_bit);
473 buf[2] = cpu_to_le32(count);
474
475 rc = put_entry(buf, sizeof(u32), 3, fp);
476 if (rc)
477 return rc;
478
479 map = 0;
480 last_startbit = INT_MIN;
481 ebitmap_for_each_positive_bit(e, n, bit) {
482 if (rounddown(bit, (int)BITS_PER_U64) > last_startbit) {
483 __le64 buf64[1];
484
485 /* this is the very first bit */
486 if (!map) {
487 last_startbit = rounddown(bit, BITS_PER_U64);
488 map = (u64)1 << (bit - last_startbit);
489 continue;
490 }
491
492 /* write the last node */
493 buf[0] = cpu_to_le32(last_startbit);
494 rc = put_entry(buf, sizeof(u32), 1, fp);
495 if (rc)
496 return rc;
497
498 buf64[0] = cpu_to_le64(map);
499 rc = put_entry(buf64, sizeof(u64), 1, fp);
500 if (rc)
501 return rc;
502
503 /* set up for the next node */
504 map = 0;
505 last_startbit = rounddown(bit, BITS_PER_U64);
506 }
507 map |= (u64)1 << (bit - last_startbit);
508 }
509 /* write the last node */
510 if (map) {
511 __le64 buf64[1];
512
513 /* write the last node */
514 buf[0] = cpu_to_le32(last_startbit);
515 rc = put_entry(buf, sizeof(u32), 1, fp);
516 if (rc)
517 return rc;
518
519 buf64[0] = cpu_to_le64(map);
520 rc = put_entry(buf64, sizeof(u64), 1, fp);
521 if (rc)
522 return rc;
523 }
524 return 0;
525}
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index f283b4367f54..922f8afa89dd 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -36,7 +36,6 @@ struct ebitmap {
36}; 36};
37 37
38#define ebitmap_length(e) ((e)->highbit) 38#define ebitmap_length(e) ((e)->highbit)
39#define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0)
40 39
41static inline unsigned int ebitmap_start_positive(struct ebitmap *e, 40static inline unsigned int ebitmap_start_positive(struct ebitmap *e,
42 struct ebitmap_node **n) 41 struct ebitmap_node **n)
@@ -123,6 +122,7 @@ int ebitmap_get_bit(struct ebitmap *e, unsigned long bit);
123int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value); 122int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value);
124void ebitmap_destroy(struct ebitmap *e); 123void ebitmap_destroy(struct ebitmap *e);
125int ebitmap_read(struct ebitmap *e, void *fp); 124int ebitmap_read(struct ebitmap *e, void *fp);
125int ebitmap_write(struct ebitmap *e, void *fp);
126 126
127#ifdef CONFIG_NETLABEL 127#ifdef CONFIG_NETLABEL
128int ebitmap_netlbl_export(struct ebitmap *ebmap, 128int ebitmap_netlbl_export(struct ebitmap *ebmap,
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index b4eff7a60c50..e96174216bc9 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -45,7 +45,7 @@ int mls_compute_context_len(struct context *context)
45 len = 1; /* for the beginning ":" */ 45 len = 1; /* for the beginning ":" */
46 for (l = 0; l < 2; l++) { 46 for (l = 0; l < 2; l++) {
47 int index_sens = context->range.level[l].sens; 47 int index_sens = context->range.level[l].sens;
48 len += strlen(policydb.p_sens_val_to_name[index_sens - 1]); 48 len += strlen(sym_name(&policydb, SYM_LEVELS, index_sens - 1));
49 49
50 /* categories */ 50 /* categories */
51 head = -2; 51 head = -2;
@@ -55,17 +55,17 @@ int mls_compute_context_len(struct context *context)
55 if (i - prev > 1) { 55 if (i - prev > 1) {
56 /* one or more negative bits are skipped */ 56 /* one or more negative bits are skipped */
57 if (head != prev) { 57 if (head != prev) {
58 nm = policydb.p_cat_val_to_name[prev]; 58 nm = sym_name(&policydb, SYM_CATS, prev);
59 len += strlen(nm) + 1; 59 len += strlen(nm) + 1;
60 } 60 }
61 nm = policydb.p_cat_val_to_name[i]; 61 nm = sym_name(&policydb, SYM_CATS, i);
62 len += strlen(nm) + 1; 62 len += strlen(nm) + 1;
63 head = i; 63 head = i;
64 } 64 }
65 prev = i; 65 prev = i;
66 } 66 }
67 if (prev != head) { 67 if (prev != head) {
68 nm = policydb.p_cat_val_to_name[prev]; 68 nm = sym_name(&policydb, SYM_CATS, prev);
69 len += strlen(nm) + 1; 69 len += strlen(nm) + 1;
70 } 70 }
71 if (l == 0) { 71 if (l == 0) {
@@ -102,8 +102,8 @@ void mls_sid_to_context(struct context *context,
102 scontextp++; 102 scontextp++;
103 103
104 for (l = 0; l < 2; l++) { 104 for (l = 0; l < 2; l++) {
105 strcpy(scontextp, 105 strcpy(scontextp, sym_name(&policydb, SYM_LEVELS,
106 policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); 106 context->range.level[l].sens - 1));
107 scontextp += strlen(scontextp); 107 scontextp += strlen(scontextp);
108 108
109 /* categories */ 109 /* categories */
@@ -118,7 +118,7 @@ void mls_sid_to_context(struct context *context,
118 *scontextp++ = '.'; 118 *scontextp++ = '.';
119 else 119 else
120 *scontextp++ = ','; 120 *scontextp++ = ',';
121 nm = policydb.p_cat_val_to_name[prev]; 121 nm = sym_name(&policydb, SYM_CATS, prev);
122 strcpy(scontextp, nm); 122 strcpy(scontextp, nm);
123 scontextp += strlen(nm); 123 scontextp += strlen(nm);
124 } 124 }
@@ -126,7 +126,7 @@ void mls_sid_to_context(struct context *context,
126 *scontextp++ = ':'; 126 *scontextp++ = ':';
127 else 127 else
128 *scontextp++ = ','; 128 *scontextp++ = ',';
129 nm = policydb.p_cat_val_to_name[i]; 129 nm = sym_name(&policydb, SYM_CATS, i);
130 strcpy(scontextp, nm); 130 strcpy(scontextp, nm);
131 scontextp += strlen(nm); 131 scontextp += strlen(nm);
132 head = i; 132 head = i;
@@ -139,7 +139,7 @@ void mls_sid_to_context(struct context *context,
139 *scontextp++ = '.'; 139 *scontextp++ = '.';
140 else 140 else
141 *scontextp++ = ','; 141 *scontextp++ = ',';
142 nm = policydb.p_cat_val_to_name[prev]; 142 nm = sym_name(&policydb, SYM_CATS, prev);
143 strcpy(scontextp, nm); 143 strcpy(scontextp, nm);
144 scontextp += strlen(nm); 144 scontextp += strlen(nm);
145 } 145 }
@@ -166,7 +166,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l)
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 = hashtab_search(p->p_levels.table,
169 p->p_sens_val_to_name[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
@@ -482,7 +482,8 @@ int mls_convert_context(struct policydb *oldp,
482 482
483 for (l = 0; l < 2; l++) { 483 for (l = 0; l < 2; l++) {
484 levdatum = hashtab_search(newp->p_levels.table, 484 levdatum = hashtab_search(newp->p_levels.table,
485 oldp->p_sens_val_to_name[c->range.level[l].sens - 1]); 485 sym_name(oldp, SYM_LEVELS,
486 c->range.level[l].sens - 1));
486 487
487 if (!levdatum) 488 if (!levdatum)
488 return -EINVAL; 489 return -EINVAL;
@@ -493,7 +494,7 @@ int mls_convert_context(struct policydb *oldp,
493 int rc; 494 int rc;
494 495
495 catdatum = hashtab_search(newp->p_cats.table, 496 catdatum = hashtab_search(newp->p_cats.table,
496 oldp->p_cat_val_to_name[i]); 497 sym_name(oldp, SYM_CATS, i));
497 if (!catdatum) 498 if (!catdatum)
498 return -EINVAL; 499 return -EINVAL;
499 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); 500 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
@@ -511,7 +512,8 @@ int mls_compute_sid(struct context *scontext,
511 struct context *tcontext, 512 struct context *tcontext,
512 u16 tclass, 513 u16 tclass,
513 u32 specified, 514 u32 specified,
514 struct context *newcontext) 515 struct context *newcontext,
516 bool sock)
515{ 517{
516 struct range_trans rtr; 518 struct range_trans rtr;
517 struct mls_range *r; 519 struct mls_range *r;
@@ -530,7 +532,7 @@ int mls_compute_sid(struct context *scontext,
530 return mls_range_set(newcontext, r); 532 return mls_range_set(newcontext, r);
531 /* Fallthrough */ 533 /* Fallthrough */
532 case AVTAB_CHANGE: 534 case AVTAB_CHANGE:
533 if (tclass == policydb.process_class) 535 if ((tclass == policydb.process_class) || (sock == true))
534 /* Use the process MLS attributes. */ 536 /* Use the process MLS attributes. */
535 return mls_context_cpy(newcontext, scontext); 537 return mls_context_cpy(newcontext, scontext);
536 else 538 else
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index cd9152632e54..037bf9d82d41 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -49,7 +49,8 @@ int mls_compute_sid(struct context *scontext,
49 struct context *tcontext, 49 struct context *tcontext,
50 u16 tclass, 50 u16 tclass,
51 u32 specified, 51 u32 specified,
52 struct context *newcontext); 52 struct context *newcontext,
53 bool sock);
53 54
54int mls_setup_user_range(struct context *fromcon, struct user_datum *user, 55int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
55 struct context *usercon); 56 struct context *usercon);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 3a29704be8ce..d246aca3f4fb 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -37,6 +37,7 @@
37#include "policydb.h" 37#include "policydb.h"
38#include "conditional.h" 38#include "conditional.h"
39#include "mls.h" 39#include "mls.h"
40#include "services.h"
40 41
41#define _DEBUG_HASHES 42#define _DEBUG_HASHES
42 43
@@ -122,6 +123,16 @@ static struct policydb_compat_info policydb_compat[] = {
122 .sym_num = SYM_NUM, 123 .sym_num = SYM_NUM,
123 .ocon_num = OCON_NUM, 124 .ocon_num = OCON_NUM,
124 }, 125 },
126 {
127 .version = POLICYDB_VERSION_FILENAME_TRANS,
128 .sym_num = SYM_NUM,
129 .ocon_num = OCON_NUM,
130 },
131 {
132 .version = POLICYDB_VERSION_ROLETRANS,
133 .sym_num = SYM_NUM,
134 .ocon_num = OCON_NUM,
135 },
125}; 136};
126 137
127static struct policydb_compat_info *policydb_lookup_compat(int version) 138static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -147,32 +158,67 @@ static int roles_init(struct policydb *p)
147 int rc; 158 int rc;
148 struct role_datum *role; 159 struct role_datum *role;
149 160
161 rc = -ENOMEM;
150 role = kzalloc(sizeof(*role), GFP_KERNEL); 162 role = kzalloc(sizeof(*role), GFP_KERNEL);
151 if (!role) { 163 if (!role)
152 rc = -ENOMEM;
153 goto out; 164 goto out;
154 } 165
166 rc = -EINVAL;
155 role->value = ++p->p_roles.nprim; 167 role->value = ++p->p_roles.nprim;
156 if (role->value != OBJECT_R_VAL) { 168 if (role->value != OBJECT_R_VAL)
157 rc = -EINVAL; 169 goto out;
158 goto out_free_role; 170
159 } 171 rc = -ENOMEM;
160 key = kstrdup(OBJECT_R, GFP_KERNEL); 172 key = kstrdup(OBJECT_R, GFP_KERNEL);
161 if (!key) { 173 if (!key)
162 rc = -ENOMEM; 174 goto out;
163 goto out_free_role; 175
164 }
165 rc = hashtab_insert(p->p_roles.table, key, role); 176 rc = hashtab_insert(p->p_roles.table, key, role);
166 if (rc) 177 if (rc)
167 goto out_free_key; 178 goto out;
168out:
169 return rc;
170 179
171out_free_key: 180 return 0;
181out:
172 kfree(key); 182 kfree(key);
173out_free_role:
174 kfree(role); 183 kfree(role);
175 goto out; 184 return rc;
185}
186
187static u32 filenametr_hash(struct hashtab *h, const void *k)
188{
189 const struct filename_trans *ft = k;
190 unsigned long hash;
191 unsigned int byte_num;
192 unsigned char focus;
193
194 hash = ft->stype ^ ft->ttype ^ ft->tclass;
195
196 byte_num = 0;
197 while ((focus = ft->name[byte_num++]))
198 hash = partial_name_hash(focus, hash);
199 return hash & (h->size - 1);
200}
201
202static int filenametr_cmp(struct hashtab *h, const void *k1, const void *k2)
203{
204 const struct filename_trans *ft1 = k1;
205 const struct filename_trans *ft2 = k2;
206 int v;
207
208 v = ft1->stype - ft2->stype;
209 if (v)
210 return v;
211
212 v = ft1->ttype - ft2->ttype;
213 if (v)
214 return v;
215
216 v = ft1->tclass - ft2->tclass;
217 if (v)
218 return v;
219
220 return strcmp(ft1->name, ft2->name);
221
176} 222}
177 223
178static u32 rangetr_hash(struct hashtab *h, const void *k) 224static u32 rangetr_hash(struct hashtab *h, const void *k)
@@ -185,9 +231,19 @@ static u32 rangetr_hash(struct hashtab *h, const void *k)
185static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2) 231static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2)
186{ 232{
187 const struct range_trans *key1 = k1, *key2 = k2; 233 const struct range_trans *key1 = k1, *key2 = k2;
188 return (key1->source_type != key2->source_type || 234 int v;
189 key1->target_type != key2->target_type || 235
190 key1->target_class != key2->target_class); 236 v = key1->source_type - key2->source_type;
237 if (v)
238 return v;
239
240 v = key1->target_type - key2->target_type;
241 if (v)
242 return v;
243
244 v = key1->target_class - key2->target_class;
245
246 return v;
191} 247}
192 248
193/* 249/*
@@ -202,35 +258,40 @@ static int policydb_init(struct policydb *p)
202 for (i = 0; i < SYM_NUM; i++) { 258 for (i = 0; i < SYM_NUM; i++) {
203 rc = symtab_init(&p->symtab[i], symtab_sizes[i]); 259 rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
204 if (rc) 260 if (rc)
205 goto out_free_symtab; 261 goto out;
206 } 262 }
207 263
208 rc = avtab_init(&p->te_avtab); 264 rc = avtab_init(&p->te_avtab);
209 if (rc) 265 if (rc)
210 goto out_free_symtab; 266 goto out;
211 267
212 rc = roles_init(p); 268 rc = roles_init(p);
213 if (rc) 269 if (rc)
214 goto out_free_symtab; 270 goto out;
215 271
216 rc = cond_policydb_init(p); 272 rc = cond_policydb_init(p);
217 if (rc) 273 if (rc)
218 goto out_free_symtab; 274 goto out;
275
276 p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10));
277 if (!p->filename_trans)
278 goto out;
219 279
220 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); 280 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
221 if (!p->range_tr) 281 if (!p->range_tr)
222 goto out_free_symtab; 282 goto out;
223 283
284 ebitmap_init(&p->filename_trans_ttypes);
224 ebitmap_init(&p->policycaps); 285 ebitmap_init(&p->policycaps);
225 ebitmap_init(&p->permissive_map); 286 ebitmap_init(&p->permissive_map);
226 287
288 return 0;
227out: 289out:
228 return rc; 290 hashtab_destroy(p->filename_trans);
229 291 hashtab_destroy(p->range_tr);
230out_free_symtab:
231 for (i = 0; i < SYM_NUM; i++) 292 for (i = 0; i < SYM_NUM; i++)
232 hashtab_destroy(p->symtab[i].table); 293 hashtab_destroy(p->symtab[i].table);
233 goto out; 294 return rc;
234} 295}
235 296
236/* 297/*
@@ -247,12 +308,17 @@ static int common_index(void *key, void *datum, void *datap)
247{ 308{
248 struct policydb *p; 309 struct policydb *p;
249 struct common_datum *comdatum; 310 struct common_datum *comdatum;
311 struct flex_array *fa;
250 312
251 comdatum = datum; 313 comdatum = datum;
252 p = datap; 314 p = datap;
253 if (!comdatum->value || comdatum->value > p->p_commons.nprim) 315 if (!comdatum->value || comdatum->value > p->p_commons.nprim)
254 return -EINVAL; 316 return -EINVAL;
255 p->p_common_val_to_name[comdatum->value - 1] = key; 317
318 fa = p->sym_val_to_name[SYM_COMMONS];
319 if (flex_array_put_ptr(fa, comdatum->value - 1, key,
320 GFP_KERNEL | __GFP_ZERO))
321 BUG();
256 return 0; 322 return 0;
257} 323}
258 324
@@ -260,12 +326,16 @@ static int class_index(void *key, void *datum, void *datap)
260{ 326{
261 struct policydb *p; 327 struct policydb *p;
262 struct class_datum *cladatum; 328 struct class_datum *cladatum;
329 struct flex_array *fa;
263 330
264 cladatum = datum; 331 cladatum = datum;
265 p = datap; 332 p = datap;
266 if (!cladatum->value || cladatum->value > p->p_classes.nprim) 333 if (!cladatum->value || cladatum->value > p->p_classes.nprim)
267 return -EINVAL; 334 return -EINVAL;
268 p->p_class_val_to_name[cladatum->value - 1] = key; 335 fa = p->sym_val_to_name[SYM_CLASSES];
336 if (flex_array_put_ptr(fa, cladatum->value - 1, key,
337 GFP_KERNEL | __GFP_ZERO))
338 BUG();
269 p->class_val_to_struct[cladatum->value - 1] = cladatum; 339 p->class_val_to_struct[cladatum->value - 1] = cladatum;
270 return 0; 340 return 0;
271} 341}
@@ -274,6 +344,7 @@ static int role_index(void *key, void *datum, void *datap)
274{ 344{
275 struct policydb *p; 345 struct policydb *p;
276 struct role_datum *role; 346 struct role_datum *role;
347 struct flex_array *fa;
277 348
278 role = datum; 349 role = datum;
279 p = datap; 350 p = datap;
@@ -281,7 +352,11 @@ static int role_index(void *key, void *datum, void *datap)
281 || role->value > p->p_roles.nprim 352 || role->value > p->p_roles.nprim
282 || role->bounds > p->p_roles.nprim) 353 || role->bounds > p->p_roles.nprim)
283 return -EINVAL; 354 return -EINVAL;
284 p->p_role_val_to_name[role->value - 1] = key; 355
356 fa = p->sym_val_to_name[SYM_ROLES];
357 if (flex_array_put_ptr(fa, role->value - 1, key,
358 GFP_KERNEL | __GFP_ZERO))
359 BUG();
285 p->role_val_to_struct[role->value - 1] = role; 360 p->role_val_to_struct[role->value - 1] = role;
286 return 0; 361 return 0;
287} 362}
@@ -290,6 +365,7 @@ static int type_index(void *key, void *datum, void *datap)
290{ 365{
291 struct policydb *p; 366 struct policydb *p;
292 struct type_datum *typdatum; 367 struct type_datum *typdatum;
368 struct flex_array *fa;
293 369
294 typdatum = datum; 370 typdatum = datum;
295 p = datap; 371 p = datap;
@@ -299,8 +375,15 @@ static int type_index(void *key, void *datum, void *datap)
299 || typdatum->value > p->p_types.nprim 375 || typdatum->value > p->p_types.nprim
300 || typdatum->bounds > p->p_types.nprim) 376 || typdatum->bounds > p->p_types.nprim)
301 return -EINVAL; 377 return -EINVAL;
302 p->p_type_val_to_name[typdatum->value - 1] = key; 378 fa = p->sym_val_to_name[SYM_TYPES];
303 p->type_val_to_struct[typdatum->value - 1] = typdatum; 379 if (flex_array_put_ptr(fa, typdatum->value - 1, key,
380 GFP_KERNEL | __GFP_ZERO))
381 BUG();
382
383 fa = p->type_val_to_struct_array;
384 if (flex_array_put_ptr(fa, typdatum->value - 1, typdatum,
385 GFP_KERNEL | __GFP_ZERO))
386 BUG();
304 } 387 }
305 388
306 return 0; 389 return 0;
@@ -310,6 +393,7 @@ static int user_index(void *key, void *datum, void *datap)
310{ 393{
311 struct policydb *p; 394 struct policydb *p;
312 struct user_datum *usrdatum; 395 struct user_datum *usrdatum;
396 struct flex_array *fa;
313 397
314 usrdatum = datum; 398 usrdatum = datum;
315 p = datap; 399 p = datap;
@@ -317,7 +401,11 @@ static int user_index(void *key, void *datum, void *datap)
317 || usrdatum->value > p->p_users.nprim 401 || usrdatum->value > p->p_users.nprim
318 || usrdatum->bounds > p->p_users.nprim) 402 || usrdatum->bounds > p->p_users.nprim)
319 return -EINVAL; 403 return -EINVAL;
320 p->p_user_val_to_name[usrdatum->value - 1] = key; 404
405 fa = p->sym_val_to_name[SYM_USERS];
406 if (flex_array_put_ptr(fa, usrdatum->value - 1, key,
407 GFP_KERNEL | __GFP_ZERO))
408 BUG();
321 p->user_val_to_struct[usrdatum->value - 1] = usrdatum; 409 p->user_val_to_struct[usrdatum->value - 1] = usrdatum;
322 return 0; 410 return 0;
323} 411}
@@ -326,6 +414,7 @@ static int sens_index(void *key, void *datum, void *datap)
326{ 414{
327 struct policydb *p; 415 struct policydb *p;
328 struct level_datum *levdatum; 416 struct level_datum *levdatum;
417 struct flex_array *fa;
329 418
330 levdatum = datum; 419 levdatum = datum;
331 p = datap; 420 p = datap;
@@ -334,7 +423,10 @@ static int sens_index(void *key, void *datum, void *datap)
334 if (!levdatum->level->sens || 423 if (!levdatum->level->sens ||
335 levdatum->level->sens > p->p_levels.nprim) 424 levdatum->level->sens > p->p_levels.nprim)
336 return -EINVAL; 425 return -EINVAL;
337 p->p_sens_val_to_name[levdatum->level->sens - 1] = key; 426 fa = p->sym_val_to_name[SYM_LEVELS];
427 if (flex_array_put_ptr(fa, levdatum->level->sens - 1, key,
428 GFP_KERNEL | __GFP_ZERO))
429 BUG();
338 } 430 }
339 431
340 return 0; 432 return 0;
@@ -344,6 +436,7 @@ static int cat_index(void *key, void *datum, void *datap)
344{ 436{
345 struct policydb *p; 437 struct policydb *p;
346 struct cat_datum *catdatum; 438 struct cat_datum *catdatum;
439 struct flex_array *fa;
347 440
348 catdatum = datum; 441 catdatum = datum;
349 p = datap; 442 p = datap;
@@ -351,7 +444,10 @@ static int cat_index(void *key, void *datum, void *datap)
351 if (!catdatum->isalias) { 444 if (!catdatum->isalias) {
352 if (!catdatum->value || catdatum->value > p->p_cats.nprim) 445 if (!catdatum->value || catdatum->value > p->p_cats.nprim)
353 return -EINVAL; 446 return -EINVAL;
354 p->p_cat_val_to_name[catdatum->value - 1] = key; 447 fa = p->sym_val_to_name[SYM_CATS];
448 if (flex_array_put_ptr(fa, catdatum->value - 1, key,
449 GFP_KERNEL | __GFP_ZERO))
450 BUG();
355 } 451 }
356 452
357 return 0; 453 return 0;
@@ -369,74 +465,27 @@ static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) =
369 cat_index, 465 cat_index,
370}; 466};
371 467
372/* 468#ifdef DEBUG_HASHES
373 * Define the common val_to_name array and the class 469static void hash_eval(struct hashtab *h, const char *hash_name)
374 * val_to_name and val_to_struct arrays in a policy
375 * database structure.
376 *
377 * Caller must clean up upon failure.
378 */
379static int policydb_index_classes(struct policydb *p)
380{ 470{
381 int rc; 471 struct hashtab_info info;
382
383 p->p_common_val_to_name =
384 kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL);
385 if (!p->p_common_val_to_name) {
386 rc = -ENOMEM;
387 goto out;
388 }
389
390 rc = hashtab_map(p->p_commons.table, common_index, p);
391 if (rc)
392 goto out;
393
394 p->class_val_to_struct =
395 kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), GFP_KERNEL);
396 if (!p->class_val_to_struct) {
397 rc = -ENOMEM;
398 goto out;
399 }
400
401 p->p_class_val_to_name =
402 kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL);
403 if (!p->p_class_val_to_name) {
404 rc = -ENOMEM;
405 goto out;
406 }
407 472
408 rc = hashtab_map(p->p_classes.table, class_index, p); 473 hashtab_stat(h, &info);
409out: 474 printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, "
410 return rc; 475 "longest chain length %d\n", hash_name, h->nel,
476 info.slots_used, h->size, info.max_chain_len);
411} 477}
412 478
413#ifdef DEBUG_HASHES
414static void symtab_hash_eval(struct symtab *s) 479static void symtab_hash_eval(struct symtab *s)
415{ 480{
416 int i; 481 int i;
417 482
418 for (i = 0; i < SYM_NUM; i++) { 483 for (i = 0; i < SYM_NUM; i++)
419 struct hashtab *h = s[i].table; 484 hash_eval(s[i].table, symtab_name[i]);
420 struct hashtab_info info;
421
422 hashtab_stat(h, &info);
423 printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, "
424 "longest chain length %d\n", symtab_name[i], h->nel,
425 info.slots_used, h->size, info.max_chain_len);
426 }
427} 485}
428 486
429static void rangetr_hash_eval(struct hashtab *h)
430{
431 struct hashtab_info info;
432
433 hashtab_stat(h, &info);
434 printk(KERN_DEBUG "SELinux: rangetr: %d entries and %d/%d buckets used, "
435 "longest chain length %d\n", h->nel,
436 info.slots_used, h->size, info.max_chain_len);
437}
438#else 487#else
439static inline void rangetr_hash_eval(struct hashtab *h) 488static inline void hash_eval(struct hashtab *h, char *hash_name)
440{ 489{
441} 490}
442#endif 491#endif
@@ -447,9 +496,9 @@ static inline void rangetr_hash_eval(struct hashtab *h)
447 * 496 *
448 * Caller must clean up on failure. 497 * Caller must clean up on failure.
449 */ 498 */
450static int policydb_index_others(struct policydb *p) 499static int policydb_index(struct policydb *p)
451{ 500{
452 int i, rc = 0; 501 int i, rc;
453 502
454 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", 503 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools",
455 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); 504 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
@@ -466,47 +515,63 @@ static int policydb_index_others(struct policydb *p)
466 symtab_hash_eval(p->symtab); 515 symtab_hash_eval(p->symtab);
467#endif 516#endif
468 517
518 rc = -ENOMEM;
519 p->class_val_to_struct =
520 kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)),
521 GFP_KERNEL);
522 if (!p->class_val_to_struct)
523 goto out;
524
525 rc = -ENOMEM;
469 p->role_val_to_struct = 526 p->role_val_to_struct =
470 kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)), 527 kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),
471 GFP_KERNEL); 528 GFP_KERNEL);
472 if (!p->role_val_to_struct) { 529 if (!p->role_val_to_struct)
473 rc = -ENOMEM;
474 goto out; 530 goto out;
475 }
476 531
532 rc = -ENOMEM;
477 p->user_val_to_struct = 533 p->user_val_to_struct =
478 kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)), 534 kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),
479 GFP_KERNEL); 535 GFP_KERNEL);
480 if (!p->user_val_to_struct) { 536 if (!p->user_val_to_struct)
481 rc = -ENOMEM;
482 goto out; 537 goto out;
483 }
484 538
485 p->type_val_to_struct = 539 /* Yes, I want the sizeof the pointer, not the structure */
486 kmalloc(p->p_types.nprim * sizeof(*(p->type_val_to_struct)), 540 rc = -ENOMEM;
487 GFP_KERNEL); 541 p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *),
488 if (!p->type_val_to_struct) { 542 p->p_types.nprim,
489 rc = -ENOMEM; 543 GFP_KERNEL | __GFP_ZERO);
544 if (!p->type_val_to_struct_array)
490 goto out; 545 goto out;
491 }
492 546
493 if (cond_init_bool_indexes(p)) { 547 rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
494 rc = -ENOMEM; 548 p->p_types.nprim, GFP_KERNEL | __GFP_ZERO);
549 if (rc)
495 goto out; 550 goto out;
496 }
497 551
498 for (i = SYM_ROLES; i < SYM_NUM; i++) { 552 rc = cond_init_bool_indexes(p);
499 p->sym_val_to_name[i] = 553 if (rc)
500 kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL); 554 goto out;
501 if (!p->sym_val_to_name[i]) { 555
502 rc = -ENOMEM; 556 for (i = 0; i < SYM_NUM; i++) {
557 rc = -ENOMEM;
558 p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *),
559 p->symtab[i].nprim,
560 GFP_KERNEL | __GFP_ZERO);
561 if (!p->sym_val_to_name[i])
503 goto out; 562 goto out;
504 } 563
564 rc = flex_array_prealloc(p->sym_val_to_name[i],
565 0, p->symtab[i].nprim,
566 GFP_KERNEL | __GFP_ZERO);
567 if (rc)
568 goto out;
569
505 rc = hashtab_map(p->symtab[i].table, index_f[i], p); 570 rc = hashtab_map(p->symtab[i].table, index_f[i], p);
506 if (rc) 571 if (rc)
507 goto out; 572 goto out;
508 } 573 }
509 574 rc = 0;
510out: 575out:
511 return rc; 576 return rc;
512} 577}
@@ -529,9 +594,11 @@ static int common_destroy(void *key, void *datum, void *p)
529 struct common_datum *comdatum; 594 struct common_datum *comdatum;
530 595
531 kfree(key); 596 kfree(key);
532 comdatum = datum; 597 if (datum) {
533 hashtab_map(comdatum->permissions.table, perm_destroy, NULL); 598 comdatum = datum;
534 hashtab_destroy(comdatum->permissions.table); 599 hashtab_map(comdatum->permissions.table, perm_destroy, NULL);
600 hashtab_destroy(comdatum->permissions.table);
601 }
535 kfree(datum); 602 kfree(datum);
536 return 0; 603 return 0;
537} 604}
@@ -543,38 +610,40 @@ static int cls_destroy(void *key, void *datum, void *p)
543 struct constraint_expr *e, *etmp; 610 struct constraint_expr *e, *etmp;
544 611
545 kfree(key); 612 kfree(key);
546 cladatum = datum; 613 if (datum) {
547 hashtab_map(cladatum->permissions.table, perm_destroy, NULL); 614 cladatum = datum;
548 hashtab_destroy(cladatum->permissions.table); 615 hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
549 constraint = cladatum->constraints; 616 hashtab_destroy(cladatum->permissions.table);
550 while (constraint) { 617 constraint = cladatum->constraints;
551 e = constraint->expr; 618 while (constraint) {
552 while (e) { 619 e = constraint->expr;
553 ebitmap_destroy(&e->names); 620 while (e) {
554 etmp = e; 621 ebitmap_destroy(&e->names);
555 e = e->next; 622 etmp = e;
556 kfree(etmp); 623 e = e->next;
624 kfree(etmp);
625 }
626 ctemp = constraint;
627 constraint = constraint->next;
628 kfree(ctemp);
557 } 629 }
558 ctemp = constraint; 630
559 constraint = constraint->next; 631 constraint = cladatum->validatetrans;
560 kfree(ctemp); 632 while (constraint) {
561 } 633 e = constraint->expr;
562 634 while (e) {
563 constraint = cladatum->validatetrans; 635 ebitmap_destroy(&e->names);
564 while (constraint) { 636 etmp = e;
565 e = constraint->expr; 637 e = e->next;
566 while (e) { 638 kfree(etmp);
567 ebitmap_destroy(&e->names); 639 }
568 etmp = e; 640 ctemp = constraint;
569 e = e->next; 641 constraint = constraint->next;
570 kfree(etmp); 642 kfree(ctemp);
571 } 643 }
572 ctemp = constraint;
573 constraint = constraint->next;
574 kfree(ctemp);
575 }
576 644
577 kfree(cladatum->comkey); 645 kfree(cladatum->comkey);
646 }
578 kfree(datum); 647 kfree(datum);
579 return 0; 648 return 0;
580} 649}
@@ -584,9 +653,11 @@ static int role_destroy(void *key, void *datum, void *p)
584 struct role_datum *role; 653 struct role_datum *role;
585 654
586 kfree(key); 655 kfree(key);
587 role = datum; 656 if (datum) {
588 ebitmap_destroy(&role->dominates); 657 role = datum;
589 ebitmap_destroy(&role->types); 658 ebitmap_destroy(&role->dominates);
659 ebitmap_destroy(&role->types);
660 }
590 kfree(datum); 661 kfree(datum);
591 return 0; 662 return 0;
592} 663}
@@ -603,11 +674,13 @@ static int user_destroy(void *key, void *datum, void *p)
603 struct user_datum *usrdatum; 674 struct user_datum *usrdatum;
604 675
605 kfree(key); 676 kfree(key);
606 usrdatum = datum; 677 if (datum) {
607 ebitmap_destroy(&usrdatum->roles); 678 usrdatum = datum;
608 ebitmap_destroy(&usrdatum->range.level[0].cat); 679 ebitmap_destroy(&usrdatum->roles);
609 ebitmap_destroy(&usrdatum->range.level[1].cat); 680 ebitmap_destroy(&usrdatum->range.level[0].cat);
610 ebitmap_destroy(&usrdatum->dfltlevel.cat); 681 ebitmap_destroy(&usrdatum->range.level[1].cat);
682 ebitmap_destroy(&usrdatum->dfltlevel.cat);
683 }
611 kfree(datum); 684 kfree(datum);
612 return 0; 685 return 0;
613} 686}
@@ -617,9 +690,11 @@ static int sens_destroy(void *key, void *datum, void *p)
617 struct level_datum *levdatum; 690 struct level_datum *levdatum;
618 691
619 kfree(key); 692 kfree(key);
620 levdatum = datum; 693 if (datum) {
621 ebitmap_destroy(&levdatum->level->cat); 694 levdatum = datum;
622 kfree(levdatum->level); 695 ebitmap_destroy(&levdatum->level->cat);
696 kfree(levdatum->level);
697 }
623 kfree(datum); 698 kfree(datum);
624 return 0; 699 return 0;
625} 700}
@@ -643,6 +718,16 @@ static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) =
643 cat_destroy, 718 cat_destroy,
644}; 719};
645 720
721static int filenametr_destroy(void *key, void *datum, void *p)
722{
723 struct filename_trans *ft = key;
724 kfree(ft->name);
725 kfree(key);
726 kfree(datum);
727 cond_resched();
728 return 0;
729}
730
646static int range_tr_destroy(void *key, void *datum, void *p) 731static int range_tr_destroy(void *key, void *datum, void *p)
647{ 732{
648 struct mls_range *rt = datum; 733 struct mls_range *rt = datum;
@@ -684,13 +769,16 @@ void policydb_destroy(struct policydb *p)
684 hashtab_destroy(p->symtab[i].table); 769 hashtab_destroy(p->symtab[i].table);
685 } 770 }
686 771
687 for (i = 0; i < SYM_NUM; i++) 772 for (i = 0; i < SYM_NUM; i++) {
688 kfree(p->sym_val_to_name[i]); 773 if (p->sym_val_to_name[i])
774 flex_array_free(p->sym_val_to_name[i]);
775 }
689 776
690 kfree(p->class_val_to_struct); 777 kfree(p->class_val_to_struct);
691 kfree(p->role_val_to_struct); 778 kfree(p->role_val_to_struct);
692 kfree(p->user_val_to_struct); 779 kfree(p->user_val_to_struct);
693 kfree(p->type_val_to_struct); 780 if (p->type_val_to_struct_array)
781 flex_array_free(p->type_val_to_struct_array);
694 782
695 avtab_destroy(&p->te_avtab); 783 avtab_destroy(&p->te_avtab);
696 784
@@ -737,6 +825,9 @@ void policydb_destroy(struct policydb *p)
737 } 825 }
738 kfree(lra); 826 kfree(lra);
739 827
828 hashtab_map(p->filename_trans, filenametr_destroy, NULL);
829 hashtab_destroy(p->filename_trans);
830
740 hashtab_map(p->range_tr, range_tr_destroy, NULL); 831 hashtab_map(p->range_tr, range_tr_destroy, NULL);
741 hashtab_destroy(p->range_tr); 832 hashtab_destroy(p->range_tr);
742 833
@@ -751,6 +842,8 @@ void policydb_destroy(struct policydb *p)
751 } 842 }
752 flex_array_free(p->type_attr_map_array); 843 flex_array_free(p->type_attr_map_array);
753 } 844 }
845
846 ebitmap_destroy(&p->filename_trans_ttypes);
754 ebitmap_destroy(&p->policycaps); 847 ebitmap_destroy(&p->policycaps);
755 ebitmap_destroy(&p->permissive_map); 848 ebitmap_destroy(&p->permissive_map);
756 849
@@ -774,19 +867,21 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
774 867
775 head = p->ocontexts[OCON_ISID]; 868 head = p->ocontexts[OCON_ISID];
776 for (c = head; c; c = c->next) { 869 for (c = head; c; c = c->next) {
870 rc = -EINVAL;
777 if (!c->context[0].user) { 871 if (!c->context[0].user) {
778 printk(KERN_ERR "SELinux: SID %s was never " 872 printk(KERN_ERR "SELinux: SID %s was never defined.\n",
779 "defined.\n", c->u.name); 873 c->u.name);
780 rc = -EINVAL;
781 goto out; 874 goto out;
782 } 875 }
783 if (sidtab_insert(s, c->sid[0], &c->context[0])) { 876
784 printk(KERN_ERR "SELinux: unable to load initial " 877 rc = sidtab_insert(s, c->sid[0], &c->context[0]);
785 "SID %s.\n", c->u.name); 878 if (rc) {
786 rc = -EINVAL; 879 printk(KERN_ERR "SELinux: unable to load initial SID %s.\n",
880 c->u.name);
787 goto out; 881 goto out;
788 } 882 }
789 } 883 }
884 rc = 0;
790out: 885out:
791 return rc; 886 return rc;
792} 887}
@@ -835,8 +930,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
835 * Role must be authorized for the type. 930 * Role must be authorized for the type.
836 */ 931 */
837 role = p->role_val_to_struct[c->role - 1]; 932 role = p->role_val_to_struct[c->role - 1];
838 if (!ebitmap_get_bit(&role->types, 933 if (!ebitmap_get_bit(&role->types, c->type - 1))
839 c->type - 1))
840 /* role may not be associated with type */ 934 /* role may not be associated with type */
841 return 0; 935 return 0;
842 936
@@ -847,8 +941,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
847 if (!usrdatum) 941 if (!usrdatum)
848 return 0; 942 return 0;
849 943
850 if (!ebitmap_get_bit(&usrdatum->roles, 944 if (!ebitmap_get_bit(&usrdatum->roles, c->role - 1))
851 c->role - 1))
852 /* user may not be associated with role */ 945 /* user may not be associated with role */
853 return 0; 946 return 0;
854 } 947 }
@@ -870,20 +963,22 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
870 int rc; 963 int rc;
871 964
872 rc = next_entry(buf, fp, sizeof(u32)); 965 rc = next_entry(buf, fp, sizeof(u32));
873 if (rc < 0) 966 if (rc)
874 goto out; 967 goto out;
875 968
969 rc = -EINVAL;
876 items = le32_to_cpu(buf[0]); 970 items = le32_to_cpu(buf[0]);
877 if (items > ARRAY_SIZE(buf)) { 971 if (items > ARRAY_SIZE(buf)) {
878 printk(KERN_ERR "SELinux: mls: range overflow\n"); 972 printk(KERN_ERR "SELinux: mls: range overflow\n");
879 rc = -EINVAL;
880 goto out; 973 goto out;
881 } 974 }
975
882 rc = next_entry(buf, fp, sizeof(u32) * items); 976 rc = next_entry(buf, fp, sizeof(u32) * items);
883 if (rc < 0) { 977 if (rc) {
884 printk(KERN_ERR "SELinux: mls: truncated range\n"); 978 printk(KERN_ERR "SELinux: mls: truncated range\n");
885 goto out; 979 goto out;
886 } 980 }
981
887 r->level[0].sens = le32_to_cpu(buf[0]); 982 r->level[0].sens = le32_to_cpu(buf[0]);
888 if (items > 1) 983 if (items > 1)
889 r->level[1].sens = le32_to_cpu(buf[1]); 984 r->level[1].sens = le32_to_cpu(buf[1]);
@@ -892,15 +987,13 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
892 987
893 rc = ebitmap_read(&r->level[0].cat, fp); 988 rc = ebitmap_read(&r->level[0].cat, fp);
894 if (rc) { 989 if (rc) {
895 printk(KERN_ERR "SELinux: mls: error reading low " 990 printk(KERN_ERR "SELinux: mls: error reading low categories\n");
896 "categories\n");
897 goto out; 991 goto out;
898 } 992 }
899 if (items > 1) { 993 if (items > 1) {
900 rc = ebitmap_read(&r->level[1].cat, fp); 994 rc = ebitmap_read(&r->level[1].cat, fp);
901 if (rc) { 995 if (rc) {
902 printk(KERN_ERR "SELinux: mls: error reading high " 996 printk(KERN_ERR "SELinux: mls: error reading high categories\n");
903 "categories\n");
904 goto bad_high; 997 goto bad_high;
905 } 998 }
906 } else { 999 } else {
@@ -911,12 +1004,11 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
911 } 1004 }
912 } 1005 }
913 1006
914 rc = 0; 1007 return 0;
915out:
916 return rc;
917bad_high: 1008bad_high:
918 ebitmap_destroy(&r->level[0].cat); 1009 ebitmap_destroy(&r->level[0].cat);
919 goto out; 1010out:
1011 return rc;
920} 1012}
921 1013
922/* 1014/*
@@ -931,7 +1023,7 @@ static int context_read_and_validate(struct context *c,
931 int rc; 1023 int rc;
932 1024
933 rc = next_entry(buf, fp, sizeof buf); 1025 rc = next_entry(buf, fp, sizeof buf);
934 if (rc < 0) { 1026 if (rc) {
935 printk(KERN_ERR "SELinux: context truncated\n"); 1027 printk(KERN_ERR "SELinux: context truncated\n");
936 goto out; 1028 goto out;
937 } 1029 }
@@ -939,19 +1031,20 @@ static int context_read_and_validate(struct context *c,
939 c->role = le32_to_cpu(buf[1]); 1031 c->role = le32_to_cpu(buf[1]);
940 c->type = le32_to_cpu(buf[2]); 1032 c->type = le32_to_cpu(buf[2]);
941 if (p->policyvers >= POLICYDB_VERSION_MLS) { 1033 if (p->policyvers >= POLICYDB_VERSION_MLS) {
942 if (mls_read_range_helper(&c->range, fp)) { 1034 rc = mls_read_range_helper(&c->range, fp);
943 printk(KERN_ERR "SELinux: error reading MLS range of " 1035 if (rc) {
944 "context\n"); 1036 printk(KERN_ERR "SELinux: error reading MLS range of context\n");
945 rc = -EINVAL;
946 goto out; 1037 goto out;
947 } 1038 }
948 } 1039 }
949 1040
1041 rc = -EINVAL;
950 if (!policydb_context_isvalid(p, c)) { 1042 if (!policydb_context_isvalid(p, c)) {
951 printk(KERN_ERR "SELinux: invalid security context\n"); 1043 printk(KERN_ERR "SELinux: invalid security context\n");
952 context_destroy(c); 1044 context_destroy(c);
953 rc = -EINVAL; 1045 goto out;
954 } 1046 }
1047 rc = 0;
955out: 1048out:
956 return rc; 1049 return rc;
957} 1050}
@@ -970,37 +1063,36 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
970 __le32 buf[2]; 1063 __le32 buf[2];
971 u32 len; 1064 u32 len;
972 1065
1066 rc = -ENOMEM;
973 perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL); 1067 perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);
974 if (!perdatum) { 1068 if (!perdatum)
975 rc = -ENOMEM; 1069 goto bad;
976 goto out;
977 }
978 1070
979 rc = next_entry(buf, fp, sizeof buf); 1071 rc = next_entry(buf, fp, sizeof buf);
980 if (rc < 0) 1072 if (rc)
981 goto bad; 1073 goto bad;
982 1074
983 len = le32_to_cpu(buf[0]); 1075 len = le32_to_cpu(buf[0]);
984 perdatum->value = le32_to_cpu(buf[1]); 1076 perdatum->value = le32_to_cpu(buf[1]);
985 1077
1078 rc = -ENOMEM;
986 key = kmalloc(len + 1, GFP_KERNEL); 1079 key = kmalloc(len + 1, GFP_KERNEL);
987 if (!key) { 1080 if (!key)
988 rc = -ENOMEM;
989 goto bad; 1081 goto bad;
990 } 1082
991 rc = next_entry(key, fp, len); 1083 rc = next_entry(key, fp, len);
992 if (rc < 0) 1084 if (rc)
993 goto bad; 1085 goto bad;
994 key[len] = '\0'; 1086 key[len] = '\0';
995 1087
996 rc = hashtab_insert(h, key, perdatum); 1088 rc = hashtab_insert(h, key, perdatum);
997 if (rc) 1089 if (rc)
998 goto bad; 1090 goto bad;
999out: 1091
1000 return rc; 1092 return 0;
1001bad: 1093bad:
1002 perm_destroy(key, perdatum, NULL); 1094 perm_destroy(key, perdatum, NULL);
1003 goto out; 1095 return rc;
1004} 1096}
1005 1097
1006static int common_read(struct policydb *p, struct hashtab *h, void *fp) 1098static int common_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1011,14 +1103,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1011 u32 len, nel; 1103 u32 len, nel;
1012 int i, rc; 1104 int i, rc;
1013 1105
1106 rc = -ENOMEM;
1014 comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL); 1107 comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
1015 if (!comdatum) { 1108 if (!comdatum)
1016 rc = -ENOMEM; 1109 goto bad;
1017 goto out;
1018 }
1019 1110
1020 rc = next_entry(buf, fp, sizeof buf); 1111 rc = next_entry(buf, fp, sizeof buf);
1021 if (rc < 0) 1112 if (rc)
1022 goto bad; 1113 goto bad;
1023 1114
1024 len = le32_to_cpu(buf[0]); 1115 len = le32_to_cpu(buf[0]);
@@ -1030,13 +1121,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1030 comdatum->permissions.nprim = le32_to_cpu(buf[2]); 1121 comdatum->permissions.nprim = le32_to_cpu(buf[2]);
1031 nel = le32_to_cpu(buf[3]); 1122 nel = le32_to_cpu(buf[3]);
1032 1123
1124 rc = -ENOMEM;
1033 key = kmalloc(len + 1, GFP_KERNEL); 1125 key = kmalloc(len + 1, GFP_KERNEL);
1034 if (!key) { 1126 if (!key)
1035 rc = -ENOMEM;
1036 goto bad; 1127 goto bad;
1037 } 1128
1038 rc = next_entry(key, fp, len); 1129 rc = next_entry(key, fp, len);
1039 if (rc < 0) 1130 if (rc)
1040 goto bad; 1131 goto bad;
1041 key[len] = '\0'; 1132 key[len] = '\0';
1042 1133
@@ -1049,11 +1140,10 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1049 rc = hashtab_insert(h, key, comdatum); 1140 rc = hashtab_insert(h, key, comdatum);
1050 if (rc) 1141 if (rc)
1051 goto bad; 1142 goto bad;
1052out: 1143 return 0;
1053 return rc;
1054bad: 1144bad:
1055 common_destroy(key, comdatum, NULL); 1145 common_destroy(key, comdatum, NULL);
1056 goto out; 1146 return rc;
1057} 1147}
1058 1148
1059static int read_cons_helper(struct constraint_node **nodep, int ncons, 1149static int read_cons_helper(struct constraint_node **nodep, int ncons,
@@ -1077,7 +1167,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1077 *nodep = c; 1167 *nodep = c;
1078 1168
1079 rc = next_entry(buf, fp, (sizeof(u32) * 2)); 1169 rc = next_entry(buf, fp, (sizeof(u32) * 2));
1080 if (rc < 0) 1170 if (rc)
1081 return rc; 1171 return rc;
1082 c->permissions = le32_to_cpu(buf[0]); 1172 c->permissions = le32_to_cpu(buf[0]);
1083 nexpr = le32_to_cpu(buf[1]); 1173 nexpr = le32_to_cpu(buf[1]);
@@ -1094,7 +1184,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1094 c->expr = e; 1184 c->expr = e;
1095 1185
1096 rc = next_entry(buf, fp, (sizeof(u32) * 3)); 1186 rc = next_entry(buf, fp, (sizeof(u32) * 3));
1097 if (rc < 0) 1187 if (rc)
1098 return rc; 1188 return rc;
1099 e->expr_type = le32_to_cpu(buf[0]); 1189 e->expr_type = le32_to_cpu(buf[0]);
1100 e->attr = le32_to_cpu(buf[1]); 1190 e->attr = le32_to_cpu(buf[1]);
@@ -1122,8 +1212,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1122 if (depth == (CEXPR_MAXDEPTH - 1)) 1212 if (depth == (CEXPR_MAXDEPTH - 1))
1123 return -EINVAL; 1213 return -EINVAL;
1124 depth++; 1214 depth++;
1125 if (ebitmap_read(&e->names, fp)) 1215 rc = ebitmap_read(&e->names, fp);
1126 return -EINVAL; 1216 if (rc)
1217 return rc;
1127 break; 1218 break;
1128 default: 1219 default:
1129 return -EINVAL; 1220 return -EINVAL;
@@ -1146,14 +1237,13 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1146 u32 len, len2, ncons, nel; 1237 u32 len, len2, ncons, nel;
1147 int i, rc; 1238 int i, rc;
1148 1239
1240 rc = -ENOMEM;
1149 cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL); 1241 cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
1150 if (!cladatum) { 1242 if (!cladatum)
1151 rc = -ENOMEM; 1243 goto bad;
1152 goto out;
1153 }
1154 1244
1155 rc = next_entry(buf, fp, sizeof(u32)*6); 1245 rc = next_entry(buf, fp, sizeof(u32)*6);
1156 if (rc < 0) 1246 if (rc)
1157 goto bad; 1247 goto bad;
1158 1248
1159 len = le32_to_cpu(buf[0]); 1249 len = le32_to_cpu(buf[0]);
@@ -1168,33 +1258,30 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1168 1258
1169 ncons = le32_to_cpu(buf[5]); 1259 ncons = le32_to_cpu(buf[5]);
1170 1260
1261 rc = -ENOMEM;
1171 key = kmalloc(len + 1, GFP_KERNEL); 1262 key = kmalloc(len + 1, GFP_KERNEL);
1172 if (!key) { 1263 if (!key)
1173 rc = -ENOMEM;
1174 goto bad; 1264 goto bad;
1175 } 1265
1176 rc = next_entry(key, fp, len); 1266 rc = next_entry(key, fp, len);
1177 if (rc < 0) 1267 if (rc)
1178 goto bad; 1268 goto bad;
1179 key[len] = '\0'; 1269 key[len] = '\0';
1180 1270
1181 if (len2) { 1271 if (len2) {
1272 rc = -ENOMEM;
1182 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL); 1273 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL);
1183 if (!cladatum->comkey) { 1274 if (!cladatum->comkey)
1184 rc = -ENOMEM;
1185 goto bad; 1275 goto bad;
1186 }
1187 rc = next_entry(cladatum->comkey, fp, len2); 1276 rc = next_entry(cladatum->comkey, fp, len2);
1188 if (rc < 0) 1277 if (rc)
1189 goto bad; 1278 goto bad;
1190 cladatum->comkey[len2] = '\0'; 1279 cladatum->comkey[len2] = '\0';
1191 1280
1192 cladatum->comdatum = hashtab_search(p->p_commons.table, 1281 rc = -EINVAL;
1193 cladatum->comkey); 1282 cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey);
1194 if (!cladatum->comdatum) { 1283 if (!cladatum->comdatum) {
1195 printk(KERN_ERR "SELinux: unknown common %s\n", 1284 printk(KERN_ERR "SELinux: unknown common %s\n", cladatum->comkey);
1196 cladatum->comkey);
1197 rc = -EINVAL;
1198 goto bad; 1285 goto bad;
1199 } 1286 }
1200 } 1287 }
@@ -1211,7 +1298,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1211 if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) { 1298 if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) {
1212 /* grab the validatetrans rules */ 1299 /* grab the validatetrans rules */
1213 rc = next_entry(buf, fp, sizeof(u32)); 1300 rc = next_entry(buf, fp, sizeof(u32));
1214 if (rc < 0) 1301 if (rc)
1215 goto bad; 1302 goto bad;
1216 ncons = le32_to_cpu(buf[0]); 1303 ncons = le32_to_cpu(buf[0]);
1217 rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); 1304 rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp);
@@ -1223,12 +1310,10 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1223 if (rc) 1310 if (rc)
1224 goto bad; 1311 goto bad;
1225 1312
1226 rc = 0; 1313 return 0;
1227out:
1228 return rc;
1229bad: 1314bad:
1230 cls_destroy(key, cladatum, NULL); 1315 cls_destroy(key, cladatum, NULL);
1231 goto out; 1316 return rc;
1232} 1317}
1233 1318
1234static int role_read(struct policydb *p, struct hashtab *h, void *fp) 1319static int role_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1239,17 +1324,16 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1239 __le32 buf[3]; 1324 __le32 buf[3];
1240 u32 len; 1325 u32 len;
1241 1326
1327 rc = -ENOMEM;
1242 role = kzalloc(sizeof(*role), GFP_KERNEL); 1328 role = kzalloc(sizeof(*role), GFP_KERNEL);
1243 if (!role) { 1329 if (!role)
1244 rc = -ENOMEM; 1330 goto bad;
1245 goto out;
1246 }
1247 1331
1248 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1332 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1249 to_read = 3; 1333 to_read = 3;
1250 1334
1251 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1335 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1252 if (rc < 0) 1336 if (rc)
1253 goto bad; 1337 goto bad;
1254 1338
1255 len = le32_to_cpu(buf[0]); 1339 len = le32_to_cpu(buf[0]);
@@ -1257,13 +1341,13 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1257 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1341 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1258 role->bounds = le32_to_cpu(buf[2]); 1342 role->bounds = le32_to_cpu(buf[2]);
1259 1343
1344 rc = -ENOMEM;
1260 key = kmalloc(len + 1, GFP_KERNEL); 1345 key = kmalloc(len + 1, GFP_KERNEL);
1261 if (!key) { 1346 if (!key)
1262 rc = -ENOMEM;
1263 goto bad; 1347 goto bad;
1264 } 1348
1265 rc = next_entry(key, fp, len); 1349 rc = next_entry(key, fp, len);
1266 if (rc < 0) 1350 if (rc)
1267 goto bad; 1351 goto bad;
1268 key[len] = '\0'; 1352 key[len] = '\0';
1269 1353
@@ -1276,10 +1360,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1276 goto bad; 1360 goto bad;
1277 1361
1278 if (strcmp(key, OBJECT_R) == 0) { 1362 if (strcmp(key, OBJECT_R) == 0) {
1363 rc = -EINVAL;
1279 if (role->value != OBJECT_R_VAL) { 1364 if (role->value != OBJECT_R_VAL) {
1280 printk(KERN_ERR "SELinux: Role %s has wrong value %d\n", 1365 printk(KERN_ERR "SELinux: Role %s has wrong value %d\n",
1281 OBJECT_R, role->value); 1366 OBJECT_R, role->value);
1282 rc = -EINVAL;
1283 goto bad; 1367 goto bad;
1284 } 1368 }
1285 rc = 0; 1369 rc = 0;
@@ -1289,11 +1373,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1289 rc = hashtab_insert(h, key, role); 1373 rc = hashtab_insert(h, key, role);
1290 if (rc) 1374 if (rc)
1291 goto bad; 1375 goto bad;
1292out: 1376 return 0;
1293 return rc;
1294bad: 1377bad:
1295 role_destroy(key, role, NULL); 1378 role_destroy(key, role, NULL);
1296 goto out; 1379 return rc;
1297} 1380}
1298 1381
1299static int type_read(struct policydb *p, struct hashtab *h, void *fp) 1382static int type_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1304,17 +1387,16 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1304 __le32 buf[4]; 1387 __le32 buf[4];
1305 u32 len; 1388 u32 len;
1306 1389
1390 rc = -ENOMEM;
1307 typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL); 1391 typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL);
1308 if (!typdatum) { 1392 if (!typdatum)
1309 rc = -ENOMEM; 1393 goto bad;
1310 return rc;
1311 }
1312 1394
1313 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1395 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1314 to_read = 4; 1396 to_read = 4;
1315 1397
1316 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1398 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1317 if (rc < 0) 1399 if (rc)
1318 goto bad; 1400 goto bad;
1319 1401
1320 len = le32_to_cpu(buf[0]); 1402 len = le32_to_cpu(buf[0]);
@@ -1332,24 +1414,22 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1332 typdatum->primary = le32_to_cpu(buf[2]); 1414 typdatum->primary = le32_to_cpu(buf[2]);
1333 } 1415 }
1334 1416
1417 rc = -ENOMEM;
1335 key = kmalloc(len + 1, GFP_KERNEL); 1418 key = kmalloc(len + 1, GFP_KERNEL);
1336 if (!key) { 1419 if (!key)
1337 rc = -ENOMEM;
1338 goto bad; 1420 goto bad;
1339 }
1340 rc = next_entry(key, fp, len); 1421 rc = next_entry(key, fp, len);
1341 if (rc < 0) 1422 if (rc)
1342 goto bad; 1423 goto bad;
1343 key[len] = '\0'; 1424 key[len] = '\0';
1344 1425
1345 rc = hashtab_insert(h, key, typdatum); 1426 rc = hashtab_insert(h, key, typdatum);
1346 if (rc) 1427 if (rc)
1347 goto bad; 1428 goto bad;
1348out: 1429 return 0;
1349 return rc;
1350bad: 1430bad:
1351 type_destroy(key, typdatum, NULL); 1431 type_destroy(key, typdatum, NULL);
1352 goto out; 1432 return rc;
1353} 1433}
1354 1434
1355 1435
@@ -1365,22 +1445,18 @@ static int mls_read_level(struct mls_level *lp, void *fp)
1365 memset(lp, 0, sizeof(*lp)); 1445 memset(lp, 0, sizeof(*lp));
1366 1446
1367 rc = next_entry(buf, fp, sizeof buf); 1447 rc = next_entry(buf, fp, sizeof buf);
1368 if (rc < 0) { 1448 if (rc) {
1369 printk(KERN_ERR "SELinux: mls: truncated level\n"); 1449 printk(KERN_ERR "SELinux: mls: truncated level\n");
1370 goto bad; 1450 return rc;
1371 } 1451 }
1372 lp->sens = le32_to_cpu(buf[0]); 1452 lp->sens = le32_to_cpu(buf[0]);
1373 1453
1374 if (ebitmap_read(&lp->cat, fp)) { 1454 rc = ebitmap_read(&lp->cat, fp);
1375 printk(KERN_ERR "SELinux: mls: error reading level " 1455 if (rc) {
1376 "categories\n"); 1456 printk(KERN_ERR "SELinux: mls: error reading level categories\n");
1377 goto bad; 1457 return rc;
1378 } 1458 }
1379
1380 return 0; 1459 return 0;
1381
1382bad:
1383 return -EINVAL;
1384} 1460}
1385 1461
1386static int user_read(struct policydb *p, struct hashtab *h, void *fp) 1462static int user_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1391,17 +1467,16 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1391 __le32 buf[3]; 1467 __le32 buf[3];
1392 u32 len; 1468 u32 len;
1393 1469
1470 rc = -ENOMEM;
1394 usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL); 1471 usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
1395 if (!usrdatum) { 1472 if (!usrdatum)
1396 rc = -ENOMEM; 1473 goto bad;
1397 goto out;
1398 }
1399 1474
1400 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1475 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1401 to_read = 3; 1476 to_read = 3;
1402 1477
1403 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1478 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1404 if (rc < 0) 1479 if (rc)
1405 goto bad; 1480 goto bad;
1406 1481
1407 len = le32_to_cpu(buf[0]); 1482 len = le32_to_cpu(buf[0]);
@@ -1409,13 +1484,12 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1409 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1484 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1410 usrdatum->bounds = le32_to_cpu(buf[2]); 1485 usrdatum->bounds = le32_to_cpu(buf[2]);
1411 1486
1487 rc = -ENOMEM;
1412 key = kmalloc(len + 1, GFP_KERNEL); 1488 key = kmalloc(len + 1, GFP_KERNEL);
1413 if (!key) { 1489 if (!key)
1414 rc = -ENOMEM;
1415 goto bad; 1490 goto bad;
1416 }
1417 rc = next_entry(key, fp, len); 1491 rc = next_entry(key, fp, len);
1418 if (rc < 0) 1492 if (rc)
1419 goto bad; 1493 goto bad;
1420 key[len] = '\0'; 1494 key[len] = '\0';
1421 1495
@@ -1435,11 +1509,10 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1435 rc = hashtab_insert(h, key, usrdatum); 1509 rc = hashtab_insert(h, key, usrdatum);
1436 if (rc) 1510 if (rc)
1437 goto bad; 1511 goto bad;
1438out: 1512 return 0;
1439 return rc;
1440bad: 1513bad:
1441 user_destroy(key, usrdatum, NULL); 1514 user_destroy(key, usrdatum, NULL);
1442 goto out; 1515 return rc;
1443} 1516}
1444 1517
1445static int sens_read(struct policydb *p, struct hashtab *h, void *fp) 1518static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1450,47 +1523,43 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
1450 __le32 buf[2]; 1523 __le32 buf[2];
1451 u32 len; 1524 u32 len;
1452 1525
1526 rc = -ENOMEM;
1453 levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC); 1527 levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
1454 if (!levdatum) { 1528 if (!levdatum)
1455 rc = -ENOMEM; 1529 goto bad;
1456 goto out;
1457 }
1458 1530
1459 rc = next_entry(buf, fp, sizeof buf); 1531 rc = next_entry(buf, fp, sizeof buf);
1460 if (rc < 0) 1532 if (rc)
1461 goto bad; 1533 goto bad;
1462 1534
1463 len = le32_to_cpu(buf[0]); 1535 len = le32_to_cpu(buf[0]);
1464 levdatum->isalias = le32_to_cpu(buf[1]); 1536 levdatum->isalias = le32_to_cpu(buf[1]);
1465 1537
1538 rc = -ENOMEM;
1466 key = kmalloc(len + 1, GFP_ATOMIC); 1539 key = kmalloc(len + 1, GFP_ATOMIC);
1467 if (!key) { 1540 if (!key)
1468 rc = -ENOMEM;
1469 goto bad; 1541 goto bad;
1470 }
1471 rc = next_entry(key, fp, len); 1542 rc = next_entry(key, fp, len);
1472 if (rc < 0) 1543 if (rc)
1473 goto bad; 1544 goto bad;
1474 key[len] = '\0'; 1545 key[len] = '\0';
1475 1546
1547 rc = -ENOMEM;
1476 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); 1548 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);
1477 if (!levdatum->level) { 1549 if (!levdatum->level)
1478 rc = -ENOMEM;
1479 goto bad; 1550 goto bad;
1480 } 1551
1481 if (mls_read_level(levdatum->level, fp)) { 1552 rc = mls_read_level(levdatum->level, fp);
1482 rc = -EINVAL; 1553 if (rc)
1483 goto bad; 1554 goto bad;
1484 }
1485 1555
1486 rc = hashtab_insert(h, key, levdatum); 1556 rc = hashtab_insert(h, key, levdatum);
1487 if (rc) 1557 if (rc)
1488 goto bad; 1558 goto bad;
1489out: 1559 return 0;
1490 return rc;
1491bad: 1560bad:
1492 sens_destroy(key, levdatum, NULL); 1561 sens_destroy(key, levdatum, NULL);
1493 goto out; 1562 return rc;
1494} 1563}
1495 1564
1496static int cat_read(struct policydb *p, struct hashtab *h, void *fp) 1565static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1501,39 +1570,35 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
1501 __le32 buf[3]; 1570 __le32 buf[3];
1502 u32 len; 1571 u32 len;
1503 1572
1573 rc = -ENOMEM;
1504 catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC); 1574 catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
1505 if (!catdatum) { 1575 if (!catdatum)
1506 rc = -ENOMEM; 1576 goto bad;
1507 goto out;
1508 }
1509 1577
1510 rc = next_entry(buf, fp, sizeof buf); 1578 rc = next_entry(buf, fp, sizeof buf);
1511 if (rc < 0) 1579 if (rc)
1512 goto bad; 1580 goto bad;
1513 1581
1514 len = le32_to_cpu(buf[0]); 1582 len = le32_to_cpu(buf[0]);
1515 catdatum->value = le32_to_cpu(buf[1]); 1583 catdatum->value = le32_to_cpu(buf[1]);
1516 catdatum->isalias = le32_to_cpu(buf[2]); 1584 catdatum->isalias = le32_to_cpu(buf[2]);
1517 1585
1586 rc = -ENOMEM;
1518 key = kmalloc(len + 1, GFP_ATOMIC); 1587 key = kmalloc(len + 1, GFP_ATOMIC);
1519 if (!key) { 1588 if (!key)
1520 rc = -ENOMEM;
1521 goto bad; 1589 goto bad;
1522 }
1523 rc = next_entry(key, fp, len); 1590 rc = next_entry(key, fp, len);
1524 if (rc < 0) 1591 if (rc)
1525 goto bad; 1592 goto bad;
1526 key[len] = '\0'; 1593 key[len] = '\0';
1527 1594
1528 rc = hashtab_insert(h, key, catdatum); 1595 rc = hashtab_insert(h, key, catdatum);
1529 if (rc) 1596 if (rc)
1530 goto bad; 1597 goto bad;
1531out: 1598 return 0;
1532 return rc;
1533
1534bad: 1599bad:
1535 cat_destroy(key, catdatum, NULL); 1600 cat_destroy(key, catdatum, NULL);
1536 goto out; 1601 return rc;
1537} 1602}
1538 1603
1539static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) = 1604static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) =
@@ -1574,9 +1639,9 @@ static int user_bounds_sanity_check(void *key, void *datum, void *datap)
1574 printk(KERN_ERR 1639 printk(KERN_ERR
1575 "SELinux: boundary violated policy: " 1640 "SELinux: boundary violated policy: "
1576 "user=%s role=%s bounds=%s\n", 1641 "user=%s role=%s bounds=%s\n",
1577 p->p_user_val_to_name[user->value - 1], 1642 sym_name(p, SYM_USERS, user->value - 1),
1578 p->p_role_val_to_name[bit], 1643 sym_name(p, SYM_ROLES, bit),
1579 p->p_user_val_to_name[upper->value - 1]); 1644 sym_name(p, SYM_USERS, upper->value - 1));
1580 1645
1581 return -EINVAL; 1646 return -EINVAL;
1582 } 1647 }
@@ -1611,9 +1676,9 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap)
1611 printk(KERN_ERR 1676 printk(KERN_ERR
1612 "SELinux: boundary violated policy: " 1677 "SELinux: boundary violated policy: "
1613 "role=%s type=%s bounds=%s\n", 1678 "role=%s type=%s bounds=%s\n",
1614 p->p_role_val_to_name[role->value - 1], 1679 sym_name(p, SYM_ROLES, role->value - 1),
1615 p->p_type_val_to_name[bit], 1680 sym_name(p, SYM_TYPES, bit),
1616 p->p_role_val_to_name[upper->value - 1]); 1681 sym_name(p, SYM_ROLES, upper->value - 1));
1617 1682
1618 return -EINVAL; 1683 return -EINVAL;
1619 } 1684 }
@@ -1624,11 +1689,11 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap)
1624 1689
1625static int type_bounds_sanity_check(void *key, void *datum, void *datap) 1690static int type_bounds_sanity_check(void *key, void *datum, void *datap)
1626{ 1691{
1627 struct type_datum *upper, *type; 1692 struct type_datum *upper;
1628 struct policydb *p = datap; 1693 struct policydb *p = datap;
1629 int depth = 0; 1694 int depth = 0;
1630 1695
1631 upper = type = datum; 1696 upper = datum;
1632 while (upper->bounds) { 1697 while (upper->bounds) {
1633 if (++depth == POLICYDB_BOUNDS_MAXDEPTH) { 1698 if (++depth == POLICYDB_BOUNDS_MAXDEPTH) {
1634 printk(KERN_ERR "SELinux: type %s: " 1699 printk(KERN_ERR "SELinux: type %s: "
@@ -1637,12 +1702,15 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap)
1637 return -EINVAL; 1702 return -EINVAL;
1638 } 1703 }
1639 1704
1640 upper = p->type_val_to_struct[upper->bounds - 1]; 1705 upper = flex_array_get_ptr(p->type_val_to_struct_array,
1706 upper->bounds - 1);
1707 BUG_ON(!upper);
1708
1641 if (upper->attribute) { 1709 if (upper->attribute) {
1642 printk(KERN_ERR "SELinux: type %s: " 1710 printk(KERN_ERR "SELinux: type %s: "
1643 "bounded by attribute %s", 1711 "bounded by attribute %s",
1644 (char *) key, 1712 (char *) key,
1645 p->p_type_val_to_name[upper->value - 1]); 1713 sym_name(p, SYM_TYPES, upper->value - 1));
1646 return -EINVAL; 1714 return -EINVAL;
1647 } 1715 }
1648 } 1716 }
@@ -1775,7 +1843,7 @@ static int range_read(struct policydb *p, void *fp)
1775 rt = NULL; 1843 rt = NULL;
1776 r = NULL; 1844 r = NULL;
1777 } 1845 }
1778 rangetr_hash_eval(p->range_tr); 1846 hash_eval(p->range_tr, "rangetr");
1779 rc = 0; 1847 rc = 0;
1780out: 1848out:
1781 kfree(rt); 1849 kfree(rt);
@@ -1783,6 +1851,83 @@ out:
1783 return rc; 1851 return rc;
1784} 1852}
1785 1853
1854static int filename_trans_read(struct policydb *p, void *fp)
1855{
1856 struct filename_trans *ft;
1857 struct filename_trans_datum *otype;
1858 char *name;
1859 u32 nel, len;
1860 __le32 buf[4];
1861 int rc, i;
1862
1863 if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
1864 return 0;
1865
1866 rc = next_entry(buf, fp, sizeof(u32));
1867 if (rc)
1868 return rc;
1869 nel = le32_to_cpu(buf[0]);
1870
1871 for (i = 0; i < nel; i++) {
1872 ft = NULL;
1873 otype = NULL;
1874 name = NULL;
1875
1876 rc = -ENOMEM;
1877 ft = kzalloc(sizeof(*ft), GFP_KERNEL);
1878 if (!ft)
1879 goto out;
1880
1881 rc = -ENOMEM;
1882 otype = kmalloc(sizeof(*otype), GFP_KERNEL);
1883 if (!otype)
1884 goto out;
1885
1886 /* length of the path component string */
1887 rc = next_entry(buf, fp, sizeof(u32));
1888 if (rc)
1889 goto out;
1890 len = le32_to_cpu(buf[0]);
1891
1892 rc = -ENOMEM;
1893 name = kmalloc(len + 1, GFP_KERNEL);
1894 if (!name)
1895 goto out;
1896
1897 ft->name = name;
1898
1899 /* path component string */
1900 rc = next_entry(name, fp, len);
1901 if (rc)
1902 goto out;
1903 name[len] = 0;
1904
1905 rc = next_entry(buf, fp, sizeof(u32) * 4);
1906 if (rc)
1907 goto out;
1908
1909 ft->stype = le32_to_cpu(buf[0]);
1910 ft->ttype = le32_to_cpu(buf[1]);
1911 ft->tclass = le32_to_cpu(buf[2]);
1912
1913 otype->otype = le32_to_cpu(buf[3]);
1914
1915 rc = ebitmap_set_bit(&p->filename_trans_ttypes, ft->ttype, 1);
1916 if (rc)
1917 goto out;
1918
1919 hashtab_insert(p->filename_trans, ft, otype);
1920 }
1921 hash_eval(p->filename_trans, "filenametr");
1922 return 0;
1923out:
1924 kfree(ft);
1925 kfree(name);
1926 kfree(otype);
1927
1928 return rc;
1929}
1930
1786static int genfs_read(struct policydb *p, void *fp) 1931static int genfs_read(struct policydb *p, void *fp)
1787{ 1932{
1788 int i, j, rc; 1933 int i, j, rc;
@@ -2055,13 +2200,14 @@ int policydb_read(struct policydb *p, void *fp)
2055 2200
2056 rc = policydb_init(p); 2201 rc = policydb_init(p);
2057 if (rc) 2202 if (rc)
2058 goto out; 2203 return rc;
2059 2204
2060 /* Read the magic number and string length. */ 2205 /* Read the magic number and string length. */
2061 rc = next_entry(buf, fp, sizeof(u32) * 2); 2206 rc = next_entry(buf, fp, sizeof(u32) * 2);
2062 if (rc < 0) 2207 if (rc)
2063 goto bad; 2208 goto bad;
2064 2209
2210 rc = -EINVAL;
2065 if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { 2211 if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) {
2066 printk(KERN_ERR "SELinux: policydb magic number 0x%x does " 2212 printk(KERN_ERR "SELinux: policydb magic number 0x%x does "
2067 "not match expected magic number 0x%x\n", 2213 "not match expected magic number 0x%x\n",
@@ -2069,6 +2215,7 @@ int policydb_read(struct policydb *p, void *fp)
2069 goto bad; 2215 goto bad;
2070 } 2216 }
2071 2217
2218 rc = -EINVAL;
2072 len = le32_to_cpu(buf[1]); 2219 len = le32_to_cpu(buf[1]);
2073 if (len != strlen(POLICYDB_STRING)) { 2220 if (len != strlen(POLICYDB_STRING)) {
2074 printk(KERN_ERR "SELinux: policydb string length %d does not " 2221 printk(KERN_ERR "SELinux: policydb string length %d does not "
@@ -2076,19 +2223,23 @@ int policydb_read(struct policydb *p, void *fp)
2076 len, strlen(POLICYDB_STRING)); 2223 len, strlen(POLICYDB_STRING));
2077 goto bad; 2224 goto bad;
2078 } 2225 }
2226
2227 rc = -ENOMEM;
2079 policydb_str = kmalloc(len + 1, GFP_KERNEL); 2228 policydb_str = kmalloc(len + 1, GFP_KERNEL);
2080 if (!policydb_str) { 2229 if (!policydb_str) {
2081 printk(KERN_ERR "SELinux: unable to allocate memory for policydb " 2230 printk(KERN_ERR "SELinux: unable to allocate memory for policydb "
2082 "string of length %d\n", len); 2231 "string of length %d\n", len);
2083 rc = -ENOMEM;
2084 goto bad; 2232 goto bad;
2085 } 2233 }
2234
2086 rc = next_entry(policydb_str, fp, len); 2235 rc = next_entry(policydb_str, fp, len);
2087 if (rc < 0) { 2236 if (rc) {
2088 printk(KERN_ERR "SELinux: truncated policydb string identifier\n"); 2237 printk(KERN_ERR "SELinux: truncated policydb string identifier\n");
2089 kfree(policydb_str); 2238 kfree(policydb_str);
2090 goto bad; 2239 goto bad;
2091 } 2240 }
2241
2242 rc = -EINVAL;
2092 policydb_str[len] = '\0'; 2243 policydb_str[len] = '\0';
2093 if (strcmp(policydb_str, POLICYDB_STRING)) { 2244 if (strcmp(policydb_str, POLICYDB_STRING)) {
2094 printk(KERN_ERR "SELinux: policydb string %s does not match " 2245 printk(KERN_ERR "SELinux: policydb string %s does not match "
@@ -2102,9 +2253,10 @@ int policydb_read(struct policydb *p, void *fp)
2102 2253
2103 /* Read the version and table sizes. */ 2254 /* Read the version and table sizes. */
2104 rc = next_entry(buf, fp, sizeof(u32)*4); 2255 rc = next_entry(buf, fp, sizeof(u32)*4);
2105 if (rc < 0) 2256 if (rc)
2106 goto bad; 2257 goto bad;
2107 2258
2259 rc = -EINVAL;
2108 p->policyvers = le32_to_cpu(buf[0]); 2260 p->policyvers = le32_to_cpu(buf[0]);
2109 if (p->policyvers < POLICYDB_VERSION_MIN || 2261 if (p->policyvers < POLICYDB_VERSION_MIN ||
2110 p->policyvers > POLICYDB_VERSION_MAX) { 2262 p->policyvers > POLICYDB_VERSION_MAX) {
@@ -2117,6 +2269,7 @@ int policydb_read(struct policydb *p, void *fp)
2117 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { 2269 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
2118 p->mls_enabled = 1; 2270 p->mls_enabled = 1;
2119 2271
2272 rc = -EINVAL;
2120 if (p->policyvers < POLICYDB_VERSION_MLS) { 2273 if (p->policyvers < POLICYDB_VERSION_MLS) {
2121 printk(KERN_ERR "SELinux: security policydb version %d " 2274 printk(KERN_ERR "SELinux: security policydb version %d "
2122 "(MLS) not backwards compatible\n", 2275 "(MLS) not backwards compatible\n",
@@ -2127,14 +2280,19 @@ int policydb_read(struct policydb *p, void *fp)
2127 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); 2280 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
2128 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); 2281 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
2129 2282
2130 if (p->policyvers >= POLICYDB_VERSION_POLCAP && 2283 if (p->policyvers >= POLICYDB_VERSION_POLCAP) {
2131 ebitmap_read(&p->policycaps, fp) != 0) 2284 rc = ebitmap_read(&p->policycaps, fp);
2132 goto bad; 2285 if (rc)
2286 goto bad;
2287 }
2133 2288
2134 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && 2289 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE) {
2135 ebitmap_read(&p->permissive_map, fp) != 0) 2290 rc = ebitmap_read(&p->permissive_map, fp);
2136 goto bad; 2291 if (rc)
2292 goto bad;
2293 }
2137 2294
2295 rc = -EINVAL;
2138 info = policydb_lookup_compat(p->policyvers); 2296 info = policydb_lookup_compat(p->policyvers);
2139 if (!info) { 2297 if (!info) {
2140 printk(KERN_ERR "SELinux: unable to find policy compat info " 2298 printk(KERN_ERR "SELinux: unable to find policy compat info "
@@ -2142,6 +2300,7 @@ int policydb_read(struct policydb *p, void *fp)
2142 goto bad; 2300 goto bad;
2143 } 2301 }
2144 2302
2303 rc = -EINVAL;
2145 if (le32_to_cpu(buf[2]) != info->sym_num || 2304 if (le32_to_cpu(buf[2]) != info->sym_num ||
2146 le32_to_cpu(buf[3]) != info->ocon_num) { 2305 le32_to_cpu(buf[3]) != info->ocon_num) {
2147 printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do " 2306 printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do "
@@ -2153,7 +2312,7 @@ int policydb_read(struct policydb *p, void *fp)
2153 2312
2154 for (i = 0; i < info->sym_num; i++) { 2313 for (i = 0; i < info->sym_num; i++) {
2155 rc = next_entry(buf, fp, sizeof(u32)*2); 2314 rc = next_entry(buf, fp, sizeof(u32)*2);
2156 if (rc < 0) 2315 if (rc)
2157 goto bad; 2316 goto bad;
2158 nprim = le32_to_cpu(buf[0]); 2317 nprim = le32_to_cpu(buf[0]);
2159 nel = le32_to_cpu(buf[1]); 2318 nel = le32_to_cpu(buf[1]);
@@ -2166,6 +2325,11 @@ int policydb_read(struct policydb *p, void *fp)
2166 p->symtab[i].nprim = nprim; 2325 p->symtab[i].nprim = nprim;
2167 } 2326 }
2168 2327
2328 rc = -EINVAL;
2329 p->process_class = string_to_security_class(p, "process");
2330 if (!p->process_class)
2331 goto bad;
2332
2169 rc = avtab_read(&p->te_avtab, fp, p); 2333 rc = avtab_read(&p->te_avtab, fp, p);
2170 if (rc) 2334 if (rc)
2171 goto bad; 2335 goto bad;
@@ -2177,78 +2341,81 @@ int policydb_read(struct policydb *p, void *fp)
2177 } 2341 }
2178 2342
2179 rc = next_entry(buf, fp, sizeof(u32)); 2343 rc = next_entry(buf, fp, sizeof(u32));
2180 if (rc < 0) 2344 if (rc)
2181 goto bad; 2345 goto bad;
2182 nel = le32_to_cpu(buf[0]); 2346 nel = le32_to_cpu(buf[0]);
2183 ltr = NULL; 2347 ltr = NULL;
2184 for (i = 0; i < nel; i++) { 2348 for (i = 0; i < nel; i++) {
2349 rc = -ENOMEM;
2185 tr = kzalloc(sizeof(*tr), GFP_KERNEL); 2350 tr = kzalloc(sizeof(*tr), GFP_KERNEL);
2186 if (!tr) { 2351 if (!tr)
2187 rc = -ENOMEM;
2188 goto bad; 2352 goto bad;
2189 }
2190 if (ltr) 2353 if (ltr)
2191 ltr->next = tr; 2354 ltr->next = tr;
2192 else 2355 else
2193 p->role_tr = tr; 2356 p->role_tr = tr;
2194 rc = next_entry(buf, fp, sizeof(u32)*3); 2357 rc = next_entry(buf, fp, sizeof(u32)*3);
2195 if (rc < 0) 2358 if (rc)
2196 goto bad; 2359 goto bad;
2360
2361 rc = -EINVAL;
2197 tr->role = le32_to_cpu(buf[0]); 2362 tr->role = le32_to_cpu(buf[0]);
2198 tr->type = le32_to_cpu(buf[1]); 2363 tr->type = le32_to_cpu(buf[1]);
2199 tr->new_role = le32_to_cpu(buf[2]); 2364 tr->new_role = le32_to_cpu(buf[2]);
2365 if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
2366 rc = next_entry(buf, fp, sizeof(u32));
2367 if (rc)
2368 goto bad;
2369 tr->tclass = le32_to_cpu(buf[0]);
2370 } else
2371 tr->tclass = p->process_class;
2372
2200 if (!policydb_role_isvalid(p, tr->role) || 2373 if (!policydb_role_isvalid(p, tr->role) ||
2201 !policydb_type_isvalid(p, tr->type) || 2374 !policydb_type_isvalid(p, tr->type) ||
2202 !policydb_role_isvalid(p, tr->new_role)) { 2375 !policydb_class_isvalid(p, tr->tclass) ||
2203 rc = -EINVAL; 2376 !policydb_role_isvalid(p, tr->new_role))
2204 goto bad; 2377 goto bad;
2205 }
2206 ltr = tr; 2378 ltr = tr;
2207 } 2379 }
2208 2380
2209 rc = next_entry(buf, fp, sizeof(u32)); 2381 rc = next_entry(buf, fp, sizeof(u32));
2210 if (rc < 0) 2382 if (rc)
2211 goto bad; 2383 goto bad;
2212 nel = le32_to_cpu(buf[0]); 2384 nel = le32_to_cpu(buf[0]);
2213 lra = NULL; 2385 lra = NULL;
2214 for (i = 0; i < nel; i++) { 2386 for (i = 0; i < nel; i++) {
2387 rc = -ENOMEM;
2215 ra = kzalloc(sizeof(*ra), GFP_KERNEL); 2388 ra = kzalloc(sizeof(*ra), GFP_KERNEL);
2216 if (!ra) { 2389 if (!ra)
2217 rc = -ENOMEM;
2218 goto bad; 2390 goto bad;
2219 }
2220 if (lra) 2391 if (lra)
2221 lra->next = ra; 2392 lra->next = ra;
2222 else 2393 else
2223 p->role_allow = ra; 2394 p->role_allow = ra;
2224 rc = next_entry(buf, fp, sizeof(u32)*2); 2395 rc = next_entry(buf, fp, sizeof(u32)*2);
2225 if (rc < 0) 2396 if (rc)
2226 goto bad; 2397 goto bad;
2398
2399 rc = -EINVAL;
2227 ra->role = le32_to_cpu(buf[0]); 2400 ra->role = le32_to_cpu(buf[0]);
2228 ra->new_role = le32_to_cpu(buf[1]); 2401 ra->new_role = le32_to_cpu(buf[1]);
2229 if (!policydb_role_isvalid(p, ra->role) || 2402 if (!policydb_role_isvalid(p, ra->role) ||
2230 !policydb_role_isvalid(p, ra->new_role)) { 2403 !policydb_role_isvalid(p, ra->new_role))
2231 rc = -EINVAL;
2232 goto bad; 2404 goto bad;
2233 }
2234 lra = ra; 2405 lra = ra;
2235 } 2406 }
2236 2407
2237 rc = policydb_index_classes(p); 2408 rc = filename_trans_read(p, fp);
2238 if (rc) 2409 if (rc)
2239 goto bad; 2410 goto bad;
2240 2411
2241 rc = policydb_index_others(p); 2412 rc = policydb_index(p);
2242 if (rc) 2413 if (rc)
2243 goto bad; 2414 goto bad;
2244 2415
2245 p->process_class = string_to_security_class(p, "process"); 2416 rc = -EINVAL;
2246 if (!p->process_class) 2417 p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition");
2247 goto bad; 2418 p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition");
2248 p->process_trans_perms = string_to_av_perm(p, p->process_class,
2249 "transition");
2250 p->process_trans_perms |= string_to_av_perm(p, p->process_class,
2251 "dyntransition");
2252 if (!p->process_trans_perms) 2419 if (!p->process_trans_perms)
2253 goto bad; 2420 goto bad;
2254 2421
@@ -2272,7 +2439,7 @@ int policydb_read(struct policydb *p, void *fp)
2272 goto bad; 2439 goto bad;
2273 2440
2274 /* preallocate so we don't have to worry about the put ever failing */ 2441 /* preallocate so we don't have to worry about the put ever failing */
2275 rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim - 1, 2442 rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim,
2276 GFP_KERNEL | __GFP_ZERO); 2443 GFP_KERNEL | __GFP_ZERO);
2277 if (rc) 2444 if (rc)
2278 goto bad; 2445 goto bad;
@@ -2301,8 +2468,914 @@ int policydb_read(struct policydb *p, void *fp)
2301out: 2468out:
2302 return rc; 2469 return rc;
2303bad: 2470bad:
2304 if (!rc)
2305 rc = -EINVAL;
2306 policydb_destroy(p); 2471 policydb_destroy(p);
2307 goto out; 2472 goto out;
2308} 2473}
2474
2475/*
2476 * Write a MLS level structure to a policydb binary
2477 * representation file.
2478 */
2479static int mls_write_level(struct mls_level *l, void *fp)
2480{
2481 __le32 buf[1];
2482 int rc;
2483
2484 buf[0] = cpu_to_le32(l->sens);
2485 rc = put_entry(buf, sizeof(u32), 1, fp);
2486 if (rc)
2487 return rc;
2488
2489 rc = ebitmap_write(&l->cat, fp);
2490 if (rc)
2491 return rc;
2492
2493 return 0;
2494}
2495
2496/*
2497 * Write a MLS range structure to a policydb binary
2498 * representation file.
2499 */
2500static int mls_write_range_helper(struct mls_range *r, void *fp)
2501{
2502 __le32 buf[3];
2503 size_t items;
2504 int rc, eq;
2505
2506 eq = mls_level_eq(&r->level[1], &r->level[0]);
2507
2508 if (eq)
2509 items = 2;
2510 else
2511 items = 3;
2512 buf[0] = cpu_to_le32(items-1);
2513 buf[1] = cpu_to_le32(r->level[0].sens);
2514 if (!eq)
2515 buf[2] = cpu_to_le32(r->level[1].sens);
2516
2517 BUG_ON(items > (sizeof(buf)/sizeof(buf[0])));
2518
2519 rc = put_entry(buf, sizeof(u32), items, fp);
2520 if (rc)
2521 return rc;
2522
2523 rc = ebitmap_write(&r->level[0].cat, fp);
2524 if (rc)
2525 return rc;
2526 if (!eq) {
2527 rc = ebitmap_write(&r->level[1].cat, fp);
2528 if (rc)
2529 return rc;
2530 }
2531
2532 return 0;
2533}
2534
2535static int sens_write(void *vkey, void *datum, void *ptr)
2536{
2537 char *key = vkey;
2538 struct level_datum *levdatum = datum;
2539 struct policy_data *pd = ptr;
2540 void *fp = pd->fp;
2541 __le32 buf[2];
2542 size_t len;
2543 int rc;
2544
2545 len = strlen(key);
2546 buf[0] = cpu_to_le32(len);
2547 buf[1] = cpu_to_le32(levdatum->isalias);
2548 rc = put_entry(buf, sizeof(u32), 2, fp);
2549 if (rc)
2550 return rc;
2551
2552 rc = put_entry(key, 1, len, fp);
2553 if (rc)
2554 return rc;
2555
2556 rc = mls_write_level(levdatum->level, fp);
2557 if (rc)
2558 return rc;
2559
2560 return 0;
2561}
2562
2563static int cat_write(void *vkey, void *datum, void *ptr)
2564{
2565 char *key = vkey;
2566 struct cat_datum *catdatum = datum;
2567 struct policy_data *pd = ptr;
2568 void *fp = pd->fp;
2569 __le32 buf[3];
2570 size_t len;
2571 int rc;
2572
2573 len = strlen(key);
2574 buf[0] = cpu_to_le32(len);
2575 buf[1] = cpu_to_le32(catdatum->value);
2576 buf[2] = cpu_to_le32(catdatum->isalias);
2577 rc = put_entry(buf, sizeof(u32), 3, fp);
2578 if (rc)
2579 return rc;
2580
2581 rc = put_entry(key, 1, len, fp);
2582 if (rc)
2583 return rc;
2584
2585 return 0;
2586}
2587
2588static int role_trans_write(struct policydb *p, void *fp)
2589{
2590 struct role_trans *r = p->role_tr;
2591 struct role_trans *tr;
2592 u32 buf[3];
2593 size_t nel;
2594 int rc;
2595
2596 nel = 0;
2597 for (tr = r; tr; tr = tr->next)
2598 nel++;
2599 buf[0] = cpu_to_le32(nel);
2600 rc = put_entry(buf, sizeof(u32), 1, fp);
2601 if (rc)
2602 return rc;
2603 for (tr = r; tr; tr = tr->next) {
2604 buf[0] = cpu_to_le32(tr->role);
2605 buf[1] = cpu_to_le32(tr->type);
2606 buf[2] = cpu_to_le32(tr->new_role);
2607 rc = put_entry(buf, sizeof(u32), 3, fp);
2608 if (rc)
2609 return rc;
2610 if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
2611 buf[0] = cpu_to_le32(tr->tclass);
2612 rc = put_entry(buf, sizeof(u32), 1, fp);
2613 if (rc)
2614 return rc;
2615 }
2616 }
2617
2618 return 0;
2619}
2620
2621static int role_allow_write(struct role_allow *r, void *fp)
2622{
2623 struct role_allow *ra;
2624 u32 buf[2];
2625 size_t nel;
2626 int rc;
2627
2628 nel = 0;
2629 for (ra = r; ra; ra = ra->next)
2630 nel++;
2631 buf[0] = cpu_to_le32(nel);
2632 rc = put_entry(buf, sizeof(u32), 1, fp);
2633 if (rc)
2634 return rc;
2635 for (ra = r; ra; ra = ra->next) {
2636 buf[0] = cpu_to_le32(ra->role);
2637 buf[1] = cpu_to_le32(ra->new_role);
2638 rc = put_entry(buf, sizeof(u32), 2, fp);
2639 if (rc)
2640 return rc;
2641 }
2642 return 0;
2643}
2644
2645/*
2646 * Write a security context structure
2647 * to a policydb binary representation file.
2648 */
2649static int context_write(struct policydb *p, struct context *c,
2650 void *fp)
2651{
2652 int rc;
2653 __le32 buf[3];
2654
2655 buf[0] = cpu_to_le32(c->user);
2656 buf[1] = cpu_to_le32(c->role);
2657 buf[2] = cpu_to_le32(c->type);
2658
2659 rc = put_entry(buf, sizeof(u32), 3, fp);
2660 if (rc)
2661 return rc;
2662
2663 rc = mls_write_range_helper(&c->range, fp);
2664 if (rc)
2665 return rc;
2666
2667 return 0;
2668}
2669
2670/*
2671 * The following *_write functions are used to
2672 * write the symbol data to a policy database
2673 * binary representation file.
2674 */
2675
2676static int perm_write(void *vkey, void *datum, void *fp)
2677{
2678 char *key = vkey;
2679 struct perm_datum *perdatum = datum;
2680 __le32 buf[2];
2681 size_t len;
2682 int rc;
2683
2684 len = strlen(key);
2685 buf[0] = cpu_to_le32(len);
2686 buf[1] = cpu_to_le32(perdatum->value);
2687 rc = put_entry(buf, sizeof(u32), 2, fp);
2688 if (rc)
2689 return rc;
2690
2691 rc = put_entry(key, 1, len, fp);
2692 if (rc)
2693 return rc;
2694
2695 return 0;
2696}
2697
2698static int common_write(void *vkey, void *datum, void *ptr)
2699{
2700 char *key = vkey;
2701 struct common_datum *comdatum = datum;
2702 struct policy_data *pd = ptr;
2703 void *fp = pd->fp;
2704 __le32 buf[4];
2705 size_t len;
2706 int rc;
2707
2708 len = strlen(key);
2709 buf[0] = cpu_to_le32(len);
2710 buf[1] = cpu_to_le32(comdatum->value);
2711 buf[2] = cpu_to_le32(comdatum->permissions.nprim);
2712 buf[3] = cpu_to_le32(comdatum->permissions.table->nel);
2713 rc = put_entry(buf, sizeof(u32), 4, fp);
2714 if (rc)
2715 return rc;
2716
2717 rc = put_entry(key, 1, len, fp);
2718 if (rc)
2719 return rc;
2720
2721 rc = hashtab_map(comdatum->permissions.table, perm_write, fp);
2722 if (rc)
2723 return rc;
2724
2725 return 0;
2726}
2727
2728static int write_cons_helper(struct policydb *p, struct constraint_node *node,
2729 void *fp)
2730{
2731 struct constraint_node *c;
2732 struct constraint_expr *e;
2733 __le32 buf[3];
2734 u32 nel;
2735 int rc;
2736
2737 for (c = node; c; c = c->next) {
2738 nel = 0;
2739 for (e = c->expr; e; e = e->next)
2740 nel++;
2741 buf[0] = cpu_to_le32(c->permissions);
2742 buf[1] = cpu_to_le32(nel);
2743 rc = put_entry(buf, sizeof(u32), 2, fp);
2744 if (rc)
2745 return rc;
2746 for (e = c->expr; e; e = e->next) {
2747 buf[0] = cpu_to_le32(e->expr_type);
2748 buf[1] = cpu_to_le32(e->attr);
2749 buf[2] = cpu_to_le32(e->op);
2750 rc = put_entry(buf, sizeof(u32), 3, fp);
2751 if (rc)
2752 return rc;
2753
2754 switch (e->expr_type) {
2755 case CEXPR_NAMES:
2756 rc = ebitmap_write(&e->names, fp);
2757 if (rc)
2758 return rc;
2759 break;
2760 default:
2761 break;
2762 }
2763 }
2764 }
2765
2766 return 0;
2767}
2768
2769static int class_write(void *vkey, void *datum, void *ptr)
2770{
2771 char *key = vkey;
2772 struct class_datum *cladatum = datum;
2773 struct policy_data *pd = ptr;
2774 void *fp = pd->fp;
2775 struct policydb *p = pd->p;
2776 struct constraint_node *c;
2777 __le32 buf[6];
2778 u32 ncons;
2779 size_t len, len2;
2780 int rc;
2781
2782 len = strlen(key);
2783 if (cladatum->comkey)
2784 len2 = strlen(cladatum->comkey);
2785 else
2786 len2 = 0;
2787
2788 ncons = 0;
2789 for (c = cladatum->constraints; c; c = c->next)
2790 ncons++;
2791
2792 buf[0] = cpu_to_le32(len);
2793 buf[1] = cpu_to_le32(len2);
2794 buf[2] = cpu_to_le32(cladatum->value);
2795 buf[3] = cpu_to_le32(cladatum->permissions.nprim);
2796 if (cladatum->permissions.table)
2797 buf[4] = cpu_to_le32(cladatum->permissions.table->nel);
2798 else
2799 buf[4] = 0;
2800 buf[5] = cpu_to_le32(ncons);
2801 rc = put_entry(buf, sizeof(u32), 6, fp);
2802 if (rc)
2803 return rc;
2804
2805 rc = put_entry(key, 1, len, fp);
2806 if (rc)
2807 return rc;
2808
2809 if (cladatum->comkey) {
2810 rc = put_entry(cladatum->comkey, 1, len2, fp);
2811 if (rc)
2812 return rc;
2813 }
2814
2815 rc = hashtab_map(cladatum->permissions.table, perm_write, fp);
2816 if (rc)
2817 return rc;
2818
2819 rc = write_cons_helper(p, cladatum->constraints, fp);
2820 if (rc)
2821 return rc;
2822
2823 /* write out the validatetrans rule */
2824 ncons = 0;
2825 for (c = cladatum->validatetrans; c; c = c->next)
2826 ncons++;
2827
2828 buf[0] = cpu_to_le32(ncons);
2829 rc = put_entry(buf, sizeof(u32), 1, fp);
2830 if (rc)
2831 return rc;
2832
2833 rc = write_cons_helper(p, cladatum->validatetrans, fp);
2834 if (rc)
2835 return rc;
2836
2837 return 0;
2838}
2839
2840static int role_write(void *vkey, void *datum, void *ptr)
2841{
2842 char *key = vkey;
2843 struct role_datum *role = datum;
2844 struct policy_data *pd = ptr;
2845 void *fp = pd->fp;
2846 struct policydb *p = pd->p;
2847 __le32 buf[3];
2848 size_t items, len;
2849 int rc;
2850
2851 len = strlen(key);
2852 items = 0;
2853 buf[items++] = cpu_to_le32(len);
2854 buf[items++] = cpu_to_le32(role->value);
2855 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
2856 buf[items++] = cpu_to_le32(role->bounds);
2857
2858 BUG_ON(items > (sizeof(buf)/sizeof(buf[0])));
2859
2860 rc = put_entry(buf, sizeof(u32), items, fp);
2861 if (rc)
2862 return rc;
2863
2864 rc = put_entry(key, 1, len, fp);
2865 if (rc)
2866 return rc;
2867
2868 rc = ebitmap_write(&role->dominates, fp);
2869 if (rc)
2870 return rc;
2871
2872 rc = ebitmap_write(&role->types, fp);
2873 if (rc)
2874 return rc;
2875
2876 return 0;
2877}
2878
2879static int type_write(void *vkey, void *datum, void *ptr)
2880{
2881 char *key = vkey;
2882 struct type_datum *typdatum = datum;
2883 struct policy_data *pd = ptr;
2884 struct policydb *p = pd->p;
2885 void *fp = pd->fp;
2886 __le32 buf[4];
2887 int rc;
2888 size_t items, len;
2889
2890 len = strlen(key);
2891 items = 0;
2892 buf[items++] = cpu_to_le32(len);
2893 buf[items++] = cpu_to_le32(typdatum->value);
2894 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) {
2895 u32 properties = 0;
2896
2897 if (typdatum->primary)
2898 properties |= TYPEDATUM_PROPERTY_PRIMARY;
2899
2900 if (typdatum->attribute)
2901 properties |= TYPEDATUM_PROPERTY_ATTRIBUTE;
2902
2903 buf[items++] = cpu_to_le32(properties);
2904 buf[items++] = cpu_to_le32(typdatum->bounds);
2905 } else {
2906 buf[items++] = cpu_to_le32(typdatum->primary);
2907 }
2908 BUG_ON(items > (sizeof(buf) / sizeof(buf[0])));
2909 rc = put_entry(buf, sizeof(u32), items, fp);
2910 if (rc)
2911 return rc;
2912
2913 rc = put_entry(key, 1, len, fp);
2914 if (rc)
2915 return rc;
2916
2917 return 0;
2918}
2919
2920static int user_write(void *vkey, void *datum, void *ptr)
2921{
2922 char *key = vkey;
2923 struct user_datum *usrdatum = datum;
2924 struct policy_data *pd = ptr;
2925 struct policydb *p = pd->p;
2926 void *fp = pd->fp;
2927 __le32 buf[3];
2928 size_t items, len;
2929 int rc;
2930
2931 len = strlen(key);
2932 items = 0;
2933 buf[items++] = cpu_to_le32(len);
2934 buf[items++] = cpu_to_le32(usrdatum->value);
2935 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
2936 buf[items++] = cpu_to_le32(usrdatum->bounds);
2937 BUG_ON(items > (sizeof(buf) / sizeof(buf[0])));
2938 rc = put_entry(buf, sizeof(u32), items, fp);
2939 if (rc)
2940 return rc;
2941
2942 rc = put_entry(key, 1, len, fp);
2943 if (rc)
2944 return rc;
2945
2946 rc = ebitmap_write(&usrdatum->roles, fp);
2947 if (rc)
2948 return rc;
2949
2950 rc = mls_write_range_helper(&usrdatum->range, fp);
2951 if (rc)
2952 return rc;
2953
2954 rc = mls_write_level(&usrdatum->dfltlevel, fp);
2955 if (rc)
2956 return rc;
2957
2958 return 0;
2959}
2960
2961static int (*write_f[SYM_NUM]) (void *key, void *datum,
2962 void *datap) =
2963{
2964 common_write,
2965 class_write,
2966 role_write,
2967 type_write,
2968 user_write,
2969 cond_write_bool,
2970 sens_write,
2971 cat_write,
2972};
2973
2974static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
2975 void *fp)
2976{
2977 unsigned int i, j, rc;
2978 size_t nel, len;
2979 __le32 buf[3];
2980 u32 nodebuf[8];
2981 struct ocontext *c;
2982 for (i = 0; i < info->ocon_num; i++) {
2983 nel = 0;
2984 for (c = p->ocontexts[i]; c; c = c->next)
2985 nel++;
2986 buf[0] = cpu_to_le32(nel);
2987 rc = put_entry(buf, sizeof(u32), 1, fp);
2988 if (rc)
2989 return rc;
2990 for (c = p->ocontexts[i]; c; c = c->next) {
2991 switch (i) {
2992 case OCON_ISID:
2993 buf[0] = cpu_to_le32(c->sid[0]);
2994 rc = put_entry(buf, sizeof(u32), 1, fp);
2995 if (rc)
2996 return rc;
2997 rc = context_write(p, &c->context[0], fp);
2998 if (rc)
2999 return rc;
3000 break;
3001 case OCON_FS:
3002 case OCON_NETIF:
3003 len = strlen(c->u.name);
3004 buf[0] = cpu_to_le32(len);
3005 rc = put_entry(buf, sizeof(u32), 1, fp);
3006 if (rc)
3007 return rc;
3008 rc = put_entry(c->u.name, 1, len, fp);
3009 if (rc)
3010 return rc;
3011 rc = context_write(p, &c->context[0], fp);
3012 if (rc)
3013 return rc;
3014 rc = context_write(p, &c->context[1], fp);
3015 if (rc)
3016 return rc;
3017 break;
3018 case OCON_PORT:
3019 buf[0] = cpu_to_le32(c->u.port.protocol);
3020 buf[1] = cpu_to_le32(c->u.port.low_port);
3021 buf[2] = cpu_to_le32(c->u.port.high_port);
3022 rc = put_entry(buf, sizeof(u32), 3, fp);
3023 if (rc)
3024 return rc;
3025 rc = context_write(p, &c->context[0], fp);
3026 if (rc)
3027 return rc;
3028 break;
3029 case OCON_NODE:
3030 nodebuf[0] = c->u.node.addr; /* network order */
3031 nodebuf[1] = c->u.node.mask; /* network order */
3032 rc = put_entry(nodebuf, sizeof(u32), 2, fp);
3033 if (rc)
3034 return rc;
3035 rc = context_write(p, &c->context[0], fp);
3036 if (rc)
3037 return rc;
3038 break;
3039 case OCON_FSUSE:
3040 buf[0] = cpu_to_le32(c->v.behavior);
3041 len = strlen(c->u.name);
3042 buf[1] = cpu_to_le32(len);
3043 rc = put_entry(buf, sizeof(u32), 2, fp);
3044 if (rc)
3045 return rc;
3046 rc = put_entry(c->u.name, 1, len, fp);
3047 if (rc)
3048 return rc;
3049 rc = context_write(p, &c->context[0], fp);
3050 if (rc)
3051 return rc;
3052 break;
3053 case OCON_NODE6:
3054 for (j = 0; j < 4; j++)
3055 nodebuf[j] = c->u.node6.addr[j]; /* network order */
3056 for (j = 0; j < 4; j++)
3057 nodebuf[j + 4] = c->u.node6.mask[j]; /* network order */
3058 rc = put_entry(nodebuf, sizeof(u32), 8, fp);
3059 if (rc)
3060 return rc;
3061 rc = context_write(p, &c->context[0], fp);
3062 if (rc)
3063 return rc;
3064 break;
3065 }
3066 }
3067 }
3068 return 0;
3069}
3070
3071static int genfs_write(struct policydb *p, void *fp)
3072{
3073 struct genfs *genfs;
3074 struct ocontext *c;
3075 size_t len;
3076 __le32 buf[1];
3077 int rc;
3078
3079 len = 0;
3080 for (genfs = p->genfs; genfs; genfs = genfs->next)
3081 len++;
3082 buf[0] = cpu_to_le32(len);
3083 rc = put_entry(buf, sizeof(u32), 1, fp);
3084 if (rc)
3085 return rc;
3086 for (genfs = p->genfs; genfs; genfs = genfs->next) {
3087 len = strlen(genfs->fstype);
3088 buf[0] = cpu_to_le32(len);
3089 rc = put_entry(buf, sizeof(u32), 1, fp);
3090 if (rc)
3091 return rc;
3092 rc = put_entry(genfs->fstype, 1, len, fp);
3093 if (rc)
3094 return rc;
3095 len = 0;
3096 for (c = genfs->head; c; c = c->next)
3097 len++;
3098 buf[0] = cpu_to_le32(len);
3099 rc = put_entry(buf, sizeof(u32), 1, fp);
3100 if (rc)
3101 return rc;
3102 for (c = genfs->head; c; c = c->next) {
3103 len = strlen(c->u.name);
3104 buf[0] = cpu_to_le32(len);
3105 rc = put_entry(buf, sizeof(u32), 1, fp);
3106 if (rc)
3107 return rc;
3108 rc = put_entry(c->u.name, 1, len, fp);
3109 if (rc)
3110 return rc;
3111 buf[0] = cpu_to_le32(c->v.sclass);
3112 rc = put_entry(buf, sizeof(u32), 1, fp);
3113 if (rc)
3114 return rc;
3115 rc = context_write(p, &c->context[0], fp);
3116 if (rc)
3117 return rc;
3118 }
3119 }
3120 return 0;
3121}
3122
3123static int hashtab_cnt(void *key, void *data, void *ptr)
3124{
3125 int *cnt = ptr;
3126 *cnt = *cnt + 1;
3127
3128 return 0;
3129}
3130
3131static int range_write_helper(void *key, void *data, void *ptr)
3132{
3133 __le32 buf[2];
3134 struct range_trans *rt = key;
3135 struct mls_range *r = data;
3136 struct policy_data *pd = ptr;
3137 void *fp = pd->fp;
3138 struct policydb *p = pd->p;
3139 int rc;
3140
3141 buf[0] = cpu_to_le32(rt->source_type);
3142 buf[1] = cpu_to_le32(rt->target_type);
3143 rc = put_entry(buf, sizeof(u32), 2, fp);
3144 if (rc)
3145 return rc;
3146 if (p->policyvers >= POLICYDB_VERSION_RANGETRANS) {
3147 buf[0] = cpu_to_le32(rt->target_class);
3148 rc = put_entry(buf, sizeof(u32), 1, fp);
3149 if (rc)
3150 return rc;
3151 }
3152 rc = mls_write_range_helper(r, fp);
3153 if (rc)
3154 return rc;
3155
3156 return 0;
3157}
3158
3159static int range_write(struct policydb *p, void *fp)
3160{
3161 size_t nel;
3162 __le32 buf[1];
3163 int rc;
3164 struct policy_data pd;
3165
3166 pd.p = p;
3167 pd.fp = fp;
3168
3169 /* count the number of entries in the hashtab */
3170 nel = 0;
3171 rc = hashtab_map(p->range_tr, hashtab_cnt, &nel);
3172 if (rc)
3173 return rc;
3174
3175 buf[0] = cpu_to_le32(nel);
3176 rc = put_entry(buf, sizeof(u32), 1, fp);
3177 if (rc)
3178 return rc;
3179
3180 /* actually write all of the entries */
3181 rc = hashtab_map(p->range_tr, range_write_helper, &pd);
3182 if (rc)
3183 return rc;
3184
3185 return 0;
3186}
3187
3188static int filename_write_helper(void *key, void *data, void *ptr)
3189{
3190 __le32 buf[4];
3191 struct filename_trans *ft = key;
3192 struct filename_trans_datum *otype = data;
3193 void *fp = ptr;
3194 int rc;
3195 u32 len;
3196
3197 len = strlen(ft->name);
3198 buf[0] = cpu_to_le32(len);
3199 rc = put_entry(buf, sizeof(u32), 1, fp);
3200 if (rc)
3201 return rc;
3202
3203 rc = put_entry(ft->name, sizeof(char), len, fp);
3204 if (rc)
3205 return rc;
3206
3207 buf[0] = ft->stype;
3208 buf[1] = ft->ttype;
3209 buf[2] = ft->tclass;
3210 buf[3] = otype->otype;
3211
3212 rc = put_entry(buf, sizeof(u32), 4, fp);
3213 if (rc)
3214 return rc;
3215
3216 return 0;
3217}
3218
3219static int filename_trans_write(struct policydb *p, void *fp)
3220{
3221 u32 nel;
3222 __le32 buf[1];
3223 int rc;
3224
3225 if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
3226 return 0;
3227
3228 nel = 0;
3229 rc = hashtab_map(p->filename_trans, hashtab_cnt, &nel);
3230 if (rc)
3231 return rc;
3232
3233 buf[0] = cpu_to_le32(nel);
3234 rc = put_entry(buf, sizeof(u32), 1, fp);
3235 if (rc)
3236 return rc;
3237
3238 rc = hashtab_map(p->filename_trans, filename_write_helper, fp);
3239 if (rc)
3240 return rc;
3241
3242 return 0;
3243}
3244
3245/*
3246 * Write the configuration data in a policy database
3247 * structure to a policy database binary representation
3248 * file.
3249 */
3250int policydb_write(struct policydb *p, void *fp)
3251{
3252 unsigned int i, num_syms;
3253 int rc;
3254 __le32 buf[4];
3255 u32 config;
3256 size_t len;
3257 struct policydb_compat_info *info;
3258
3259 /*
3260 * refuse to write policy older than compressed avtab
3261 * to simplify the writer. There are other tests dropped
3262 * since we assume this throughout the writer code. Be
3263 * careful if you ever try to remove this restriction
3264 */
3265 if (p->policyvers < POLICYDB_VERSION_AVTAB) {
3266 printk(KERN_ERR "SELinux: refusing to write policy version %d."
3267 " Because it is less than version %d\n", p->policyvers,
3268 POLICYDB_VERSION_AVTAB);
3269 return -EINVAL;
3270 }
3271
3272 config = 0;
3273 if (p->mls_enabled)
3274 config |= POLICYDB_CONFIG_MLS;
3275
3276 if (p->reject_unknown)
3277 config |= REJECT_UNKNOWN;
3278 if (p->allow_unknown)
3279 config |= ALLOW_UNKNOWN;
3280
3281 /* Write the magic number and string identifiers. */
3282 buf[0] = cpu_to_le32(POLICYDB_MAGIC);
3283 len = strlen(POLICYDB_STRING);
3284 buf[1] = cpu_to_le32(len);
3285 rc = put_entry(buf, sizeof(u32), 2, fp);
3286 if (rc)
3287 return rc;
3288 rc = put_entry(POLICYDB_STRING, 1, len, fp);
3289 if (rc)
3290 return rc;
3291
3292 /* Write the version, config, and table sizes. */
3293 info = policydb_lookup_compat(p->policyvers);
3294 if (!info) {
3295 printk(KERN_ERR "SELinux: compatibility lookup failed for policy "
3296 "version %d", p->policyvers);
3297 return -EINVAL;
3298 }
3299
3300 buf[0] = cpu_to_le32(p->policyvers);
3301 buf[1] = cpu_to_le32(config);
3302 buf[2] = cpu_to_le32(info->sym_num);
3303 buf[3] = cpu_to_le32(info->ocon_num);
3304
3305 rc = put_entry(buf, sizeof(u32), 4, fp);
3306 if (rc)
3307 return rc;
3308
3309 if (p->policyvers >= POLICYDB_VERSION_POLCAP) {
3310 rc = ebitmap_write(&p->policycaps, fp);
3311 if (rc)
3312 return rc;
3313 }
3314
3315 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE) {
3316 rc = ebitmap_write(&p->permissive_map, fp);
3317 if (rc)
3318 return rc;
3319 }
3320
3321 num_syms = info->sym_num;
3322 for (i = 0; i < num_syms; i++) {
3323 struct policy_data pd;
3324
3325 pd.fp = fp;
3326 pd.p = p;
3327
3328 buf[0] = cpu_to_le32(p->symtab[i].nprim);
3329 buf[1] = cpu_to_le32(p->symtab[i].table->nel);
3330
3331 rc = put_entry(buf, sizeof(u32), 2, fp);
3332 if (rc)
3333 return rc;
3334 rc = hashtab_map(p->symtab[i].table, write_f[i], &pd);
3335 if (rc)
3336 return rc;
3337 }
3338
3339 rc = avtab_write(p, &p->te_avtab, fp);
3340 if (rc)
3341 return rc;
3342
3343 rc = cond_write_list(p, p->cond_list, fp);
3344 if (rc)
3345 return rc;
3346
3347 rc = role_trans_write(p, fp);
3348 if (rc)
3349 return rc;
3350
3351 rc = role_allow_write(p->role_allow, fp);
3352 if (rc)
3353 return rc;
3354
3355 rc = filename_trans_write(p, fp);
3356 if (rc)
3357 return rc;
3358
3359 rc = ocontext_write(p, info, fp);
3360 if (rc)
3361 return rc;
3362
3363 rc = genfs_write(p, fp);
3364 if (rc)
3365 return rc;
3366
3367 rc = range_write(p, fp);
3368 if (rc)
3369 return rc;
3370
3371 for (i = 0; i < p->p_types.nprim; i++) {
3372 struct ebitmap *e = flex_array_get(p->type_attr_map_array, i);
3373
3374 BUG_ON(!e);
3375 rc = ebitmap_write(e, fp);
3376 if (rc)
3377 return rc;
3378 }
3379
3380 return 0;
3381}
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 310e94442cb8..b846c0387180 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -72,11 +72,23 @@ struct role_datum {
72 72
73struct role_trans { 73struct role_trans {
74 u32 role; /* current role */ 74 u32 role; /* current role */
75 u32 type; /* program executable type */ 75 u32 type; /* program executable type, or new object type */
76 u32 tclass; /* process class, or new object class */
76 u32 new_role; /* new role */ 77 u32 new_role; /* new role */
77 struct role_trans *next; 78 struct role_trans *next;
78}; 79};
79 80
81struct filename_trans {
82 u32 stype; /* current process */
83 u32 ttype; /* parent dir context */
84 u16 tclass; /* class of new object */
85 const char *name; /* last path component */
86};
87
88struct filename_trans_datum {
89 u32 otype; /* expected of new object */
90};
91
80struct role_allow { 92struct role_allow {
81 u32 role; /* current role */ 93 u32 role; /* current role */
82 u32 new_role; /* new role */ 94 u32 new_role; /* new role */
@@ -203,21 +215,13 @@ struct policydb {
203#define p_cats symtab[SYM_CATS] 215#define p_cats symtab[SYM_CATS]
204 216
205 /* symbol names indexed by (value - 1) */ 217 /* symbol names indexed by (value - 1) */
206 char **sym_val_to_name[SYM_NUM]; 218 struct flex_array *sym_val_to_name[SYM_NUM];
207#define p_common_val_to_name sym_val_to_name[SYM_COMMONS]
208#define p_class_val_to_name sym_val_to_name[SYM_CLASSES]
209#define p_role_val_to_name sym_val_to_name[SYM_ROLES]
210#define p_type_val_to_name sym_val_to_name[SYM_TYPES]
211#define p_user_val_to_name sym_val_to_name[SYM_USERS]
212#define p_bool_val_to_name sym_val_to_name[SYM_BOOLS]
213#define p_sens_val_to_name sym_val_to_name[SYM_LEVELS]
214#define p_cat_val_to_name sym_val_to_name[SYM_CATS]
215 219
216 /* class, role, and user attributes indexed by (value - 1) */ 220 /* class, role, and user attributes indexed by (value - 1) */
217 struct class_datum **class_val_to_struct; 221 struct class_datum **class_val_to_struct;
218 struct role_datum **role_val_to_struct; 222 struct role_datum **role_val_to_struct;
219 struct user_datum **user_val_to_struct; 223 struct user_datum **user_val_to_struct;
220 struct type_datum **type_val_to_struct; 224 struct flex_array *type_val_to_struct_array;
221 225
222 /* type enforcement access vectors and transitions */ 226 /* type enforcement access vectors and transitions */
223 struct avtab te_avtab; 227 struct avtab te_avtab;
@@ -225,6 +229,12 @@ struct policydb {
225 /* role transitions */ 229 /* role transitions */
226 struct role_trans *role_tr; 230 struct role_trans *role_tr;
227 231
232 /* file transitions with the last path component */
233 /* quickly exclude lookups when parent ttype has no rules */
234 struct ebitmap filename_trans_ttypes;
235 /* actual set of filename_trans rules */
236 struct hashtab *filename_trans;
237
228 /* bools indexed by (value - 1) */ 238 /* bools indexed by (value - 1) */
229 struct cond_bool_datum **bool_val_to_struct; 239 struct cond_bool_datum **bool_val_to_struct;
230 /* type enforcement conditional access vectors and transitions */ 240 /* type enforcement conditional access vectors and transitions */
@@ -254,6 +264,9 @@ struct policydb {
254 264
255 struct ebitmap permissive_map; 265 struct ebitmap permissive_map;
256 266
267 /* length of this policy when it was loaded */
268 size_t len;
269
257 unsigned int policyvers; 270 unsigned int policyvers;
258 271
259 unsigned int reject_unknown : 1; 272 unsigned int reject_unknown : 1;
@@ -270,6 +283,7 @@ extern int policydb_class_isvalid(struct policydb *p, unsigned int class);
270extern int policydb_type_isvalid(struct policydb *p, unsigned int type); 283extern int policydb_type_isvalid(struct policydb *p, unsigned int type);
271extern int policydb_role_isvalid(struct policydb *p, unsigned int role); 284extern int policydb_role_isvalid(struct policydb *p, unsigned int role);
272extern int policydb_read(struct policydb *p, void *fp); 285extern int policydb_read(struct policydb *p, void *fp);
286extern int policydb_write(struct policydb *p, void *fp);
273 287
274#define PERM_SYMTAB_SIZE 32 288#define PERM_SYMTAB_SIZE 32
275 289
@@ -290,6 +304,11 @@ struct policy_file {
290 size_t len; 304 size_t len;
291}; 305};
292 306
307struct policy_data {
308 struct policydb *p;
309 void *fp;
310};
311
293static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes) 312static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
294{ 313{
295 if (bytes > fp->len) 314 if (bytes > fp->len)
@@ -301,6 +320,24 @@ static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
301 return 0; 320 return 0;
302} 321}
303 322
323static inline int put_entry(const void *buf, size_t bytes, int num, struct policy_file *fp)
324{
325 size_t len = bytes * num;
326
327 memcpy(fp->data, buf, len);
328 fp->data += len;
329 fp->len -= len;
330
331 return 0;
332}
333
334static inline char *sym_name(struct policydb *p, unsigned int sym_num, unsigned int element_nr)
335{
336 struct flex_array *fa = p->sym_val_to_name[sym_num];
337
338 return flex_array_get_ptr(fa, element_nr);
339}
340
304extern u16 string_to_security_class(struct policydb *p, const char *name); 341extern u16 string_to_security_class(struct policydb *p, const char *name);
305extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name); 342extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name);
306 343
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 9ea2feca3cd4..973e00e34fa9 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -51,6 +51,7 @@
51#include <linux/mutex.h> 51#include <linux/mutex.h>
52#include <linux/selinux.h> 52#include <linux/selinux.h>
53#include <linux/flex_array.h> 53#include <linux/flex_array.h>
54#include <linux/vmalloc.h>
54#include <net/netlabel.h> 55#include <net/netlabel.h>
55 56
56#include "flask.h" 57#include "flask.h"
@@ -200,6 +201,21 @@ static u16 unmap_class(u16 tclass)
200 return tclass; 201 return tclass;
201} 202}
202 203
204/*
205 * Get kernel value for class from its policy value
206 */
207static u16 map_class(u16 pol_value)
208{
209 u16 i;
210
211 for (i = 1; i < current_mapping_size; i++) {
212 if (current_mapping[i].value == pol_value)
213 return i;
214 }
215
216 return SECCLASS_NULL;
217}
218
203static void map_decision(u16 tclass, struct av_decision *avd, 219static void map_decision(u16 tclass, struct av_decision *avd,
204 int allow_unknown) 220 int allow_unknown)
205{ 221{
@@ -463,7 +479,7 @@ static void security_dump_masked_av(struct context *scontext,
463 if (!permissions) 479 if (!permissions)
464 return; 480 return;
465 481
466 tclass_name = policydb.p_class_val_to_name[tclass - 1]; 482 tclass_name = sym_name(&policydb, SYM_CLASSES, tclass - 1);
467 tclass_dat = policydb.class_val_to_struct[tclass - 1]; 483 tclass_dat = policydb.class_val_to_struct[tclass - 1];
468 common_dat = tclass_dat->comdatum; 484 common_dat = tclass_dat->comdatum;
469 485
@@ -529,12 +545,18 @@ static void type_attribute_bounds_av(struct context *scontext,
529 struct context lo_scontext; 545 struct context lo_scontext;
530 struct context lo_tcontext; 546 struct context lo_tcontext;
531 struct av_decision lo_avd; 547 struct av_decision lo_avd;
532 struct type_datum *source 548 struct type_datum *source;
533 = policydb.type_val_to_struct[scontext->type - 1]; 549 struct type_datum *target;
534 struct type_datum *target
535 = policydb.type_val_to_struct[tcontext->type - 1];
536 u32 masked = 0; 550 u32 masked = 0;
537 551
552 source = flex_array_get_ptr(policydb.type_val_to_struct_array,
553 scontext->type - 1);
554 BUG_ON(!source);
555
556 target = flex_array_get_ptr(policydb.type_val_to_struct_array,
557 tcontext->type - 1);
558 BUG_ON(!target);
559
538 if (source->bounds) { 560 if (source->bounds) {
539 memset(&lo_avd, 0, sizeof(lo_avd)); 561 memset(&lo_avd, 0, sizeof(lo_avd));
540 562
@@ -700,16 +722,16 @@ static int security_validtrans_handle_fail(struct context *ocontext,
700 char *o = NULL, *n = NULL, *t = NULL; 722 char *o = NULL, *n = NULL, *t = NULL;
701 u32 olen, nlen, tlen; 723 u32 olen, nlen, tlen;
702 724
703 if (context_struct_to_string(ocontext, &o, &olen) < 0) 725 if (context_struct_to_string(ocontext, &o, &olen))
704 goto out; 726 goto out;
705 if (context_struct_to_string(ncontext, &n, &nlen) < 0) 727 if (context_struct_to_string(ncontext, &n, &nlen))
706 goto out; 728 goto out;
707 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 729 if (context_struct_to_string(tcontext, &t, &tlen))
708 goto out; 730 goto out;
709 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 731 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
710 "security_validate_transition: denied for" 732 "security_validate_transition: denied for"
711 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", 733 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
712 o, n, t, policydb.p_class_val_to_name[tclass-1]); 734 o, n, t, sym_name(&policydb, SYM_CLASSES, tclass-1));
713out: 735out:
714 kfree(o); 736 kfree(o);
715 kfree(n); 737 kfree(n);
@@ -800,10 +822,11 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
800 struct context *old_context, *new_context; 822 struct context *old_context, *new_context;
801 struct type_datum *type; 823 struct type_datum *type;
802 int index; 824 int index;
803 int rc = -EINVAL; 825 int rc;
804 826
805 read_lock(&policy_rwlock); 827 read_lock(&policy_rwlock);
806 828
829 rc = -EINVAL;
807 old_context = sidtab_search(&sidtab, old_sid); 830 old_context = sidtab_search(&sidtab, old_sid);
808 if (!old_context) { 831 if (!old_context) {
809 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", 832 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
@@ -811,6 +834,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
811 goto out; 834 goto out;
812 } 835 }
813 836
837 rc = -EINVAL;
814 new_context = sidtab_search(&sidtab, new_sid); 838 new_context = sidtab_search(&sidtab, new_sid);
815 if (!new_context) { 839 if (!new_context) {
816 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", 840 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
@@ -818,28 +842,27 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
818 goto out; 842 goto out;
819 } 843 }
820 844
845 rc = 0;
821 /* type/domain unchanged */ 846 /* type/domain unchanged */
822 if (old_context->type == new_context->type) { 847 if (old_context->type == new_context->type)
823 rc = 0;
824 goto out; 848 goto out;
825 }
826 849
827 index = new_context->type; 850 index = new_context->type;
828 while (true) { 851 while (true) {
829 type = policydb.type_val_to_struct[index - 1]; 852 type = flex_array_get_ptr(policydb.type_val_to_struct_array,
853 index - 1);
830 BUG_ON(!type); 854 BUG_ON(!type);
831 855
832 /* not bounded anymore */ 856 /* not bounded anymore */
833 if (!type->bounds) { 857 rc = -EPERM;
834 rc = -EPERM; 858 if (!type->bounds)
835 break; 859 break;
836 }
837 860
838 /* @newsid is bounded by @oldsid */ 861 /* @newsid is bounded by @oldsid */
839 if (type->bounds == old_context->type) { 862 rc = 0;
840 rc = 0; 863 if (type->bounds == old_context->type)
841 break; 864 break;
842 } 865
843 index = type->bounds; 866 index = type->bounds;
844 } 867 }
845 868
@@ -991,7 +1014,8 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
991{ 1014{
992 char *scontextp; 1015 char *scontextp;
993 1016
994 *scontext = NULL; 1017 if (scontext)
1018 *scontext = NULL;
995 *scontext_len = 0; 1019 *scontext_len = 0;
996 1020
997 if (context->len) { 1021 if (context->len) {
@@ -1003,11 +1027,14 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
1003 } 1027 }
1004 1028
1005 /* Compute the size of the context. */ 1029 /* Compute the size of the context. */
1006 *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1; 1030 *scontext_len += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) + 1;
1007 *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1; 1031 *scontext_len += strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) + 1;
1008 *scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1; 1032 *scontext_len += strlen(sym_name(&policydb, SYM_TYPES, context->type - 1)) + 1;
1009 *scontext_len += mls_compute_context_len(context); 1033 *scontext_len += mls_compute_context_len(context);
1010 1034
1035 if (!scontext)
1036 return 0;
1037
1011 /* Allocate space for the context; caller must free this space. */ 1038 /* Allocate space for the context; caller must free this space. */
1012 scontextp = kmalloc(*scontext_len, GFP_ATOMIC); 1039 scontextp = kmalloc(*scontext_len, GFP_ATOMIC);
1013 if (!scontextp) 1040 if (!scontextp)
@@ -1018,12 +1045,12 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
1018 * Copy the user name, role name and type name into the context. 1045 * Copy the user name, role name and type name into the context.
1019 */ 1046 */
1020 sprintf(scontextp, "%s:%s:%s", 1047 sprintf(scontextp, "%s:%s:%s",
1021 policydb.p_user_val_to_name[context->user - 1], 1048 sym_name(&policydb, SYM_USERS, context->user - 1),
1022 policydb.p_role_val_to_name[context->role - 1], 1049 sym_name(&policydb, SYM_ROLES, context->role - 1),
1023 policydb.p_type_val_to_name[context->type - 1]); 1050 sym_name(&policydb, SYM_TYPES, context->type - 1));
1024 scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1051 scontextp += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) +
1025 1 + strlen(policydb.p_role_val_to_name[context->role - 1]) + 1052 1 + strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) +
1026 1 + strlen(policydb.p_type_val_to_name[context->type - 1]); 1053 1 + strlen(sym_name(&policydb, SYM_TYPES, context->type - 1));
1027 1054
1028 mls_sid_to_context(context, &scontextp); 1055 mls_sid_to_context(context, &scontextp);
1029 1056
@@ -1047,7 +1074,8 @@ static int security_sid_to_context_core(u32 sid, char **scontext,
1047 struct context *context; 1074 struct context *context;
1048 int rc = 0; 1075 int rc = 0;
1049 1076
1050 *scontext = NULL; 1077 if (scontext)
1078 *scontext = NULL;
1051 *scontext_len = 0; 1079 *scontext_len = 0;
1052 1080
1053 if (!ss_initialized) { 1081 if (!ss_initialized) {
@@ -1055,6 +1083,8 @@ static int security_sid_to_context_core(u32 sid, char **scontext,
1055 char *scontextp; 1083 char *scontextp;
1056 1084
1057 *scontext_len = strlen(initial_sid_to_string[sid]) + 1; 1085 *scontext_len = strlen(initial_sid_to_string[sid]) + 1;
1086 if (!scontext)
1087 goto out;
1058 scontextp = kmalloc(*scontext_len, GFP_ATOMIC); 1088 scontextp = kmalloc(*scontext_len, GFP_ATOMIC);
1059 if (!scontextp) { 1089 if (!scontextp) {
1060 rc = -ENOMEM; 1090 rc = -ENOMEM;
@@ -1179,16 +1209,13 @@ static int string_to_context_struct(struct policydb *pol,
1179 if (rc) 1209 if (rc)
1180 goto out; 1210 goto out;
1181 1211
1182 if ((p - scontext) < scontext_len) { 1212 rc = -EINVAL;
1183 rc = -EINVAL; 1213 if ((p - scontext) < scontext_len)
1184 goto out; 1214 goto out;
1185 }
1186 1215
1187 /* Check the validity of the new context. */ 1216 /* Check the validity of the new context. */
1188 if (!policydb_context_isvalid(pol, ctx)) { 1217 if (!policydb_context_isvalid(pol, ctx))
1189 rc = -EINVAL;
1190 goto out; 1218 goto out;
1191 }
1192 rc = 0; 1219 rc = 0;
1193out: 1220out:
1194 if (rc) 1221 if (rc)
@@ -1227,27 +1254,26 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
1227 1254
1228 if (force) { 1255 if (force) {
1229 /* Save another copy for storing in uninterpreted form */ 1256 /* Save another copy for storing in uninterpreted form */
1257 rc = -ENOMEM;
1230 str = kstrdup(scontext2, gfp_flags); 1258 str = kstrdup(scontext2, gfp_flags);
1231 if (!str) { 1259 if (!str)
1232 kfree(scontext2); 1260 goto out;
1233 return -ENOMEM;
1234 }
1235 } 1261 }
1236 1262
1237 read_lock(&policy_rwlock); 1263 read_lock(&policy_rwlock);
1238 rc = string_to_context_struct(&policydb, &sidtab, 1264 rc = string_to_context_struct(&policydb, &sidtab, scontext2,
1239 scontext2, scontext_len, 1265 scontext_len, &context, def_sid);
1240 &context, def_sid);
1241 if (rc == -EINVAL && force) { 1266 if (rc == -EINVAL && force) {
1242 context.str = str; 1267 context.str = str;
1243 context.len = scontext_len; 1268 context.len = scontext_len;
1244 str = NULL; 1269 str = NULL;
1245 } else if (rc) 1270 } else if (rc)
1246 goto out; 1271 goto out_unlock;
1247 rc = sidtab_context_to_sid(&sidtab, &context, sid); 1272 rc = sidtab_context_to_sid(&sidtab, &context, sid);
1248 context_destroy(&context); 1273 context_destroy(&context);
1249out: 1274out_unlock:
1250 read_unlock(&policy_rwlock); 1275 read_unlock(&policy_rwlock);
1276out:
1251 kfree(scontext2); 1277 kfree(scontext2);
1252 kfree(str); 1278 kfree(str);
1253 return rc; 1279 return rc;
@@ -1311,18 +1337,18 @@ static int compute_sid_handle_invalid_context(
1311 char *s = NULL, *t = NULL, *n = NULL; 1337 char *s = NULL, *t = NULL, *n = NULL;
1312 u32 slen, tlen, nlen; 1338 u32 slen, tlen, nlen;
1313 1339
1314 if (context_struct_to_string(scontext, &s, &slen) < 0) 1340 if (context_struct_to_string(scontext, &s, &slen))
1315 goto out; 1341 goto out;
1316 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 1342 if (context_struct_to_string(tcontext, &t, &tlen))
1317 goto out; 1343 goto out;
1318 if (context_struct_to_string(newcontext, &n, &nlen) < 0) 1344 if (context_struct_to_string(newcontext, &n, &nlen))
1319 goto out; 1345 goto out;
1320 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 1346 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1321 "security_compute_sid: invalid context %s" 1347 "security_compute_sid: invalid context %s"
1322 " for scontext=%s" 1348 " for scontext=%s"
1323 " tcontext=%s" 1349 " tcontext=%s"
1324 " tclass=%s", 1350 " tclass=%s",
1325 n, s, t, policydb.p_class_val_to_name[tclass-1]); 1351 n, s, t, sym_name(&policydb, SYM_CLASSES, tclass-1));
1326out: 1352out:
1327 kfree(s); 1353 kfree(s);
1328 kfree(t); 1354 kfree(t);
@@ -1332,10 +1358,36 @@ out:
1332 return -EACCES; 1358 return -EACCES;
1333} 1359}
1334 1360
1361static void filename_compute_type(struct policydb *p, struct context *newcontext,
1362 u32 stype, u32 ttype, u16 tclass,
1363 const char *objname)
1364{
1365 struct filename_trans ft;
1366 struct filename_trans_datum *otype;
1367
1368 /*
1369 * Most filename trans rules are going to live in specific directories
1370 * like /dev or /var/run. This bitmap will quickly skip rule searches
1371 * if the ttype does not contain any rules.
1372 */
1373 if (!ebitmap_get_bit(&p->filename_trans_ttypes, ttype))
1374 return;
1375
1376 ft.stype = stype;
1377 ft.ttype = ttype;
1378 ft.tclass = tclass;
1379 ft.name = objname;
1380
1381 otype = hashtab_search(p->filename_trans, &ft);
1382 if (otype)
1383 newcontext->type = otype->otype;
1384}
1385
1335static int security_compute_sid(u32 ssid, 1386static int security_compute_sid(u32 ssid,
1336 u32 tsid, 1387 u32 tsid,
1337 u16 orig_tclass, 1388 u16 orig_tclass,
1338 u32 specified, 1389 u32 specified,
1390 const char *objname,
1339 u32 *out_sid, 1391 u32 *out_sid,
1340 bool kern) 1392 bool kern)
1341{ 1393{
@@ -1346,6 +1398,7 @@ static int security_compute_sid(u32 ssid,
1346 struct avtab_node *node; 1398 struct avtab_node *node;
1347 u16 tclass; 1399 u16 tclass;
1348 int rc = 0; 1400 int rc = 0;
1401 bool sock;
1349 1402
1350 if (!ss_initialized) { 1403 if (!ss_initialized) {
1351 switch (orig_tclass) { 1404 switch (orig_tclass) {
@@ -1363,10 +1416,13 @@ static int security_compute_sid(u32 ssid,
1363 1416
1364 read_lock(&policy_rwlock); 1417 read_lock(&policy_rwlock);
1365 1418
1366 if (kern) 1419 if (kern) {
1367 tclass = unmap_class(orig_tclass); 1420 tclass = unmap_class(orig_tclass);
1368 else 1421 sock = security_is_socket_class(orig_tclass);
1422 } else {
1369 tclass = orig_tclass; 1423 tclass = orig_tclass;
1424 sock = security_is_socket_class(map_class(tclass));
1425 }
1370 1426
1371 scontext = sidtab_search(&sidtab, ssid); 1427 scontext = sidtab_search(&sidtab, ssid);
1372 if (!scontext) { 1428 if (!scontext) {
@@ -1397,7 +1453,7 @@ static int security_compute_sid(u32 ssid,
1397 } 1453 }
1398 1454
1399 /* Set the role and type to default values. */ 1455 /* Set the role and type to default values. */
1400 if (tclass == policydb.process_class) { 1456 if ((tclass == policydb.process_class) || (sock == true)) {
1401 /* Use the current role and type of process. */ 1457 /* Use the current role and type of process. */
1402 newcontext.role = scontext->role; 1458 newcontext.role = scontext->role;
1403 newcontext.type = scontext->type; 1459 newcontext.type = scontext->type;
@@ -1431,25 +1487,29 @@ static int security_compute_sid(u32 ssid,
1431 newcontext.type = avdatum->data; 1487 newcontext.type = avdatum->data;
1432 } 1488 }
1433 1489
1490 /* if we have a objname this is a file trans check so check those rules */
1491 if (objname)
1492 filename_compute_type(&policydb, &newcontext, scontext->type,
1493 tcontext->type, tclass, objname);
1494
1434 /* Check for class-specific changes. */ 1495 /* Check for class-specific changes. */
1435 if (tclass == policydb.process_class) { 1496 if (specified & AVTAB_TRANSITION) {
1436 if (specified & AVTAB_TRANSITION) { 1497 /* Look for a role transition rule. */
1437 /* Look for a role transition rule. */ 1498 for (roletr = policydb.role_tr; roletr; roletr = roletr->next) {
1438 for (roletr = policydb.role_tr; roletr; 1499 if ((roletr->role == scontext->role) &&
1439 roletr = roletr->next) { 1500 (roletr->type == tcontext->type) &&
1440 if (roletr->role == scontext->role && 1501 (roletr->tclass == tclass)) {
1441 roletr->type == tcontext->type) { 1502 /* Use the role transition rule. */
1442 /* Use the role transition rule. */ 1503 newcontext.role = roletr->new_role;
1443 newcontext.role = roletr->new_role; 1504 break;
1444 break;
1445 }
1446 } 1505 }
1447 } 1506 }
1448 } 1507 }
1449 1508
1450 /* Set the MLS attributes. 1509 /* Set the MLS attributes.
1451 This is done last because it may allocate memory. */ 1510 This is done last because it may allocate memory. */
1452 rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext); 1511 rc = mls_compute_sid(scontext, tcontext, tclass, specified,
1512 &newcontext, sock);
1453 if (rc) 1513 if (rc)
1454 goto out_unlock; 1514 goto out_unlock;
1455 1515
@@ -1484,22 +1544,18 @@ out:
1484 * if insufficient memory is available, or %0 if the new SID was 1544 * if insufficient memory is available, or %0 if the new SID was
1485 * computed successfully. 1545 * computed successfully.
1486 */ 1546 */
1487int security_transition_sid(u32 ssid, 1547int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
1488 u32 tsid, 1548 const struct qstr *qstr, u32 *out_sid)
1489 u16 tclass,
1490 u32 *out_sid)
1491{ 1549{
1492 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, 1550 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1493 out_sid, true); 1551 qstr ? qstr->name : NULL, out_sid, true);
1494} 1552}
1495 1553
1496int security_transition_sid_user(u32 ssid, 1554int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
1497 u32 tsid, 1555 const char *objname, u32 *out_sid)
1498 u16 tclass,
1499 u32 *out_sid)
1500{ 1556{
1501 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, 1557 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1502 out_sid, false); 1558 objname, out_sid, false);
1503} 1559}
1504 1560
1505/** 1561/**
@@ -1520,8 +1576,8 @@ int security_member_sid(u32 ssid,
1520 u16 tclass, 1576 u16 tclass,
1521 u32 *out_sid) 1577 u32 *out_sid)
1522{ 1578{
1523 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid, 1579 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, NULL,
1524 false); 1580 out_sid, false);
1525} 1581}
1526 1582
1527/** 1583/**
@@ -1542,8 +1598,8 @@ int security_change_sid(u32 ssid,
1542 u16 tclass, 1598 u16 tclass,
1543 u32 *out_sid) 1599 u32 *out_sid)
1544{ 1600{
1545 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid, 1601 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, NULL,
1546 false); 1602 out_sid, false);
1547} 1603}
1548 1604
1549/* Clone the SID into the new SID table. */ 1605/* Clone the SID into the new SID table. */
@@ -1561,22 +1617,17 @@ static int clone_sid(u32 sid,
1561 1617
1562static inline int convert_context_handle_invalid_context(struct context *context) 1618static inline int convert_context_handle_invalid_context(struct context *context)
1563{ 1619{
1564 int rc = 0; 1620 char *s;
1621 u32 len;
1565 1622
1566 if (selinux_enforcing) { 1623 if (selinux_enforcing)
1567 rc = -EINVAL; 1624 return -EINVAL;
1568 } else { 1625
1569 char *s; 1626 if (!context_struct_to_string(context, &s, &len)) {
1570 u32 len; 1627 printk(KERN_WARNING "SELinux: Context %s would be invalid if enforcing\n", s);
1571 1628 kfree(s);
1572 if (!context_struct_to_string(context, &s, &len)) {
1573 printk(KERN_WARNING
1574 "SELinux: Context %s would be invalid if enforcing\n",
1575 s);
1576 kfree(s);
1577 }
1578 } 1629 }
1579 return rc; 1630 return 0;
1580} 1631}
1581 1632
1582struct convert_context_args { 1633struct convert_context_args {
@@ -1613,17 +1664,17 @@ static int convert_context(u32 key,
1613 1664
1614 if (c->str) { 1665 if (c->str) {
1615 struct context ctx; 1666 struct context ctx;
1667
1668 rc = -ENOMEM;
1616 s = kstrdup(c->str, GFP_KERNEL); 1669 s = kstrdup(c->str, GFP_KERNEL);
1617 if (!s) { 1670 if (!s)
1618 rc = -ENOMEM;
1619 goto out; 1671 goto out;
1620 } 1672
1621 rc = string_to_context_struct(args->newp, NULL, s, 1673 rc = string_to_context_struct(args->newp, NULL, s,
1622 c->len, &ctx, SECSID_NULL); 1674 c->len, &ctx, SECSID_NULL);
1623 kfree(s); 1675 kfree(s);
1624 if (!rc) { 1676 if (!rc) {
1625 printk(KERN_INFO 1677 printk(KERN_INFO "SELinux: Context %s became valid (mapped).\n",
1626 "SELinux: Context %s became valid (mapped).\n",
1627 c->str); 1678 c->str);
1628 /* Replace string with mapped representation. */ 1679 /* Replace string with mapped representation. */
1629 kfree(c->str); 1680 kfree(c->str);
@@ -1635,8 +1686,7 @@ static int convert_context(u32 key,
1635 goto out; 1686 goto out;
1636 } else { 1687 } else {
1637 /* Other error condition, e.g. ENOMEM. */ 1688 /* Other error condition, e.g. ENOMEM. */
1638 printk(KERN_ERR 1689 printk(KERN_ERR "SELinux: Unable to map context %s, rc = %d.\n",
1639 "SELinux: Unable to map context %s, rc = %d.\n",
1640 c->str, -rc); 1690 c->str, -rc);
1641 goto out; 1691 goto out;
1642 } 1692 }
@@ -1646,25 +1696,26 @@ static int convert_context(u32 key,
1646 if (rc) 1696 if (rc)
1647 goto out; 1697 goto out;
1648 1698
1649 rc = -EINVAL;
1650
1651 /* Convert the user. */ 1699 /* Convert the user. */
1700 rc = -EINVAL;
1652 usrdatum = hashtab_search(args->newp->p_users.table, 1701 usrdatum = hashtab_search(args->newp->p_users.table,
1653 args->oldp->p_user_val_to_name[c->user - 1]); 1702 sym_name(args->oldp, SYM_USERS, c->user - 1));
1654 if (!usrdatum) 1703 if (!usrdatum)
1655 goto bad; 1704 goto bad;
1656 c->user = usrdatum->value; 1705 c->user = usrdatum->value;
1657 1706
1658 /* Convert the role. */ 1707 /* Convert the role. */
1708 rc = -EINVAL;
1659 role = hashtab_search(args->newp->p_roles.table, 1709 role = hashtab_search(args->newp->p_roles.table,
1660 args->oldp->p_role_val_to_name[c->role - 1]); 1710 sym_name(args->oldp, SYM_ROLES, c->role - 1));
1661 if (!role) 1711 if (!role)
1662 goto bad; 1712 goto bad;
1663 c->role = role->value; 1713 c->role = role->value;
1664 1714
1665 /* Convert the type. */ 1715 /* Convert the type. */
1716 rc = -EINVAL;
1666 typdatum = hashtab_search(args->newp->p_types.table, 1717 typdatum = hashtab_search(args->newp->p_types.table,
1667 args->oldp->p_type_val_to_name[c->type - 1]); 1718 sym_name(args->oldp, SYM_TYPES, c->type - 1));
1668 if (!typdatum) 1719 if (!typdatum)
1669 goto bad; 1720 goto bad;
1670 c->type = typdatum->value; 1721 c->type = typdatum->value;
@@ -1692,6 +1743,7 @@ static int convert_context(u32 key,
1692 oc = args->newp->ocontexts[OCON_ISID]; 1743 oc = args->newp->ocontexts[OCON_ISID];
1693 while (oc && oc->sid[0] != SECINITSID_UNLABELED) 1744 while (oc && oc->sid[0] != SECINITSID_UNLABELED)
1694 oc = oc->next; 1745 oc = oc->next;
1746 rc = -EINVAL;
1695 if (!oc) { 1747 if (!oc) {
1696 printk(KERN_ERR "SELinux: unable to look up" 1748 printk(KERN_ERR "SELinux: unable to look up"
1697 " the initial SIDs list\n"); 1749 " the initial SIDs list\n");
@@ -1711,19 +1763,20 @@ static int convert_context(u32 key,
1711 } 1763 }
1712 1764
1713 context_destroy(&oldc); 1765 context_destroy(&oldc);
1766
1714 rc = 0; 1767 rc = 0;
1715out: 1768out:
1716 return rc; 1769 return rc;
1717bad: 1770bad:
1718 /* Map old representation to string and save it. */ 1771 /* Map old representation to string and save it. */
1719 if (context_struct_to_string(&oldc, &s, &len)) 1772 rc = context_struct_to_string(&oldc, &s, &len);
1720 return -ENOMEM; 1773 if (rc)
1774 return rc;
1721 context_destroy(&oldc); 1775 context_destroy(&oldc);
1722 context_destroy(c); 1776 context_destroy(c);
1723 c->str = s; 1777 c->str = s;
1724 c->len = len; 1778 c->len = len;
1725 printk(KERN_INFO 1779 printk(KERN_INFO "SELinux: Context %s became invalid (unmapped).\n",
1726 "SELinux: Context %s became invalid (unmapped).\n",
1727 c->str); 1780 c->str);
1728 rc = 0; 1781 rc = 0;
1729 goto out; 1782 goto out;
@@ -1769,6 +1822,7 @@ int security_load_policy(void *data, size_t len)
1769 return rc; 1822 return rc;
1770 } 1823 }
1771 1824
1825 policydb.len = len;
1772 rc = selinux_set_mapping(&policydb, secclass_map, 1826 rc = selinux_set_mapping(&policydb, secclass_map,
1773 &current_mapping, 1827 &current_mapping,
1774 &current_mapping_size); 1828 &current_mapping_size);
@@ -1791,6 +1845,7 @@ int security_load_policy(void *data, size_t len)
1791 selinux_complete_init(); 1845 selinux_complete_init();
1792 avc_ss_reset(seqno); 1846 avc_ss_reset(seqno);
1793 selnl_notify_policyload(seqno); 1847 selnl_notify_policyload(seqno);
1848 selinux_status_update_policyload(seqno);
1794 selinux_netlbl_cache_invalidate(); 1849 selinux_netlbl_cache_invalidate();
1795 selinux_xfrm_notify_policyload(); 1850 selinux_xfrm_notify_policyload();
1796 return 0; 1851 return 0;
@@ -1804,6 +1859,7 @@ int security_load_policy(void *data, size_t len)
1804 if (rc) 1859 if (rc)
1805 return rc; 1860 return rc;
1806 1861
1862 newpolicydb.len = len;
1807 /* If switching between different policy types, log MLS status */ 1863 /* If switching between different policy types, log MLS status */
1808 if (policydb.mls_enabled && !newpolicydb.mls_enabled) 1864 if (policydb.mls_enabled && !newpolicydb.mls_enabled)
1809 printk(KERN_INFO "SELinux: Disabling MLS support...\n"); 1865 printk(KERN_INFO "SELinux: Disabling MLS support...\n");
@@ -1870,6 +1926,7 @@ int security_load_policy(void *data, size_t len)
1870 1926
1871 avc_ss_reset(seqno); 1927 avc_ss_reset(seqno);
1872 selnl_notify_policyload(seqno); 1928 selnl_notify_policyload(seqno);
1929 selinux_status_update_policyload(seqno);
1873 selinux_netlbl_cache_invalidate(); 1930 selinux_netlbl_cache_invalidate();
1874 selinux_xfrm_notify_policyload(); 1931 selinux_xfrm_notify_policyload();
1875 1932
@@ -1883,6 +1940,17 @@ err:
1883 1940
1884} 1941}
1885 1942
1943size_t security_policydb_len(void)
1944{
1945 size_t len;
1946
1947 read_lock(&policy_rwlock);
1948 len = policydb.len;
1949 read_unlock(&policy_rwlock);
1950
1951 return len;
1952}
1953
1886/** 1954/**
1887 * security_port_sid - Obtain the SID for a port. 1955 * security_port_sid - Obtain the SID for a port.
1888 * @protocol: protocol number 1956 * @protocol: protocol number
@@ -1989,7 +2057,7 @@ int security_node_sid(u16 domain,
1989 u32 addrlen, 2057 u32 addrlen,
1990 u32 *out_sid) 2058 u32 *out_sid)
1991{ 2059{
1992 int rc = 0; 2060 int rc;
1993 struct ocontext *c; 2061 struct ocontext *c;
1994 2062
1995 read_lock(&policy_rwlock); 2063 read_lock(&policy_rwlock);
@@ -1998,10 +2066,9 @@ int security_node_sid(u16 domain,
1998 case AF_INET: { 2066 case AF_INET: {
1999 u32 addr; 2067 u32 addr;
2000 2068
2001 if (addrlen != sizeof(u32)) { 2069 rc = -EINVAL;
2002 rc = -EINVAL; 2070 if (addrlen != sizeof(u32))
2003 goto out; 2071 goto out;
2004 }
2005 2072
2006 addr = *((u32 *)addrp); 2073 addr = *((u32 *)addrp);
2007 2074
@@ -2015,10 +2082,9 @@ int security_node_sid(u16 domain,
2015 } 2082 }
2016 2083
2017 case AF_INET6: 2084 case AF_INET6:
2018 if (addrlen != sizeof(u64) * 2) { 2085 rc = -EINVAL;
2019 rc = -EINVAL; 2086 if (addrlen != sizeof(u64) * 2)
2020 goto out; 2087 goto out;
2021 }
2022 c = policydb.ocontexts[OCON_NODE6]; 2088 c = policydb.ocontexts[OCON_NODE6];
2023 while (c) { 2089 while (c) {
2024 if (match_ipv6_addrmask(addrp, c->u.node6.addr, 2090 if (match_ipv6_addrmask(addrp, c->u.node6.addr,
@@ -2029,6 +2095,7 @@ int security_node_sid(u16 domain,
2029 break; 2095 break;
2030 2096
2031 default: 2097 default:
2098 rc = 0;
2032 *out_sid = SECINITSID_NODE; 2099 *out_sid = SECINITSID_NODE;
2033 goto out; 2100 goto out;
2034 } 2101 }
@@ -2046,6 +2113,7 @@ int security_node_sid(u16 domain,
2046 *out_sid = SECINITSID_NODE; 2113 *out_sid = SECINITSID_NODE;
2047 } 2114 }
2048 2115
2116 rc = 0;
2049out: 2117out:
2050 read_unlock(&policy_rwlock); 2118 read_unlock(&policy_rwlock);
2051 return rc; 2119 return rc;
@@ -2090,24 +2158,22 @@ int security_get_user_sids(u32 fromsid,
2090 2158
2091 context_init(&usercon); 2159 context_init(&usercon);
2092 2160
2161 rc = -EINVAL;
2093 fromcon = sidtab_search(&sidtab, fromsid); 2162 fromcon = sidtab_search(&sidtab, fromsid);
2094 if (!fromcon) { 2163 if (!fromcon)
2095 rc = -EINVAL;
2096 goto out_unlock; 2164 goto out_unlock;
2097 }
2098 2165
2166 rc = -EINVAL;
2099 user = hashtab_search(policydb.p_users.table, username); 2167 user = hashtab_search(policydb.p_users.table, username);
2100 if (!user) { 2168 if (!user)
2101 rc = -EINVAL;
2102 goto out_unlock; 2169 goto out_unlock;
2103 } 2170
2104 usercon.user = user->value; 2171 usercon.user = user->value;
2105 2172
2173 rc = -ENOMEM;
2106 mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC); 2174 mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
2107 if (!mysids) { 2175 if (!mysids)
2108 rc = -ENOMEM;
2109 goto out_unlock; 2176 goto out_unlock;
2110 }
2111 2177
2112 ebitmap_for_each_positive_bit(&user->roles, rnode, i) { 2178 ebitmap_for_each_positive_bit(&user->roles, rnode, i) {
2113 role = policydb.role_val_to_struct[i]; 2179 role = policydb.role_val_to_struct[i];
@@ -2124,12 +2190,11 @@ int security_get_user_sids(u32 fromsid,
2124 if (mynel < maxnel) { 2190 if (mynel < maxnel) {
2125 mysids[mynel++] = sid; 2191 mysids[mynel++] = sid;
2126 } else { 2192 } else {
2193 rc = -ENOMEM;
2127 maxnel += SIDS_NEL; 2194 maxnel += SIDS_NEL;
2128 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC); 2195 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
2129 if (!mysids2) { 2196 if (!mysids2)
2130 rc = -ENOMEM;
2131 goto out_unlock; 2197 goto out_unlock;
2132 }
2133 memcpy(mysids2, mysids, mynel * sizeof(*mysids2)); 2198 memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
2134 kfree(mysids); 2199 kfree(mysids);
2135 mysids = mysids2; 2200 mysids = mysids2;
@@ -2137,7 +2202,7 @@ int security_get_user_sids(u32 fromsid,
2137 } 2202 }
2138 } 2203 }
2139 } 2204 }
2140 2205 rc = 0;
2141out_unlock: 2206out_unlock:
2142 read_unlock(&policy_rwlock); 2207 read_unlock(&policy_rwlock);
2143 if (rc || !mynel) { 2208 if (rc || !mynel) {
@@ -2145,17 +2210,18 @@ out_unlock:
2145 goto out; 2210 goto out;
2146 } 2211 }
2147 2212
2213 rc = -ENOMEM;
2148 mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL); 2214 mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL);
2149 if (!mysids2) { 2215 if (!mysids2) {
2150 rc = -ENOMEM;
2151 kfree(mysids); 2216 kfree(mysids);
2152 goto out; 2217 goto out;
2153 } 2218 }
2154 for (i = 0, j = 0; i < mynel; i++) { 2219 for (i = 0, j = 0; i < mynel; i++) {
2220 struct av_decision dummy_avd;
2155 rc = avc_has_perm_noaudit(fromsid, mysids[i], 2221 rc = avc_has_perm_noaudit(fromsid, mysids[i],
2156 SECCLASS_PROCESS, /* kernel value */ 2222 SECCLASS_PROCESS, /* kernel value */
2157 PROCESS__TRANSITION, AVC_STRICT, 2223 PROCESS__TRANSITION, AVC_STRICT,
2158 NULL); 2224 &dummy_avd);
2159 if (!rc) 2225 if (!rc)
2160 mysids2[j++] = mysids[i]; 2226 mysids2[j++] = mysids[i];
2161 cond_resched(); 2227 cond_resched();
@@ -2188,7 +2254,7 @@ int security_genfs_sid(const char *fstype,
2188 u16 sclass; 2254 u16 sclass;
2189 struct genfs *genfs; 2255 struct genfs *genfs;
2190 struct ocontext *c; 2256 struct ocontext *c;
2191 int rc = 0, cmp = 0; 2257 int rc, cmp = 0;
2192 2258
2193 while (path[0] == '/' && path[1] == '/') 2259 while (path[0] == '/' && path[1] == '/')
2194 path++; 2260 path++;
@@ -2196,6 +2262,7 @@ int security_genfs_sid(const char *fstype,
2196 read_lock(&policy_rwlock); 2262 read_lock(&policy_rwlock);
2197 2263
2198 sclass = unmap_class(orig_sclass); 2264 sclass = unmap_class(orig_sclass);
2265 *sid = SECINITSID_UNLABELED;
2199 2266
2200 for (genfs = policydb.genfs; genfs; genfs = genfs->next) { 2267 for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
2201 cmp = strcmp(fstype, genfs->fstype); 2268 cmp = strcmp(fstype, genfs->fstype);
@@ -2203,11 +2270,9 @@ int security_genfs_sid(const char *fstype,
2203 break; 2270 break;
2204 } 2271 }
2205 2272
2206 if (!genfs || cmp) { 2273 rc = -ENOENT;
2207 *sid = SECINITSID_UNLABELED; 2274 if (!genfs || cmp)
2208 rc = -ENOENT;
2209 goto out; 2275 goto out;
2210 }
2211 2276
2212 for (c = genfs->head; c; c = c->next) { 2277 for (c = genfs->head; c; c = c->next) {
2213 len = strlen(c->u.name); 2278 len = strlen(c->u.name);
@@ -2216,21 +2281,18 @@ int security_genfs_sid(const char *fstype,
2216 break; 2281 break;
2217 } 2282 }
2218 2283
2219 if (!c) { 2284 rc = -ENOENT;
2220 *sid = SECINITSID_UNLABELED; 2285 if (!c)
2221 rc = -ENOENT;
2222 goto out; 2286 goto out;
2223 }
2224 2287
2225 if (!c->sid[0]) { 2288 if (!c->sid[0]) {
2226 rc = sidtab_context_to_sid(&sidtab, 2289 rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]);
2227 &c->context[0],
2228 &c->sid[0]);
2229 if (rc) 2290 if (rc)
2230 goto out; 2291 goto out;
2231 } 2292 }
2232 2293
2233 *sid = c->sid[0]; 2294 *sid = c->sid[0];
2295 rc = 0;
2234out: 2296out:
2235 read_unlock(&policy_rwlock); 2297 read_unlock(&policy_rwlock);
2236 return rc; 2298 return rc;
@@ -2262,8 +2324,7 @@ int security_fs_use(
2262 if (c) { 2324 if (c) {
2263 *behavior = c->v.behavior; 2325 *behavior = c->v.behavior;
2264 if (!c->sid[0]) { 2326 if (!c->sid[0]) {
2265 rc = sidtab_context_to_sid(&sidtab, 2327 rc = sidtab_context_to_sid(&sidtab, &c->context[0],
2266 &c->context[0],
2267 &c->sid[0]); 2328 &c->sid[0]);
2268 if (rc) 2329 if (rc)
2269 goto out; 2330 goto out;
@@ -2286,34 +2347,39 @@ out:
2286 2347
2287int security_get_bools(int *len, char ***names, int **values) 2348int security_get_bools(int *len, char ***names, int **values)
2288{ 2349{
2289 int i, rc = -ENOMEM; 2350 int i, rc;
2290 2351
2291 read_lock(&policy_rwlock); 2352 read_lock(&policy_rwlock);
2292 *names = NULL; 2353 *names = NULL;
2293 *values = NULL; 2354 *values = NULL;
2294 2355
2356 rc = 0;
2295 *len = policydb.p_bools.nprim; 2357 *len = policydb.p_bools.nprim;
2296 if (!*len) { 2358 if (!*len)
2297 rc = 0;
2298 goto out; 2359 goto out;
2299 }
2300 2360
2301 *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC); 2361 rc = -ENOMEM;
2362 *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC);
2302 if (!*names) 2363 if (!*names)
2303 goto err; 2364 goto err;
2304 2365
2305 *values = kcalloc(*len, sizeof(int), GFP_ATOMIC); 2366 rc = -ENOMEM;
2367 *values = kcalloc(*len, sizeof(int), GFP_ATOMIC);
2306 if (!*values) 2368 if (!*values)
2307 goto err; 2369 goto err;
2308 2370
2309 for (i = 0; i < *len; i++) { 2371 for (i = 0; i < *len; i++) {
2310 size_t name_len; 2372 size_t name_len;
2373
2311 (*values)[i] = policydb.bool_val_to_struct[i]->state; 2374 (*values)[i] = policydb.bool_val_to_struct[i]->state;
2312 name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; 2375 name_len = strlen(sym_name(&policydb, SYM_BOOLS, i)) + 1;
2313 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); 2376
2377 rc = -ENOMEM;
2378 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC);
2314 if (!(*names)[i]) 2379 if (!(*names)[i])
2315 goto err; 2380 goto err;
2316 strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); 2381
2382 strncpy((*names)[i], sym_name(&policydb, SYM_BOOLS, i), name_len);
2317 (*names)[i][name_len - 1] = 0; 2383 (*names)[i][name_len - 1] = 0;
2318 } 2384 }
2319 rc = 0; 2385 rc = 0;
@@ -2332,24 +2398,23 @@ err:
2332 2398
2333int security_set_bools(int len, int *values) 2399int security_set_bools(int len, int *values)
2334{ 2400{
2335 int i, rc = 0; 2401 int i, rc;
2336 int lenp, seqno = 0; 2402 int lenp, seqno = 0;
2337 struct cond_node *cur; 2403 struct cond_node *cur;
2338 2404
2339 write_lock_irq(&policy_rwlock); 2405 write_lock_irq(&policy_rwlock);
2340 2406
2407 rc = -EFAULT;
2341 lenp = policydb.p_bools.nprim; 2408 lenp = policydb.p_bools.nprim;
2342 if (len != lenp) { 2409 if (len != lenp)
2343 rc = -EFAULT;
2344 goto out; 2410 goto out;
2345 }
2346 2411
2347 for (i = 0; i < len; i++) { 2412 for (i = 0; i < len; i++) {
2348 if (!!values[i] != policydb.bool_val_to_struct[i]->state) { 2413 if (!!values[i] != policydb.bool_val_to_struct[i]->state) {
2349 audit_log(current->audit_context, GFP_ATOMIC, 2414 audit_log(current->audit_context, GFP_ATOMIC,
2350 AUDIT_MAC_CONFIG_CHANGE, 2415 AUDIT_MAC_CONFIG_CHANGE,
2351 "bool=%s val=%d old_val=%d auid=%u ses=%u", 2416 "bool=%s val=%d old_val=%d auid=%u ses=%u",
2352 policydb.p_bool_val_to_name[i], 2417 sym_name(&policydb, SYM_BOOLS, i),
2353 !!values[i], 2418 !!values[i],
2354 policydb.bool_val_to_struct[i]->state, 2419 policydb.bool_val_to_struct[i]->state,
2355 audit_get_loginuid(current), 2420 audit_get_loginuid(current),
@@ -2368,12 +2433,13 @@ int security_set_bools(int len, int *values)
2368 } 2433 }
2369 2434
2370 seqno = ++latest_granting; 2435 seqno = ++latest_granting;
2371 2436 rc = 0;
2372out: 2437out:
2373 write_unlock_irq(&policy_rwlock); 2438 write_unlock_irq(&policy_rwlock);
2374 if (!rc) { 2439 if (!rc) {
2375 avc_ss_reset(seqno); 2440 avc_ss_reset(seqno);
2376 selnl_notify_policyload(seqno); 2441 selnl_notify_policyload(seqno);
2442 selinux_status_update_policyload(seqno);
2377 selinux_xfrm_notify_policyload(); 2443 selinux_xfrm_notify_policyload();
2378 } 2444 }
2379 return rc; 2445 return rc;
@@ -2381,16 +2447,15 @@ out:
2381 2447
2382int security_get_bool_value(int bool) 2448int security_get_bool_value(int bool)
2383{ 2449{
2384 int rc = 0; 2450 int rc;
2385 int len; 2451 int len;
2386 2452
2387 read_lock(&policy_rwlock); 2453 read_lock(&policy_rwlock);
2388 2454
2455 rc = -EFAULT;
2389 len = policydb.p_bools.nprim; 2456 len = policydb.p_bools.nprim;
2390 if (bool >= len) { 2457 if (bool >= len)
2391 rc = -EFAULT;
2392 goto out; 2458 goto out;
2393 }
2394 2459
2395 rc = policydb.bool_val_to_struct[bool]->state; 2460 rc = policydb.bool_val_to_struct[bool]->state;
2396out: 2461out:
@@ -2440,8 +2505,9 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2440 struct context newcon; 2505 struct context newcon;
2441 char *s; 2506 char *s;
2442 u32 len; 2507 u32 len;
2443 int rc = 0; 2508 int rc;
2444 2509
2510 rc = 0;
2445 if (!ss_initialized || !policydb.mls_enabled) { 2511 if (!ss_initialized || !policydb.mls_enabled) {
2446 *new_sid = sid; 2512 *new_sid = sid;
2447 goto out; 2513 goto out;
@@ -2450,19 +2516,20 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2450 context_init(&newcon); 2516 context_init(&newcon);
2451 2517
2452 read_lock(&policy_rwlock); 2518 read_lock(&policy_rwlock);
2519
2520 rc = -EINVAL;
2453 context1 = sidtab_search(&sidtab, sid); 2521 context1 = sidtab_search(&sidtab, sid);
2454 if (!context1) { 2522 if (!context1) {
2455 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2523 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2456 __func__, sid); 2524 __func__, sid);
2457 rc = -EINVAL;
2458 goto out_unlock; 2525 goto out_unlock;
2459 } 2526 }
2460 2527
2528 rc = -EINVAL;
2461 context2 = sidtab_search(&sidtab, mls_sid); 2529 context2 = sidtab_search(&sidtab, mls_sid);
2462 if (!context2) { 2530 if (!context2) {
2463 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2531 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2464 __func__, mls_sid); 2532 __func__, mls_sid);
2465 rc = -EINVAL;
2466 goto out_unlock; 2533 goto out_unlock;
2467 } 2534 }
2468 2535
@@ -2476,20 +2543,17 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2476 /* Check the validity of the new context. */ 2543 /* Check the validity of the new context. */
2477 if (!policydb_context_isvalid(&policydb, &newcon)) { 2544 if (!policydb_context_isvalid(&policydb, &newcon)) {
2478 rc = convert_context_handle_invalid_context(&newcon); 2545 rc = convert_context_handle_invalid_context(&newcon);
2479 if (rc) 2546 if (rc) {
2480 goto bad; 2547 if (!context_struct_to_string(&newcon, &s, &len)) {
2548 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2549 "security_sid_mls_copy: invalid context %s", s);
2550 kfree(s);
2551 }
2552 goto out_unlock;
2553 }
2481 } 2554 }
2482 2555
2483 rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid); 2556 rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid);
2484 goto out_unlock;
2485
2486bad:
2487 if (!context_struct_to_string(&newcon, &s, &len)) {
2488 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2489 "security_sid_mls_copy: invalid context %s", s);
2490 kfree(s);
2491 }
2492
2493out_unlock: 2557out_unlock:
2494 read_unlock(&policy_rwlock); 2558 read_unlock(&policy_rwlock);
2495 context_destroy(&newcon); 2559 context_destroy(&newcon);
@@ -2525,6 +2589,8 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2525 struct context *nlbl_ctx; 2589 struct context *nlbl_ctx;
2526 struct context *xfrm_ctx; 2590 struct context *xfrm_ctx;
2527 2591
2592 *peer_sid = SECSID_NULL;
2593
2528 /* handle the common (which also happens to be the set of easy) cases 2594 /* handle the common (which also happens to be the set of easy) cases
2529 * right away, these two if statements catch everything involving a 2595 * right away, these two if statements catch everything involving a
2530 * single or absent peer SID/label */ 2596 * single or absent peer SID/label */
@@ -2543,40 +2609,37 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2543 /* we don't need to check ss_initialized here since the only way both 2609 /* we don't need to check ss_initialized here since the only way both
2544 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the 2610 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
2545 * security server was initialized and ss_initialized was true */ 2611 * security server was initialized and ss_initialized was true */
2546 if (!policydb.mls_enabled) { 2612 if (!policydb.mls_enabled)
2547 *peer_sid = SECSID_NULL;
2548 return 0; 2613 return 0;
2549 }
2550 2614
2551 read_lock(&policy_rwlock); 2615 read_lock(&policy_rwlock);
2552 2616
2617 rc = -EINVAL;
2553 nlbl_ctx = sidtab_search(&sidtab, nlbl_sid); 2618 nlbl_ctx = sidtab_search(&sidtab, nlbl_sid);
2554 if (!nlbl_ctx) { 2619 if (!nlbl_ctx) {
2555 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2620 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2556 __func__, nlbl_sid); 2621 __func__, nlbl_sid);
2557 rc = -EINVAL; 2622 goto out;
2558 goto out_slowpath;
2559 } 2623 }
2624 rc = -EINVAL;
2560 xfrm_ctx = sidtab_search(&sidtab, xfrm_sid); 2625 xfrm_ctx = sidtab_search(&sidtab, xfrm_sid);
2561 if (!xfrm_ctx) { 2626 if (!xfrm_ctx) {
2562 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2627 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2563 __func__, xfrm_sid); 2628 __func__, xfrm_sid);
2564 rc = -EINVAL; 2629 goto out;
2565 goto out_slowpath;
2566 } 2630 }
2567 rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); 2631 rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES);
2632 if (rc)
2633 goto out;
2568 2634
2569out_slowpath: 2635 /* at present NetLabel SIDs/labels really only carry MLS
2636 * information so if the MLS portion of the NetLabel SID
2637 * matches the MLS portion of the labeled XFRM SID/label
2638 * then pass along the XFRM SID as it is the most
2639 * expressive */
2640 *peer_sid = xfrm_sid;
2641out:
2570 read_unlock(&policy_rwlock); 2642 read_unlock(&policy_rwlock);
2571 if (rc == 0)
2572 /* at present NetLabel SIDs/labels really only carry MLS
2573 * information so if the MLS portion of the NetLabel SID
2574 * matches the MLS portion of the labeled XFRM SID/label
2575 * then pass along the XFRM SID as it is the most
2576 * expressive */
2577 *peer_sid = xfrm_sid;
2578 else
2579 *peer_sid = SECSID_NULL;
2580 return rc; 2643 return rc;
2581} 2644}
2582 2645
@@ -2595,10 +2658,11 @@ static int get_classes_callback(void *k, void *d, void *args)
2595 2658
2596int security_get_classes(char ***classes, int *nclasses) 2659int security_get_classes(char ***classes, int *nclasses)
2597{ 2660{
2598 int rc = -ENOMEM; 2661 int rc;
2599 2662
2600 read_lock(&policy_rwlock); 2663 read_lock(&policy_rwlock);
2601 2664
2665 rc = -ENOMEM;
2602 *nclasses = policydb.p_classes.nprim; 2666 *nclasses = policydb.p_classes.nprim;
2603 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC); 2667 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC);
2604 if (!*classes) 2668 if (!*classes)
@@ -2606,7 +2670,7 @@ int security_get_classes(char ***classes, int *nclasses)
2606 2670
2607 rc = hashtab_map(policydb.p_classes.table, get_classes_callback, 2671 rc = hashtab_map(policydb.p_classes.table, get_classes_callback,
2608 *classes); 2672 *classes);
2609 if (rc < 0) { 2673 if (rc) {
2610 int i; 2674 int i;
2611 for (i = 0; i < *nclasses; i++) 2675 for (i = 0; i < *nclasses; i++)
2612 kfree((*classes)[i]); 2676 kfree((*classes)[i]);
@@ -2633,19 +2697,20 @@ static int get_permissions_callback(void *k, void *d, void *args)
2633 2697
2634int security_get_permissions(char *class, char ***perms, int *nperms) 2698int security_get_permissions(char *class, char ***perms, int *nperms)
2635{ 2699{
2636 int rc = -ENOMEM, i; 2700 int rc, i;
2637 struct class_datum *match; 2701 struct class_datum *match;
2638 2702
2639 read_lock(&policy_rwlock); 2703 read_lock(&policy_rwlock);
2640 2704
2705 rc = -EINVAL;
2641 match = hashtab_search(policydb.p_classes.table, class); 2706 match = hashtab_search(policydb.p_classes.table, class);
2642 if (!match) { 2707 if (!match) {
2643 printk(KERN_ERR "SELinux: %s: unrecognized class %s\n", 2708 printk(KERN_ERR "SELinux: %s: unrecognized class %s\n",
2644 __func__, class); 2709 __func__, class);
2645 rc = -EINVAL;
2646 goto out; 2710 goto out;
2647 } 2711 }
2648 2712
2713 rc = -ENOMEM;
2649 *nperms = match->permissions.nprim; 2714 *nperms = match->permissions.nprim;
2650 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC); 2715 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC);
2651 if (!*perms) 2716 if (!*perms)
@@ -2654,13 +2719,13 @@ int security_get_permissions(char *class, char ***perms, int *nperms)
2654 if (match->comdatum) { 2719 if (match->comdatum) {
2655 rc = hashtab_map(match->comdatum->permissions.table, 2720 rc = hashtab_map(match->comdatum->permissions.table,
2656 get_permissions_callback, *perms); 2721 get_permissions_callback, *perms);
2657 if (rc < 0) 2722 if (rc)
2658 goto err; 2723 goto err;
2659 } 2724 }
2660 2725
2661 rc = hashtab_map(match->permissions.table, get_permissions_callback, 2726 rc = hashtab_map(match->permissions.table, get_permissions_callback,
2662 *perms); 2727 *perms);
2663 if (rc < 0) 2728 if (rc)
2664 goto err; 2729 goto err;
2665 2730
2666out: 2731out:
@@ -2750,7 +2815,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
2750 case AUDIT_SUBJ_CLR: 2815 case AUDIT_SUBJ_CLR:
2751 case AUDIT_OBJ_LEV_LOW: 2816 case AUDIT_OBJ_LEV_LOW:
2752 case AUDIT_OBJ_LEV_HIGH: 2817 case AUDIT_OBJ_LEV_HIGH:
2753 /* we do not allow a range, indicated by the presense of '-' */ 2818 /* we do not allow a range, indicated by the presence of '-' */
2754 if (strchr(rulestr, '-')) 2819 if (strchr(rulestr, '-'))
2755 return -EINVAL; 2820 return -EINVAL;
2756 break; 2821 break;
@@ -2772,36 +2837,39 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
2772 switch (field) { 2837 switch (field) {
2773 case AUDIT_SUBJ_USER: 2838 case AUDIT_SUBJ_USER:
2774 case AUDIT_OBJ_USER: 2839 case AUDIT_OBJ_USER:
2840 rc = -EINVAL;
2775 userdatum = hashtab_search(policydb.p_users.table, rulestr); 2841 userdatum = hashtab_search(policydb.p_users.table, rulestr);
2776 if (!userdatum) 2842 if (!userdatum)
2777 rc = -EINVAL; 2843 goto out;
2778 else 2844 tmprule->au_ctxt.user = userdatum->value;
2779 tmprule->au_ctxt.user = userdatum->value;
2780 break; 2845 break;
2781 case AUDIT_SUBJ_ROLE: 2846 case AUDIT_SUBJ_ROLE:
2782 case AUDIT_OBJ_ROLE: 2847 case AUDIT_OBJ_ROLE:
2848 rc = -EINVAL;
2783 roledatum = hashtab_search(policydb.p_roles.table, rulestr); 2849 roledatum = hashtab_search(policydb.p_roles.table, rulestr);
2784 if (!roledatum) 2850 if (!roledatum)
2785 rc = -EINVAL; 2851 goto out;
2786 else 2852 tmprule->au_ctxt.role = roledatum->value;
2787 tmprule->au_ctxt.role = roledatum->value;
2788 break; 2853 break;
2789 case AUDIT_SUBJ_TYPE: 2854 case AUDIT_SUBJ_TYPE:
2790 case AUDIT_OBJ_TYPE: 2855 case AUDIT_OBJ_TYPE:
2856 rc = -EINVAL;
2791 typedatum = hashtab_search(policydb.p_types.table, rulestr); 2857 typedatum = hashtab_search(policydb.p_types.table, rulestr);
2792 if (!typedatum) 2858 if (!typedatum)
2793 rc = -EINVAL; 2859 goto out;
2794 else 2860 tmprule->au_ctxt.type = typedatum->value;
2795 tmprule->au_ctxt.type = typedatum->value;
2796 break; 2861 break;
2797 case AUDIT_SUBJ_SEN: 2862 case AUDIT_SUBJ_SEN:
2798 case AUDIT_SUBJ_CLR: 2863 case AUDIT_SUBJ_CLR:
2799 case AUDIT_OBJ_LEV_LOW: 2864 case AUDIT_OBJ_LEV_LOW:
2800 case AUDIT_OBJ_LEV_HIGH: 2865 case AUDIT_OBJ_LEV_HIGH:
2801 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); 2866 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC);
2867 if (rc)
2868 goto out;
2802 break; 2869 break;
2803 } 2870 }
2804 2871 rc = 0;
2872out:
2805 read_unlock(&policy_rwlock); 2873 read_unlock(&policy_rwlock);
2806 2874
2807 if (rc) { 2875 if (rc) {
@@ -3016,7 +3084,7 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr,
3016 * Description: 3084 * Description:
3017 * Convert the given NetLabel security attributes in @secattr into a 3085 * Convert the given NetLabel security attributes in @secattr into a
3018 * SELinux SID. If the @secattr field does not contain a full SELinux 3086 * SELinux SID. If the @secattr field does not contain a full SELinux
3019 * SID/context then use SECINITSID_NETMSG as the foundation. If possibile the 3087 * SID/context then use SECINITSID_NETMSG as the foundation. If possible the
3020 * 'cache' field of @secattr is set and the CACHE flag is set; this is to 3088 * 'cache' field of @secattr is set and the CACHE flag is set; this is to
3021 * allow the @secattr to be used by NetLabel to cache the secattr to SID 3089 * allow the @secattr to be used by NetLabel to cache the secattr to SID
3022 * conversion for future lookups. Returns zero on success, negative values on 3090 * conversion for future lookups. Returns zero on success, negative values on
@@ -3026,7 +3094,7 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr,
3026int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, 3094int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3027 u32 *sid) 3095 u32 *sid)
3028{ 3096{
3029 int rc = -EIDRM; 3097 int rc;
3030 struct context *ctx; 3098 struct context *ctx;
3031 struct context ctx_new; 3099 struct context ctx_new;
3032 3100
@@ -3037,16 +3105,15 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3037 3105
3038 read_lock(&policy_rwlock); 3106 read_lock(&policy_rwlock);
3039 3107
3040 if (secattr->flags & NETLBL_SECATTR_CACHE) { 3108 if (secattr->flags & NETLBL_SECATTR_CACHE)
3041 *sid = *(u32 *)secattr->cache->data; 3109 *sid = *(u32 *)secattr->cache->data;
3042 rc = 0; 3110 else if (secattr->flags & NETLBL_SECATTR_SECID)
3043 } else if (secattr->flags & NETLBL_SECATTR_SECID) {
3044 *sid = secattr->attr.secid; 3111 *sid = secattr->attr.secid;
3045 rc = 0; 3112 else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) {
3046 } else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { 3113 rc = -EIDRM;
3047 ctx = sidtab_search(&sidtab, SECINITSID_NETMSG); 3114 ctx = sidtab_search(&sidtab, SECINITSID_NETMSG);
3048 if (ctx == NULL) 3115 if (ctx == NULL)
3049 goto netlbl_secattr_to_sid_return; 3116 goto out;
3050 3117
3051 context_init(&ctx_new); 3118 context_init(&ctx_new);
3052 ctx_new.user = ctx->user; 3119 ctx_new.user = ctx->user;
@@ -3054,34 +3121,35 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3054 ctx_new.type = ctx->type; 3121 ctx_new.type = ctx->type;
3055 mls_import_netlbl_lvl(&ctx_new, secattr); 3122 mls_import_netlbl_lvl(&ctx_new, secattr);
3056 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { 3123 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
3057 if (ebitmap_netlbl_import(&ctx_new.range.level[0].cat, 3124 rc = ebitmap_netlbl_import(&ctx_new.range.level[0].cat,
3058 secattr->attr.mls.cat) != 0) 3125 secattr->attr.mls.cat);
3059 goto netlbl_secattr_to_sid_return; 3126 if (rc)
3127 goto out;
3060 memcpy(&ctx_new.range.level[1].cat, 3128 memcpy(&ctx_new.range.level[1].cat,
3061 &ctx_new.range.level[0].cat, 3129 &ctx_new.range.level[0].cat,
3062 sizeof(ctx_new.range.level[0].cat)); 3130 sizeof(ctx_new.range.level[0].cat));
3063 } 3131 }
3064 if (mls_context_isvalid(&policydb, &ctx_new) != 1) 3132 rc = -EIDRM;
3065 goto netlbl_secattr_to_sid_return_cleanup; 3133 if (!mls_context_isvalid(&policydb, &ctx_new))
3134 goto out_free;
3066 3135
3067 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid); 3136 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid);
3068 if (rc != 0) 3137 if (rc)
3069 goto netlbl_secattr_to_sid_return_cleanup; 3138 goto out_free;
3070 3139
3071 security_netlbl_cache_add(secattr, *sid); 3140 security_netlbl_cache_add(secattr, *sid);
3072 3141
3073 ebitmap_destroy(&ctx_new.range.level[0].cat); 3142 ebitmap_destroy(&ctx_new.range.level[0].cat);
3074 } else { 3143 } else
3075 *sid = SECSID_NULL; 3144 *sid = SECSID_NULL;
3076 rc = 0;
3077 }
3078 3145
3079netlbl_secattr_to_sid_return:
3080 read_unlock(&policy_rwlock); 3146 read_unlock(&policy_rwlock);
3081 return rc; 3147 return 0;
3082netlbl_secattr_to_sid_return_cleanup: 3148out_free:
3083 ebitmap_destroy(&ctx_new.range.level[0].cat); 3149 ebitmap_destroy(&ctx_new.range.level[0].cat);
3084 goto netlbl_secattr_to_sid_return; 3150out:
3151 read_unlock(&policy_rwlock);
3152 return rc;
3085} 3153}
3086 3154
3087/** 3155/**
@@ -3103,29 +3171,59 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
3103 return 0; 3171 return 0;
3104 3172
3105 read_lock(&policy_rwlock); 3173 read_lock(&policy_rwlock);
3174
3175 rc = -ENOENT;
3106 ctx = sidtab_search(&sidtab, sid); 3176 ctx = sidtab_search(&sidtab, sid);
3107 if (ctx == NULL) { 3177 if (ctx == NULL)
3108 rc = -ENOENT; 3178 goto out;
3109 goto netlbl_sid_to_secattr_failure; 3179
3110 } 3180 rc = -ENOMEM;
3111 secattr->domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], 3181 secattr->domain = kstrdup(sym_name(&policydb, SYM_TYPES, ctx->type - 1),
3112 GFP_ATOMIC); 3182 GFP_ATOMIC);
3113 if (secattr->domain == NULL) { 3183 if (secattr->domain == NULL)
3114 rc = -ENOMEM; 3184 goto out;
3115 goto netlbl_sid_to_secattr_failure; 3185
3116 }
3117 secattr->attr.secid = sid; 3186 secattr->attr.secid = sid;
3118 secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; 3187 secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID;
3119 mls_export_netlbl_lvl(ctx, secattr); 3188 mls_export_netlbl_lvl(ctx, secattr);
3120 rc = mls_export_netlbl_cat(ctx, secattr); 3189 rc = mls_export_netlbl_cat(ctx, secattr);
3121 if (rc != 0) 3190out:
3122 goto netlbl_sid_to_secattr_failure;
3123 read_unlock(&policy_rwlock); 3191 read_unlock(&policy_rwlock);
3192 return rc;
3193}
3194#endif /* CONFIG_NETLABEL */
3124 3195
3125 return 0; 3196/**
3197 * security_read_policy - read the policy.
3198 * @data: binary policy data
3199 * @len: length of data in bytes
3200 *
3201 */
3202int security_read_policy(void **data, size_t *len)
3203{
3204 int rc;
3205 struct policy_file fp;
3126 3206
3127netlbl_sid_to_secattr_failure: 3207 if (!ss_initialized)
3208 return -EINVAL;
3209
3210 *len = security_policydb_len();
3211
3212 *data = vmalloc_user(*len);
3213 if (!*data)
3214 return -ENOMEM;
3215
3216 fp.data = *data;
3217 fp.len = *len;
3218
3219 read_lock(&policy_rwlock);
3220 rc = policydb_write(&policydb, &fp);
3128 read_unlock(&policy_rwlock); 3221 read_unlock(&policy_rwlock);
3129 return rc; 3222
3223 if (rc)
3224 return rc;
3225
3226 *len = (unsigned long)fp.data - (unsigned long)*data;
3227 return 0;
3228
3130} 3229}
3131#endif /* CONFIG_NETLABEL */
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index e817989764cd..5840a35155fc 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -147,6 +147,17 @@ out:
147 return rc; 147 return rc;
148} 148}
149 149
150static void sidtab_update_cache(struct sidtab *s, struct sidtab_node *n, int loc)
151{
152 BUG_ON(loc >= SIDTAB_CACHE_LEN);
153
154 while (loc > 0) {
155 s->cache[loc] = s->cache[loc - 1];
156 loc--;
157 }
158 s->cache[0] = n;
159}
160
150static inline u32 sidtab_search_context(struct sidtab *s, 161static inline u32 sidtab_search_context(struct sidtab *s,
151 struct context *context) 162 struct context *context)
152{ 163{
@@ -156,14 +167,33 @@ static inline u32 sidtab_search_context(struct sidtab *s,
156 for (i = 0; i < SIDTAB_SIZE; i++) { 167 for (i = 0; i < SIDTAB_SIZE; i++) {
157 cur = s->htable[i]; 168 cur = s->htable[i];
158 while (cur) { 169 while (cur) {
159 if (context_cmp(&cur->context, context)) 170 if (context_cmp(&cur->context, context)) {
171 sidtab_update_cache(s, cur, SIDTAB_CACHE_LEN - 1);
160 return cur->sid; 172 return cur->sid;
173 }
161 cur = cur->next; 174 cur = cur->next;
162 } 175 }
163 } 176 }
164 return 0; 177 return 0;
165} 178}
166 179
180static inline u32 sidtab_search_cache(struct sidtab *s, struct context *context)
181{
182 int i;
183 struct sidtab_node *node;
184
185 for (i = 0; i < SIDTAB_CACHE_LEN; i++) {
186 node = s->cache[i];
187 if (unlikely(!node))
188 return 0;
189 if (context_cmp(&node->context, context)) {
190 sidtab_update_cache(s, node, i);
191 return node->sid;
192 }
193 }
194 return 0;
195}
196
167int sidtab_context_to_sid(struct sidtab *s, 197int sidtab_context_to_sid(struct sidtab *s,
168 struct context *context, 198 struct context *context,
169 u32 *out_sid) 199 u32 *out_sid)
@@ -174,7 +204,9 @@ int sidtab_context_to_sid(struct sidtab *s,
174 204
175 *out_sid = SECSID_NULL; 205 *out_sid = SECSID_NULL;
176 206
177 sid = sidtab_search_context(s, context); 207 sid = sidtab_search_cache(s, context);
208 if (!sid)
209 sid = sidtab_search_context(s, context);
178 if (!sid) { 210 if (!sid) {
179 spin_lock_irqsave(&s->lock, flags); 211 spin_lock_irqsave(&s->lock, flags);
180 /* Rescan now that we hold the lock. */ 212 /* Rescan now that we hold the lock. */
@@ -259,12 +291,15 @@ void sidtab_destroy(struct sidtab *s)
259void sidtab_set(struct sidtab *dst, struct sidtab *src) 291void sidtab_set(struct sidtab *dst, struct sidtab *src)
260{ 292{
261 unsigned long flags; 293 unsigned long flags;
294 int i;
262 295
263 spin_lock_irqsave(&src->lock, flags); 296 spin_lock_irqsave(&src->lock, flags);
264 dst->htable = src->htable; 297 dst->htable = src->htable;
265 dst->nel = src->nel; 298 dst->nel = src->nel;
266 dst->next_sid = src->next_sid; 299 dst->next_sid = src->next_sid;
267 dst->shutdown = 0; 300 dst->shutdown = 0;
301 for (i = 0; i < SIDTAB_CACHE_LEN; i++)
302 dst->cache[i] = NULL;
268 spin_unlock_irqrestore(&src->lock, flags); 303 spin_unlock_irqrestore(&src->lock, flags);
269} 304}
270 305
diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h
index 64ea5b1cdea4..84dc154d9389 100644
--- a/security/selinux/ss/sidtab.h
+++ b/security/selinux/ss/sidtab.h
@@ -26,6 +26,8 @@ struct sidtab {
26 unsigned int nel; /* number of elements */ 26 unsigned int nel; /* number of elements */
27 unsigned int next_sid; /* next SID to allocate */ 27 unsigned int next_sid; /* next SID to allocate */
28 unsigned char shutdown; 28 unsigned char shutdown;
29#define SIDTAB_CACHE_LEN 3
30 struct sidtab_node *cache[SIDTAB_CACHE_LEN];
29 spinlock_t lock; 31 spinlock_t lock;
30}; 32};
31 33
diff --git a/security/selinux/ss/status.c b/security/selinux/ss/status.c
new file mode 100644
index 000000000000..d982365f9d1a
--- /dev/null
+++ b/security/selinux/ss/status.c
@@ -0,0 +1,126 @@
1/*
2 * mmap based event notifications for SELinux
3 *
4 * Author: KaiGai Kohei <kaigai@ak.jp.nec.com>
5 *
6 * Copyright (C) 2010 NEC corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2,
10 * as published by the Free Software Foundation.
11 */
12#include <linux/kernel.h>
13#include <linux/gfp.h>
14#include <linux/mm.h>
15#include <linux/mutex.h>
16#include "avc.h"
17#include "services.h"
18
19/*
20 * The selinux_status_page shall be exposed to userspace applications
21 * using mmap interface on /selinux/status.
22 * It enables to notify applications a few events that will cause reset
23 * of userspace access vector without context switching.
24 *
25 * The selinux_kernel_status structure on the head of status page is
26 * protected from concurrent accesses using seqlock logic, so userspace
27 * application should reference the status page according to the seqlock
28 * logic.
29 *
30 * Typically, application checks status->sequence at the head of access
31 * control routine. If it is odd-number, kernel is updating the status,
32 * so please wait for a moment. If it is changed from the last sequence
33 * number, it means something happen, so application will reset userspace
34 * avc, if needed.
35 * In most cases, application shall confirm the kernel status is not
36 * changed without any system call invocations.
37 */
38static struct page *selinux_status_page;
39static DEFINE_MUTEX(selinux_status_lock);
40
41/*
42 * selinux_kernel_status_page
43 *
44 * It returns a reference to selinux_status_page. If the status page is
45 * not allocated yet, it also tries to allocate it at the first time.
46 */
47struct page *selinux_kernel_status_page(void)
48{
49 struct selinux_kernel_status *status;
50 struct page *result = NULL;
51
52 mutex_lock(&selinux_status_lock);
53 if (!selinux_status_page) {
54 selinux_status_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
55
56 if (selinux_status_page) {
57 status = page_address(selinux_status_page);
58
59 status->version = SELINUX_KERNEL_STATUS_VERSION;
60 status->sequence = 0;
61 status->enforcing = selinux_enforcing;
62 /*
63 * NOTE: the next policyload event shall set
64 * a positive value on the status->policyload,
65 * although it may not be 1, but never zero.
66 * So, application can know it was updated.
67 */
68 status->policyload = 0;
69 status->deny_unknown = !security_get_allow_unknown();
70 }
71 }
72 result = selinux_status_page;
73 mutex_unlock(&selinux_status_lock);
74
75 return result;
76}
77
78/*
79 * selinux_status_update_setenforce
80 *
81 * It updates status of the current enforcing/permissive mode.
82 */
83void selinux_status_update_setenforce(int enforcing)
84{
85 struct selinux_kernel_status *status;
86
87 mutex_lock(&selinux_status_lock);
88 if (selinux_status_page) {
89 status = page_address(selinux_status_page);
90
91 status->sequence++;
92 smp_wmb();
93
94 status->enforcing = enforcing;
95
96 smp_wmb();
97 status->sequence++;
98 }
99 mutex_unlock(&selinux_status_lock);
100}
101
102/*
103 * selinux_status_update_policyload
104 *
105 * It updates status of the times of policy reloaded, and current
106 * setting of deny_unknown.
107 */
108void selinux_status_update_policyload(int seqno)
109{
110 struct selinux_kernel_status *status;
111
112 mutex_lock(&selinux_status_lock);
113 if (selinux_status_page) {
114 status = page_address(selinux_status_page);
115
116 status->sequence++;
117 smp_wmb();
118
119 status->policyload = seqno;
120 status->deny_unknown = !security_get_allow_unknown();
121
122 smp_wmb();
123 status->sequence++;
124 }
125 mutex_unlock(&selinux_status_lock);
126}