aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/mls.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/mls.c')
-rw-r--r--security/selinux/ss/mls.c156
1 files changed, 75 insertions, 81 deletions
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 4a8bab2f3c71..9a11deaaa9e7 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -34,7 +34,9 @@
34 */ 34 */
35int mls_compute_context_len(struct context * context) 35int mls_compute_context_len(struct context * context)
36{ 36{
37 int i, l, len, range; 37 int i, l, len, head, prev;
38 char *nm;
39 struct ebitmap *e;
38 struct ebitmap_node *node; 40 struct ebitmap_node *node;
39 41
40 if (!selinux_mls_enabled) 42 if (!selinux_mls_enabled)
@@ -42,31 +44,33 @@ int mls_compute_context_len(struct context * context)
42 44
43 len = 1; /* for the beginning ":" */ 45 len = 1; /* for the beginning ":" */
44 for (l = 0; l < 2; l++) { 46 for (l = 0; l < 2; l++) {
45 range = 0; 47 int index_sens = context->range.level[l].sens;
46 len += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); 48 len += strlen(policydb.p_sens_val_to_name[index_sens - 1]);
47
48 ebitmap_for_each_bit(&context->range.level[l].cat, node, i) {
49 if (ebitmap_node_get_bit(node, i)) {
50 if (range) {
51 range++;
52 continue;
53 }
54 49
55 len += strlen(policydb.p_cat_val_to_name[i]) + 1; 50 /* categories */
56 range++; 51 head = -2;
57 } else { 52 prev = -2;
58 if (range > 1) 53 e = &context->range.level[l].cat;
59 len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1; 54 ebitmap_for_each_positive_bit(e, node, i) {
60 range = 0; 55 if (i - prev > 1) {
56 /* one or more negative bits are skipped */
57 if (head != prev) {
58 nm = policydb.p_cat_val_to_name[prev];
59 len += strlen(nm) + 1;
60 }
61 nm = policydb.p_cat_val_to_name[i];
62 len += strlen(nm) + 1;
63 head = i;
61 } 64 }
65 prev = i;
66 }
67 if (prev != head) {
68 nm = policydb.p_cat_val_to_name[prev];
69 len += strlen(nm) + 1;
62 } 70 }
63 /* Handle case where last category is the end of range */
64 if (range > 1)
65 len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1;
66
67 if (l == 0) { 71 if (l == 0) {
68 if (mls_level_eq(&context->range.level[0], 72 if (mls_level_eq(&context->range.level[0],
69 &context->range.level[1])) 73 &context->range.level[1]))
70 break; 74 break;
71 else 75 else
72 len++; 76 len++;
@@ -84,8 +88,9 @@ int mls_compute_context_len(struct context * context)
84void mls_sid_to_context(struct context *context, 88void mls_sid_to_context(struct context *context,
85 char **scontext) 89 char **scontext)
86{ 90{
87 char *scontextp; 91 char *scontextp, *nm;
88 int i, l, range, wrote_sep; 92 int i, l, head, prev;
93 struct ebitmap *e;
89 struct ebitmap_node *node; 94 struct ebitmap_node *node;
90 95
91 if (!selinux_mls_enabled) 96 if (!selinux_mls_enabled)
@@ -97,61 +102,54 @@ void mls_sid_to_context(struct context *context,
97 scontextp++; 102 scontextp++;
98 103
99 for (l = 0; l < 2; l++) { 104 for (l = 0; l < 2; l++) {
100 range = 0;
101 wrote_sep = 0;
102 strcpy(scontextp, 105 strcpy(scontextp,
103 policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); 106 policydb.p_sens_val_to_name[context->range.level[l].sens - 1]);
104 scontextp += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); 107 scontextp += strlen(scontextp);
105 108
106 /* categories */ 109 /* categories */
107 ebitmap_for_each_bit(&context->range.level[l].cat, node, i) { 110 head = -2;
108 if (ebitmap_node_get_bit(node, i)) { 111 prev = -2;
109 if (range) { 112 e = &context->range.level[l].cat;
110 range++; 113 ebitmap_for_each_positive_bit(e, node, i) {
111 continue; 114 if (i - prev > 1) {
112 } 115 /* one or more negative bits are skipped */
113 116 if (prev != head) {
114 if (!wrote_sep) { 117 if (prev - head > 1)
115 *scontextp++ = ':';
116 wrote_sep = 1;
117 } else
118 *scontextp++ = ',';
119 strcpy(scontextp, policydb.p_cat_val_to_name[i]);
120 scontextp += strlen(policydb.p_cat_val_to_name[i]);
121 range++;
122 } else {
123 if (range > 1) {
124 if (range > 2)
125 *scontextp++ = '.'; 118 *scontextp++ = '.';
126 else 119 else
127 *scontextp++ = ','; 120 *scontextp++ = ',';
128 121 nm = policydb.p_cat_val_to_name[prev];
129 strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]); 122 strcpy(scontextp, nm);
130 scontextp += strlen(policydb.p_cat_val_to_name[i - 1]); 123 scontextp += strlen(nm);
131 } 124 }
132 range = 0; 125 if (prev < 0)
126 *scontextp++ = ':';
127 else
128 *scontextp++ = ',';
129 nm = policydb.p_cat_val_to_name[i];
130 strcpy(scontextp, nm);
131 scontextp += strlen(nm);
132 head = i;
133 } 133 }
134 prev = i;
134 } 135 }
135 136
136 /* Handle case where last category is the end of range */ 137 if (prev != head) {
137 if (range > 1) { 138 if (prev - head > 1)
138 if (range > 2)
139 *scontextp++ = '.'; 139 *scontextp++ = '.';
140 else 140 else
141 *scontextp++ = ','; 141 *scontextp++ = ',';
142 142 nm = policydb.p_cat_val_to_name[prev];
143 strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]); 143 strcpy(scontextp, nm);
144 scontextp += strlen(policydb.p_cat_val_to_name[i - 1]); 144 scontextp += strlen(nm);
145 } 145 }
146 146
147 if (l == 0) { 147 if (l == 0) {
148 if (mls_level_eq(&context->range.level[0], 148 if (mls_level_eq(&context->range.level[0],
149 &context->range.level[1])) 149 &context->range.level[1]))
150 break; 150 break;
151 else { 151 else
152 *scontextp = '-'; 152 *scontextp++ = '-';
153 scontextp++;
154 }
155 } 153 }
156 } 154 }
157 155
@@ -190,17 +188,15 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
190 if (!levdatum) 188 if (!levdatum)
191 return 0; 189 return 0;
192 190
193 ebitmap_for_each_bit(&c->range.level[l].cat, node, i) { 191 ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) {
194 if (ebitmap_node_get_bit(node, i)) { 192 if (i > p->p_cats.nprim)
195 if (i > p->p_cats.nprim) 193 return 0;
196 return 0; 194 if (!ebitmap_get_bit(&levdatum->level->cat, i))
197 if (!ebitmap_get_bit(&levdatum->level->cat, i)) 195 /*
198 /* 196 * Category may not be associated with
199 * Category may not be associated with 197 * sensitivity in low level.
200 * sensitivity in low level. 198 */
201 */ 199 return 0;
202 return 0;
203 }
204 } 200 }
205 } 201 }
206 202
@@ -485,18 +481,16 @@ int mls_convert_context(struct policydb *oldp,
485 c->range.level[l].sens = levdatum->level->sens; 481 c->range.level[l].sens = levdatum->level->sens;
486 482
487 ebitmap_init(&bitmap); 483 ebitmap_init(&bitmap);
488 ebitmap_for_each_bit(&c->range.level[l].cat, node, i) { 484 ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) {
489 if (ebitmap_node_get_bit(node, i)) { 485 int rc;
490 int rc; 486
491 487 catdatum = hashtab_search(newp->p_cats.table,
492 catdatum = hashtab_search(newp->p_cats.table, 488 oldp->p_cat_val_to_name[i]);
493 oldp->p_cat_val_to_name[i]); 489 if (!catdatum)
494 if (!catdatum) 490 return -EINVAL;
495 return -EINVAL; 491 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
496 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); 492 if (rc)
497 if (rc) 493 return rc;
498 return rc;
499 }
500 } 494 }
501 ebitmap_destroy(&c->range.level[l].cat); 495 ebitmap_destroy(&c->range.level[l].cat);
502 c->range.level[l].cat = bitmap; 496 c->range.level[l].cat = bitmap;