This source file includes following definitions.
- mls_compute_context_len
- mls_sid_to_context
- mls_level_isvalid
- mls_range_isvalid
- mls_context_isvalid
- mls_context_to_sid
- mls_from_string
- mls_range_set
- mls_setup_user_range
- mls_convert_context
- mls_compute_sid
- mls_export_netlbl_lvl
- mls_import_netlbl_lvl
- mls_export_netlbl_cat
- mls_import_netlbl_cat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <linux/kernel.h>
23 #include <linux/slab.h>
24 #include <linux/string.h>
25 #include <linux/errno.h>
26 #include <net/netlabel.h>
27 #include "sidtab.h"
28 #include "mls.h"
29 #include "policydb.h"
30 #include "services.h"
31
32
33
34
35
36 int mls_compute_context_len(struct policydb *p, struct context *context)
37 {
38 int i, l, len, head, prev;
39 char *nm;
40 struct ebitmap *e;
41 struct ebitmap_node *node;
42
43 if (!p->mls_enabled)
44 return 0;
45
46 len = 1;
47 for (l = 0; l < 2; l++) {
48 int index_sens = context->range.level[l].sens;
49 len += strlen(sym_name(p, SYM_LEVELS, index_sens - 1));
50
51
52 head = -2;
53 prev = -2;
54 e = &context->range.level[l].cat;
55 ebitmap_for_each_positive_bit(e, node, i) {
56 if (i - prev > 1) {
57
58 if (head != prev) {
59 nm = sym_name(p, SYM_CATS, prev);
60 len += strlen(nm) + 1;
61 }
62 nm = sym_name(p, SYM_CATS, i);
63 len += strlen(nm) + 1;
64 head = i;
65 }
66 prev = i;
67 }
68 if (prev != head) {
69 nm = sym_name(p, SYM_CATS, prev);
70 len += strlen(nm) + 1;
71 }
72 if (l == 0) {
73 if (mls_level_eq(&context->range.level[0],
74 &context->range.level[1]))
75 break;
76 else
77 len++;
78 }
79 }
80
81 return len;
82 }
83
84
85
86
87
88
89 void mls_sid_to_context(struct policydb *p,
90 struct context *context,
91 char **scontext)
92 {
93 char *scontextp, *nm;
94 int i, l, head, prev;
95 struct ebitmap *e;
96 struct ebitmap_node *node;
97
98 if (!p->mls_enabled)
99 return;
100
101 scontextp = *scontext;
102
103 *scontextp = ':';
104 scontextp++;
105
106 for (l = 0; l < 2; l++) {
107 strcpy(scontextp, sym_name(p, SYM_LEVELS,
108 context->range.level[l].sens - 1));
109 scontextp += strlen(scontextp);
110
111
112 head = -2;
113 prev = -2;
114 e = &context->range.level[l].cat;
115 ebitmap_for_each_positive_bit(e, node, i) {
116 if (i - prev > 1) {
117
118 if (prev != head) {
119 if (prev - head > 1)
120 *scontextp++ = '.';
121 else
122 *scontextp++ = ',';
123 nm = sym_name(p, SYM_CATS, prev);
124 strcpy(scontextp, nm);
125 scontextp += strlen(nm);
126 }
127 if (prev < 0)
128 *scontextp++ = ':';
129 else
130 *scontextp++ = ',';
131 nm = sym_name(p, SYM_CATS, i);
132 strcpy(scontextp, nm);
133 scontextp += strlen(nm);
134 head = i;
135 }
136 prev = i;
137 }
138
139 if (prev != head) {
140 if (prev - head > 1)
141 *scontextp++ = '.';
142 else
143 *scontextp++ = ',';
144 nm = sym_name(p, SYM_CATS, prev);
145 strcpy(scontextp, nm);
146 scontextp += strlen(nm);
147 }
148
149 if (l == 0) {
150 if (mls_level_eq(&context->range.level[0],
151 &context->range.level[1]))
152 break;
153 else
154 *scontextp++ = '-';
155 }
156 }
157
158 *scontext = scontextp;
159 return;
160 }
161
162 int mls_level_isvalid(struct policydb *p, struct mls_level *l)
163 {
164 struct level_datum *levdatum;
165
166 if (!l->sens || l->sens > p->p_levels.nprim)
167 return 0;
168 levdatum = hashtab_search(p->p_levels.table,
169 sym_name(p, SYM_LEVELS, l->sens - 1));
170 if (!levdatum)
171 return 0;
172
173
174
175
176
177
178 return ebitmap_contains(&levdatum->level->cat, &l->cat,
179 p->p_cats.nprim);
180 }
181
182 int mls_range_isvalid(struct policydb *p, struct mls_range *r)
183 {
184 return (mls_level_isvalid(p, &r->level[0]) &&
185 mls_level_isvalid(p, &r->level[1]) &&
186 mls_level_dom(&r->level[1], &r->level[0]));
187 }
188
189
190
191
192
193 int mls_context_isvalid(struct policydb *p, struct context *c)
194 {
195 struct user_datum *usrdatum;
196
197 if (!p->mls_enabled)
198 return 1;
199
200 if (!mls_range_isvalid(p, &c->range))
201 return 0;
202
203 if (c->role == OBJECT_R_VAL)
204 return 1;
205
206
207
208
209 if (!c->user || c->user > p->p_users.nprim)
210 return 0;
211 usrdatum = p->user_val_to_struct[c->user - 1];
212 if (!mls_range_contains(usrdatum->range, c->range))
213 return 0;
214
215 return 1;
216 }
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234 int mls_context_to_sid(struct policydb *pol,
235 char oldc,
236 char *scontext,
237 struct context *context,
238 struct sidtab *s,
239 u32 def_sid)
240 {
241 char *sensitivity, *cur_cat, *next_cat, *rngptr;
242 struct level_datum *levdatum;
243 struct cat_datum *catdatum, *rngdatum;
244 int l, rc, i;
245 char *rangep[2];
246
247 if (!pol->mls_enabled) {
248
249
250
251
252 if (oldc && def_sid == SECSID_NULL)
253 return -EINVAL;
254 return 0;
255 }
256
257
258
259
260
261 if (!oldc) {
262 struct context *defcon;
263
264 if (def_sid == SECSID_NULL)
265 return -EINVAL;
266
267 defcon = sidtab_search(s, def_sid);
268 if (!defcon)
269 return -EINVAL;
270
271 return mls_context_cpy(context, defcon);
272 }
273
274
275
276
277
278 rangep[0] = scontext;
279 rangep[1] = strchr(scontext, '-');
280 if (rangep[1]) {
281 rangep[1][0] = '\0';
282 rangep[1]++;
283 }
284
285
286 for (l = 0; l < 2; l++) {
287
288 sensitivity = rangep[l];
289 if (sensitivity == NULL)
290 break;
291 next_cat = strchr(sensitivity, ':');
292 if (next_cat)
293 *(next_cat++) = '\0';
294
295
296 levdatum = hashtab_search(pol->p_levels.table, sensitivity);
297 if (!levdatum)
298 return -EINVAL;
299 context->range.level[l].sens = levdatum->level->sens;
300
301
302 while (next_cat != NULL) {
303 cur_cat = next_cat;
304 next_cat = strchr(next_cat, ',');
305 if (next_cat != NULL)
306 *(next_cat++) = '\0';
307
308
309 rngptr = strchr(cur_cat, '.');
310 if (rngptr != NULL) {
311
312 *rngptr++ = '\0';
313 }
314
315 catdatum = hashtab_search(pol->p_cats.table, cur_cat);
316 if (!catdatum)
317 return -EINVAL;
318
319 rc = ebitmap_set_bit(&context->range.level[l].cat,
320 catdatum->value - 1, 1);
321 if (rc)
322 return rc;
323
324
325 if (rngptr == NULL)
326 continue;
327
328 rngdatum = hashtab_search(pol->p_cats.table, rngptr);
329 if (!rngdatum)
330 return -EINVAL;
331
332 if (catdatum->value >= rngdatum->value)
333 return -EINVAL;
334
335 for (i = catdatum->value; i < rngdatum->value; i++) {
336 rc = ebitmap_set_bit(&context->range.level[l].cat, i, 1);
337 if (rc)
338 return rc;
339 }
340 }
341 }
342
343
344 if (rangep[1] == NULL) {
345 context->range.level[1].sens = context->range.level[0].sens;
346 rc = ebitmap_cpy(&context->range.level[1].cat,
347 &context->range.level[0].cat);
348 if (rc)
349 return rc;
350 }
351
352 return 0;
353 }
354
355
356
357
358
359
360
361 int mls_from_string(struct policydb *p, char *str, struct context *context,
362 gfp_t gfp_mask)
363 {
364 char *tmpstr;
365 int rc;
366
367 if (!p->mls_enabled)
368 return -EINVAL;
369
370 tmpstr = kstrdup(str, gfp_mask);
371 if (!tmpstr) {
372 rc = -ENOMEM;
373 } else {
374 rc = mls_context_to_sid(p, ':', tmpstr, context,
375 NULL, SECSID_NULL);
376 kfree(tmpstr);
377 }
378
379 return rc;
380 }
381
382
383
384
385 int mls_range_set(struct context *context,
386 struct mls_range *range)
387 {
388 int l, rc = 0;
389
390
391 for (l = 0; l < 2; l++) {
392 context->range.level[l].sens = range->level[l].sens;
393 rc = ebitmap_cpy(&context->range.level[l].cat,
394 &range->level[l].cat);
395 if (rc)
396 break;
397 }
398
399 return rc;
400 }
401
402 int mls_setup_user_range(struct policydb *p,
403 struct context *fromcon, struct user_datum *user,
404 struct context *usercon)
405 {
406 if (p->mls_enabled) {
407 struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
408 struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
409 struct mls_level *user_low = &(user->range.level[0]);
410 struct mls_level *user_clr = &(user->range.level[1]);
411 struct mls_level *user_def = &(user->dfltlevel);
412 struct mls_level *usercon_sen = &(usercon->range.level[0]);
413 struct mls_level *usercon_clr = &(usercon->range.level[1]);
414
415
416 if (mls_level_between(user_def, fromcon_sen, fromcon_clr))
417 *usercon_sen = *user_def;
418 else if (mls_level_between(fromcon_sen, user_def, user_clr))
419 *usercon_sen = *fromcon_sen;
420 else if (mls_level_between(fromcon_clr, user_low, user_def))
421 *usercon_sen = *user_low;
422 else
423 return -EINVAL;
424
425
426
427
428
429
430 if (mls_level_dom(user_clr, fromcon_clr))
431 *usercon_clr = *fromcon_clr;
432 else if (mls_level_dom(fromcon_clr, user_clr))
433 *usercon_clr = *user_clr;
434 else
435 return -EINVAL;
436 }
437
438 return 0;
439 }
440
441
442
443
444
445
446
447 int mls_convert_context(struct policydb *oldp,
448 struct policydb *newp,
449 struct context *oldc,
450 struct context *newc)
451 {
452 struct level_datum *levdatum;
453 struct cat_datum *catdatum;
454 struct ebitmap_node *node;
455 int l, i;
456
457 if (!oldp->mls_enabled || !newp->mls_enabled)
458 return 0;
459
460 for (l = 0; l < 2; l++) {
461 levdatum = hashtab_search(newp->p_levels.table,
462 sym_name(oldp, SYM_LEVELS,
463 oldc->range.level[l].sens - 1));
464
465 if (!levdatum)
466 return -EINVAL;
467 newc->range.level[l].sens = levdatum->level->sens;
468
469 ebitmap_for_each_positive_bit(&oldc->range.level[l].cat,
470 node, i) {
471 int rc;
472
473 catdatum = hashtab_search(newp->p_cats.table,
474 sym_name(oldp, SYM_CATS, i));
475 if (!catdatum)
476 return -EINVAL;
477 rc = ebitmap_set_bit(&newc->range.level[l].cat,
478 catdatum->value - 1, 1);
479 if (rc)
480 return rc;
481 }
482 }
483
484 return 0;
485 }
486
487 int mls_compute_sid(struct policydb *p,
488 struct context *scontext,
489 struct context *tcontext,
490 u16 tclass,
491 u32 specified,
492 struct context *newcontext,
493 bool sock)
494 {
495 struct range_trans rtr;
496 struct mls_range *r;
497 struct class_datum *cladatum;
498 int default_range = 0;
499
500 if (!p->mls_enabled)
501 return 0;
502
503 switch (specified) {
504 case AVTAB_TRANSITION:
505
506 rtr.source_type = scontext->type;
507 rtr.target_type = tcontext->type;
508 rtr.target_class = tclass;
509 r = hashtab_search(p->range_tr, &rtr);
510 if (r)
511 return mls_range_set(newcontext, r);
512
513 if (tclass && tclass <= p->p_classes.nprim) {
514 cladatum = p->class_val_to_struct[tclass - 1];
515 if (cladatum)
516 default_range = cladatum->default_range;
517 }
518
519 switch (default_range) {
520 case DEFAULT_SOURCE_LOW:
521 return mls_context_cpy_low(newcontext, scontext);
522 case DEFAULT_SOURCE_HIGH:
523 return mls_context_cpy_high(newcontext, scontext);
524 case DEFAULT_SOURCE_LOW_HIGH:
525 return mls_context_cpy(newcontext, scontext);
526 case DEFAULT_TARGET_LOW:
527 return mls_context_cpy_low(newcontext, tcontext);
528 case DEFAULT_TARGET_HIGH:
529 return mls_context_cpy_high(newcontext, tcontext);
530 case DEFAULT_TARGET_LOW_HIGH:
531 return mls_context_cpy(newcontext, tcontext);
532 }
533
534
535 case AVTAB_CHANGE:
536 if ((tclass == p->process_class) || (sock == true))
537
538 return mls_context_cpy(newcontext, scontext);
539 else
540
541 return mls_context_cpy_low(newcontext, scontext);
542 case AVTAB_MEMBER:
543
544 return mls_context_cpy_low(newcontext, scontext);
545
546
547 }
548 return -EINVAL;
549 }
550
551 #ifdef CONFIG_NETLABEL
552
553
554
555
556
557
558
559
560
561
562 void mls_export_netlbl_lvl(struct policydb *p,
563 struct context *context,
564 struct netlbl_lsm_secattr *secattr)
565 {
566 if (!p->mls_enabled)
567 return;
568
569 secattr->attr.mls.lvl = context->range.level[0].sens - 1;
570 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
571 }
572
573
574
575
576
577
578
579
580
581
582
583 void mls_import_netlbl_lvl(struct policydb *p,
584 struct context *context,
585 struct netlbl_lsm_secattr *secattr)
586 {
587 if (!p->mls_enabled)
588 return;
589
590 context->range.level[0].sens = secattr->attr.mls.lvl + 1;
591 context->range.level[1].sens = context->range.level[0].sens;
592 }
593
594
595
596
597
598
599
600
601
602
603
604 int mls_export_netlbl_cat(struct policydb *p,
605 struct context *context,
606 struct netlbl_lsm_secattr *secattr)
607 {
608 int rc;
609
610 if (!p->mls_enabled)
611 return 0;
612
613 rc = ebitmap_netlbl_export(&context->range.level[0].cat,
614 &secattr->attr.mls.cat);
615 if (rc == 0 && secattr->attr.mls.cat != NULL)
616 secattr->flags |= NETLBL_SECATTR_MLS_CAT;
617
618 return rc;
619 }
620
621
622
623
624
625
626
627
628
629
630
631
632
633 int mls_import_netlbl_cat(struct policydb *p,
634 struct context *context,
635 struct netlbl_lsm_secattr *secattr)
636 {
637 int rc;
638
639 if (!p->mls_enabled)
640 return 0;
641
642 rc = ebitmap_netlbl_import(&context->range.level[0].cat,
643 secattr->attr.mls.cat);
644 if (rc)
645 goto import_netlbl_cat_failure;
646 memcpy(&context->range.level[1].cat, &context->range.level[0].cat,
647 sizeof(context->range.level[0].cat));
648
649 return 0;
650
651 import_netlbl_cat_failure:
652 ebitmap_destroy(&context->range.level[0].cat);
653 return rc;
654 }
655 #endif