Branch data Line data Source code
1 : : /*
2 : : * Implementation of the multi-level security (MLS) policy.
3 : : *
4 : : * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
5 : : */
6 : : /*
7 : : * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
8 : : *
9 : : * Support for enhanced MLS infrastructure.
10 : : *
11 : : * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
12 : : */
13 : : /*
14 : : * Updated: Hewlett-Packard <paul@paul-moore.com>
15 : : *
16 : : * Added support to import/export the MLS label from NetLabel
17 : : *
18 : : * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
19 : : */
20 : :
21 : : #include <linux/kernel.h>
22 : : #include <linux/slab.h>
23 : : #include <linux/string.h>
24 : : #include <linux/errno.h>
25 : : #include <net/netlabel.h>
26 : : #include "sidtab.h"
27 : : #include "mls.h"
28 : : #include "policydb.h"
29 : : #include "services.h"
30 : :
31 : : /*
32 : : * Return the length in bytes for the MLS fields of the
33 : : * security context string representation of `context'.
34 : : */
35 : 0 : int mls_compute_context_len(struct context *context)
36 : : {
37 : : int i, l, len, head, prev;
38 : : char *nm;
39 : : struct ebitmap *e;
40 : : struct ebitmap_node *node;
41 : :
42 [ # # ]: 0 : if (!policydb.mls_enabled)
43 : : return 0;
44 : :
45 : : len = 1; /* for the beginning ":" */
46 [ # # ]: 0 : for (l = 0; l < 2; l++) {
47 : 0 : int index_sens = context->range.level[l].sens;
48 : 0 : len += strlen(sym_name(&policydb, SYM_LEVELS, index_sens - 1));
49 : :
50 : : /* categories */
51 : : head = -2;
52 : : prev = -2;
53 : 0 : e = &context->range.level[l].cat;
54 [ # # ]: 0 : ebitmap_for_each_positive_bit(e, node, i) {
55 [ # # ]: 0 : if (i - prev > 1) {
56 : : /* one or more negative bits are skipped */
57 [ # # ]: 0 : if (head != prev) {
58 : 0 : nm = sym_name(&policydb, SYM_CATS, prev);
59 : 0 : len += strlen(nm) + 1;
60 : : }
61 : : nm = sym_name(&policydb, SYM_CATS, i);
62 : 0 : len += strlen(nm) + 1;
63 : : head = i;
64 : : }
65 : : prev = i;
66 : : }
67 [ # # ]: 0 : if (prev != head) {
68 : 0 : nm = sym_name(&policydb, SYM_CATS, prev);
69 : 0 : len += strlen(nm) + 1;
70 : : }
71 [ # # ]: 0 : if (l == 0) {
72 [ # # ]: 0 : if (mls_level_eq(&context->range.level[0],
73 : : &context->range.level[1]))
74 : : break;
75 : : else
76 : 0 : len++;
77 : : }
78 : : }
79 : :
80 : 0 : return len;
81 : : }
82 : :
83 : : /*
84 : : * Write the security context string representation of
85 : : * the MLS fields of `context' into the string `*scontext'.
86 : : * Update `*scontext' to point to the end of the MLS fields.
87 : : */
88 : 0 : void mls_sid_to_context(struct context *context,
89 : : char **scontext)
90 : : {
91 : : char *scontextp, *nm;
92 : : int i, l, head, prev;
93 : : struct ebitmap *e;
94 : : struct ebitmap_node *node;
95 : :
96 [ # # ]: 0 : if (!policydb.mls_enabled)
97 : : return;
98 : :
99 : 0 : scontextp = *scontext;
100 : :
101 : 0 : *scontextp = ':';
102 : 0 : scontextp++;
103 : :
104 [ # # ]: 0 : for (l = 0; l < 2; l++) {
105 : 0 : strcpy(scontextp, sym_name(&policydb, SYM_LEVELS,
106 : 0 : context->range.level[l].sens - 1));
107 : 0 : scontextp += strlen(scontextp);
108 : :
109 : : /* categories */
110 : : head = -2;
111 : : prev = -2;
112 : 0 : e = &context->range.level[l].cat;
113 [ # # ]: 0 : ebitmap_for_each_positive_bit(e, node, i) {
114 [ # # ]: 0 : if (i - prev > 1) {
115 : : /* one or more negative bits are skipped */
116 [ # # ]: 0 : if (prev != head) {
117 [ # # ]: 0 : if (prev - head > 1)
118 : 0 : *scontextp++ = '.';
119 : : else
120 : 0 : *scontextp++ = ',';
121 : 0 : nm = sym_name(&policydb, SYM_CATS, prev);
122 : 0 : strcpy(scontextp, nm);
123 : 0 : scontextp += strlen(nm);
124 : : }
125 [ # # ]: 0 : if (prev < 0)
126 : 0 : *scontextp++ = ':';
127 : : else
128 : 0 : *scontextp++ = ',';
129 : : nm = sym_name(&policydb, SYM_CATS, i);
130 : 0 : strcpy(scontextp, nm);
131 : 0 : scontextp += strlen(nm);
132 : : head = i;
133 : : }
134 : : prev = i;
135 : : }
136 : :
137 [ # # ]: 0 : if (prev != head) {
138 [ # # ]: 0 : if (prev - head > 1)
139 : 0 : *scontextp++ = '.';
140 : : else
141 : 0 : *scontextp++ = ',';
142 : 0 : nm = sym_name(&policydb, SYM_CATS, prev);
143 : 0 : strcpy(scontextp, nm);
144 : 0 : scontextp += strlen(nm);
145 : : }
146 : :
147 [ # # ]: 0 : if (l == 0) {
148 [ # # ]: 0 : if (mls_level_eq(&context->range.level[0],
149 : : &context->range.level[1]))
150 : : break;
151 : : else
152 : 0 : *scontextp++ = '-';
153 : : }
154 : : }
155 : :
156 : 0 : *scontext = scontextp;
157 : 0 : return;
158 : : }
159 : :
160 : 0 : int mls_level_isvalid(struct policydb *p, struct mls_level *l)
161 : : {
162 : : struct level_datum *levdatum;
163 : :
164 [ # # ][ # # ]: 0 : if (!l->sens || l->sens > p->p_levels.nprim)
165 : : return 0;
166 : 0 : levdatum = hashtab_search(p->p_levels.table,
167 : 0 : sym_name(p, SYM_LEVELS, l->sens - 1));
168 [ # # ]: 0 : if (!levdatum)
169 : : return 0;
170 : :
171 : : /*
172 : : * Return 1 iff all the bits set in l->cat are also be set in
173 : : * levdatum->level->cat and no bit in l->cat is larger than
174 : : * p->p_cats.nprim.
175 : : */
176 : 0 : return ebitmap_contains(&levdatum->level->cat, &l->cat,
177 : : p->p_cats.nprim);
178 : : }
179 : :
180 : 0 : int mls_range_isvalid(struct policydb *p, struct mls_range *r)
181 : : {
182 [ # # ]: 0 : return (mls_level_isvalid(p, &r->level[0]) &&
183 [ # # ][ # # ]: 0 : mls_level_isvalid(p, &r->level[1]) &&
184 : : mls_level_dom(&r->level[1], &r->level[0]));
185 : : }
186 : :
187 : : /*
188 : : * Return 1 if the MLS fields in the security context
189 : : * structure `c' are valid. Return 0 otherwise.
190 : : */
191 : 0 : int mls_context_isvalid(struct policydb *p, struct context *c)
192 : : {
193 : : struct user_datum *usrdatum;
194 : :
195 [ # # ]: 0 : if (!p->mls_enabled)
196 : : return 1;
197 : :
198 [ # # ]: 0 : if (!mls_range_isvalid(p, &c->range))
199 : : return 0;
200 : :
201 [ # # ]: 0 : if (c->role == OBJECT_R_VAL)
202 : : return 1;
203 : :
204 : : /*
205 : : * User must be authorized for the MLS range.
206 : : */
207 [ # # ][ # # ]: 0 : if (!c->user || c->user > p->p_users.nprim)
208 : : return 0;
209 : 0 : usrdatum = p->user_val_to_struct[c->user - 1];
210 [ # # ][ # # ]: 0 : if (!mls_range_contains(usrdatum->range, c->range))
211 : : return 0; /* user may not be associated with range */
212 : :
213 : : return 1;
214 : : }
215 : :
216 : : /*
217 : : * Set the MLS fields in the security context structure
218 : : * `context' based on the string representation in
219 : : * the string `*scontext'. Update `*scontext' to
220 : : * point to the end of the string representation of
221 : : * the MLS fields.
222 : : *
223 : : * This function modifies the string in place, inserting
224 : : * NULL characters to terminate the MLS fields.
225 : : *
226 : : * If a def_sid is provided and no MLS field is present,
227 : : * copy the MLS field of the associated default context.
228 : : * Used for upgraded to MLS systems where objects may lack
229 : : * MLS fields.
230 : : *
231 : : * Policy read-lock must be held for sidtab lookup.
232 : : *
233 : : */
234 : 0 : 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 : :
242 : : char delim;
243 : : char *scontextp, *p, *rngptr;
244 : : struct level_datum *levdatum;
245 : : struct cat_datum *catdatum, *rngdatum;
246 : : int l, rc = -EINVAL;
247 : :
248 [ # # ]: 0 : if (!pol->mls_enabled) {
249 [ # # ]: 0 : if (def_sid != SECSID_NULL && oldc)
250 : 0 : *scontext += strlen(*scontext) + 1;
251 : : return 0;
252 : : }
253 : :
254 : : /*
255 : : * No MLS component to the security context, try and map to
256 : : * default if provided.
257 : : */
258 [ # # ]: 0 : if (!oldc) {
259 : : struct context *defcon;
260 : :
261 [ # # ]: 0 : if (def_sid == SECSID_NULL)
262 : : goto out;
263 : :
264 : 0 : defcon = sidtab_search(s, def_sid);
265 [ # # ]: 0 : if (!defcon)
266 : : goto out;
267 : :
268 : : rc = mls_context_cpy(context, defcon);
269 : 0 : goto out;
270 : : }
271 : :
272 : : /* Extract low sensitivity. */
273 : 0 : scontextp = p = *scontext;
274 [ # # ][ # # ]: 0 : while (*p && *p != ':' && *p != '-')
275 : 0 : p++;
276 : :
277 : : delim = *p;
278 [ # # ]: 0 : if (delim != '\0')
279 : 0 : *p++ = '\0';
280 : :
281 [ # # ]: 0 : for (l = 0; l < 2; l++) {
282 : 0 : levdatum = hashtab_search(pol->p_levels.table, scontextp);
283 [ # # ]: 0 : if (!levdatum) {
284 : : rc = -EINVAL;
285 : : goto out;
286 : : }
287 : :
288 : 0 : context->range.level[l].sens = levdatum->level->sens;
289 : :
290 [ # # ]: 0 : if (delim == ':') {
291 : : /* Extract category set. */
292 : : while (1) {
293 : : scontextp = p;
294 [ # # ][ # # ]: 0 : while (*p && *p != ',' && *p != '-')
295 : 0 : p++;
296 : : delim = *p;
297 [ # # ]: 0 : if (delim != '\0')
298 : 0 : *p++ = '\0';
299 : :
300 : : /* Separate into range if exists */
301 : 0 : rngptr = strchr(scontextp, '.');
302 [ # # ]: 0 : if (rngptr != NULL) {
303 : : /* Remove '.' */
304 : 0 : *rngptr++ = '\0';
305 : : }
306 : :
307 : 0 : catdatum = hashtab_search(pol->p_cats.table,
308 : : scontextp);
309 [ # # ]: 0 : if (!catdatum) {
310 : : rc = -EINVAL;
311 : : goto out;
312 : : }
313 : :
314 : 0 : rc = ebitmap_set_bit(&context->range.level[l].cat,
315 : 0 : catdatum->value - 1, 1);
316 [ # # ]: 0 : if (rc)
317 : : goto out;
318 : :
319 : : /* If range, set all categories in range */
320 [ # # ]: 0 : if (rngptr) {
321 : : int i;
322 : :
323 : 0 : rngdatum = hashtab_search(pol->p_cats.table, rngptr);
324 [ # # ]: 0 : if (!rngdatum) {
325 : : rc = -EINVAL;
326 : : goto out;
327 : : }
328 : :
329 [ # # ]: 0 : if (catdatum->value >= rngdatum->value) {
330 : : rc = -EINVAL;
331 : : goto out;
332 : : }
333 : :
334 [ # # ]: 0 : for (i = catdatum->value; i < rngdatum->value; i++) {
335 : 0 : rc = ebitmap_set_bit(&context->range.level[l].cat, i, 1);
336 [ # # ]: 0 : if (rc)
337 : : goto out;
338 : : }
339 : : }
340 : :
341 [ # # ]: 0 : if (delim != ',')
342 : : break;
343 : : }
344 : : }
345 [ # # ]: 0 : if (delim == '-') {
346 : : /* Extract high sensitivity. */
347 : : scontextp = p;
348 [ # # ]: 0 : while (*p && *p != ':')
349 : 0 : p++;
350 : :
351 : : delim = *p;
352 [ # # ]: 0 : if (delim != '\0')
353 : 0 : *p++ = '\0';
354 : : } else
355 : : break;
356 : : }
357 : :
358 [ # # ]: 0 : if (l == 0) {
359 : 0 : context->range.level[1].sens = context->range.level[0].sens;
360 : 0 : rc = ebitmap_cpy(&context->range.level[1].cat,
361 : : &context->range.level[0].cat);
362 [ # # ]: 0 : if (rc)
363 : : goto out;
364 : : }
365 : 0 : *scontext = ++p;
366 : : rc = 0;
367 : : out:
368 : 0 : return rc;
369 : : }
370 : :
371 : : /*
372 : : * Set the MLS fields in the security context structure
373 : : * `context' based on the string representation in
374 : : * the string `str'. This function will allocate temporary memory with the
375 : : * given constraints of gfp_mask.
376 : : */
377 : 0 : int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
378 : : {
379 : : char *tmpstr, *freestr;
380 : : int rc;
381 : :
382 [ # # ]: 0 : if (!policydb.mls_enabled)
383 : : return -EINVAL;
384 : :
385 : : /* we need freestr because mls_context_to_sid will change
386 : : the value of tmpstr */
387 : 0 : tmpstr = freestr = kstrdup(str, gfp_mask);
388 [ # # ]: 0 : if (!tmpstr) {
389 : : rc = -ENOMEM;
390 : : } else {
391 : 0 : rc = mls_context_to_sid(&policydb, ':', &tmpstr, context,
392 : : NULL, SECSID_NULL);
393 : 0 : kfree(freestr);
394 : : }
395 : :
396 : 0 : return rc;
397 : : }
398 : :
399 : : /*
400 : : * Copies the MLS range `range' into `context'.
401 : : */
402 : 0 : int mls_range_set(struct context *context,
403 : : struct mls_range *range)
404 : : {
405 : : int l, rc = 0;
406 : :
407 : : /* Copy the MLS range into the context */
408 [ # # ]: 0 : for (l = 0; l < 2; l++) {
409 : 0 : context->range.level[l].sens = range->level[l].sens;
410 : 0 : rc = ebitmap_cpy(&context->range.level[l].cat,
411 : : &range->level[l].cat);
412 [ # # ]: 0 : if (rc)
413 : : break;
414 : : }
415 : :
416 : 0 : return rc;
417 : : }
418 : :
419 : 0 : int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
420 : : struct context *usercon)
421 : : {
422 [ # # ]: 0 : if (policydb.mls_enabled) {
423 : : struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
424 : : struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
425 : : struct mls_level *user_low = &(user->range.level[0]);
426 : : struct mls_level *user_clr = &(user->range.level[1]);
427 : : struct mls_level *user_def = &(user->dfltlevel);
428 : : struct mls_level *usercon_sen = &(usercon->range.level[0]);
429 : : struct mls_level *usercon_clr = &(usercon->range.level[1]);
430 : :
431 : : /* Honor the user's default level if we can */
432 [ # # ][ # # ]: 0 : if (mls_level_between(user_def, fromcon_sen, fromcon_clr))
433 : 0 : *usercon_sen = *user_def;
434 [ # # ][ # # ]: 0 : else if (mls_level_between(fromcon_sen, user_def, user_clr))
435 : 0 : *usercon_sen = *fromcon_sen;
436 [ # # ][ # # ]: 0 : else if (mls_level_between(fromcon_clr, user_low, user_def))
437 : 0 : *usercon_sen = *user_low;
438 : : else
439 : : return -EINVAL;
440 : :
441 : : /* Lower the clearance of available contexts
442 : : if the clearance of "fromcon" is lower than
443 : : that of the user's default clearance (but
444 : : only if the "fromcon" clearance dominates
445 : : the user's computed sensitivity level) */
446 [ # # ]: 0 : if (mls_level_dom(user_clr, fromcon_clr))
447 : 0 : *usercon_clr = *fromcon_clr;
448 [ # # ]: 0 : else if (mls_level_dom(fromcon_clr, user_clr))
449 : 0 : *usercon_clr = *user_clr;
450 : : else
451 : : return -EINVAL;
452 : : }
453 : :
454 : : return 0;
455 : : }
456 : :
457 : : /*
458 : : * Convert the MLS fields in the security context
459 : : * structure `c' from the values specified in the
460 : : * policy `oldp' to the values specified in the policy `newp'.
461 : : */
462 : 0 : int mls_convert_context(struct policydb *oldp,
463 : : struct policydb *newp,
464 : : struct context *c)
465 : : {
466 : : struct level_datum *levdatum;
467 : : struct cat_datum *catdatum;
468 : : struct ebitmap bitmap;
469 : : struct ebitmap_node *node;
470 : : int l, i;
471 : :
472 [ # # ]: 0 : if (!policydb.mls_enabled)
473 : : return 0;
474 : :
475 [ # # ]: 0 : for (l = 0; l < 2; l++) {
476 : 0 : levdatum = hashtab_search(newp->p_levels.table,
477 : 0 : sym_name(oldp, SYM_LEVELS,
478 : 0 : c->range.level[l].sens - 1));
479 : :
480 [ # # ]: 0 : if (!levdatum)
481 : : return -EINVAL;
482 : 0 : c->range.level[l].sens = levdatum->level->sens;
483 : :
484 : : ebitmap_init(&bitmap);
485 [ # # ]: 0 : ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) {
486 : : int rc;
487 : :
488 : 0 : catdatum = hashtab_search(newp->p_cats.table,
489 : : sym_name(oldp, SYM_CATS, i));
490 [ # # ]: 0 : if (!catdatum)
491 : : return -EINVAL;
492 : 0 : rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
493 [ # # ]: 0 : if (rc)
494 : : return rc;
495 : : }
496 : 0 : ebitmap_destroy(&c->range.level[l].cat);
497 : 0 : c->range.level[l].cat = bitmap;
498 : : }
499 : :
500 : : return 0;
501 : : }
502 : :
503 : 0 : int mls_compute_sid(struct context *scontext,
504 : : struct context *tcontext,
505 : : u16 tclass,
506 : : u32 specified,
507 : : struct context *newcontext,
508 : : bool sock)
509 : : {
510 : : struct range_trans rtr;
511 : : struct mls_range *r;
512 : : struct class_datum *cladatum;
513 : : int default_range = 0;
514 : :
515 [ # # ]: 0 : if (!policydb.mls_enabled)
516 : : return 0;
517 : :
518 [ # # # # ]: 0 : switch (specified) {
519 : : case AVTAB_TRANSITION:
520 : : /* Look for a range transition rule. */
521 : 0 : rtr.source_type = scontext->type;
522 : 0 : rtr.target_type = tcontext->type;
523 : 0 : rtr.target_class = tclass;
524 : 0 : r = hashtab_search(policydb.range_tr, &rtr);
525 [ # # ]: 0 : if (r)
526 : 0 : return mls_range_set(newcontext, r);
527 : :
528 [ # # ][ # # ]: 0 : if (tclass && tclass <= policydb.p_classes.nprim) {
529 : 0 : cladatum = policydb.class_val_to_struct[tclass - 1];
530 [ # # ]: 0 : if (cladatum)
531 : 0 : default_range = cladatum->default_range;
532 : : }
533 : :
534 [ # # # # : 0 : switch (default_range) {
# # # ]
535 : : case DEFAULT_SOURCE_LOW:
536 : 0 : return mls_context_cpy_low(newcontext, scontext);
537 : : case DEFAULT_SOURCE_HIGH:
538 : 0 : return mls_context_cpy_high(newcontext, scontext);
539 : : case DEFAULT_SOURCE_LOW_HIGH:
540 : 0 : return mls_context_cpy(newcontext, scontext);
541 : : case DEFAULT_TARGET_LOW:
542 : 0 : return mls_context_cpy_low(newcontext, tcontext);
543 : : case DEFAULT_TARGET_HIGH:
544 : 0 : return mls_context_cpy_high(newcontext, tcontext);
545 : : case DEFAULT_TARGET_LOW_HIGH:
546 : 0 : return mls_context_cpy(newcontext, tcontext);
547 : : }
548 : :
549 : : /* Fallthrough */
550 : : case AVTAB_CHANGE:
551 [ # # ][ # # ]: 0 : if ((tclass == policydb.process_class) || (sock == true))
552 : : /* Use the process MLS attributes. */
553 : 0 : return mls_context_cpy(newcontext, scontext);
554 : : else
555 : : /* Use the process effective MLS attributes. */
556 : 0 : return mls_context_cpy_low(newcontext, scontext);
557 : : case AVTAB_MEMBER:
558 : : /* Use the process effective MLS attributes. */
559 : 0 : return mls_context_cpy_low(newcontext, scontext);
560 : :
561 : : /* fall through */
562 : : }
563 : : return -EINVAL;
564 : : }
565 : :
566 : : #ifdef CONFIG_NETLABEL
567 : : /**
568 : : * mls_export_netlbl_lvl - Export the MLS sensitivity levels to NetLabel
569 : : * @context: the security context
570 : : * @secattr: the NetLabel security attributes
571 : : *
572 : : * Description:
573 : : * Given the security context copy the low MLS sensitivity level into the
574 : : * NetLabel MLS sensitivity level field.
575 : : *
576 : : */
577 : 0 : void mls_export_netlbl_lvl(struct context *context,
578 : : struct netlbl_lsm_secattr *secattr)
579 : : {
580 [ # # ]: 0 : if (!policydb.mls_enabled)
581 : 0 : return;
582 : :
583 : 0 : secattr->attr.mls.lvl = context->range.level[0].sens - 1;
584 : 0 : secattr->flags |= NETLBL_SECATTR_MLS_LVL;
585 : : }
586 : :
587 : : /**
588 : : * mls_import_netlbl_lvl - Import the NetLabel MLS sensitivity levels
589 : : * @context: the security context
590 : : * @secattr: the NetLabel security attributes
591 : : *
592 : : * Description:
593 : : * Given the security context and the NetLabel security attributes, copy the
594 : : * NetLabel MLS sensitivity level into the context.
595 : : *
596 : : */
597 : 0 : void mls_import_netlbl_lvl(struct context *context,
598 : : struct netlbl_lsm_secattr *secattr)
599 : : {
600 [ # # ]: 0 : if (!policydb.mls_enabled)
601 : 0 : return;
602 : :
603 : 0 : context->range.level[0].sens = secattr->attr.mls.lvl + 1;
604 : 0 : context->range.level[1].sens = context->range.level[0].sens;
605 : : }
606 : :
607 : : /**
608 : : * mls_export_netlbl_cat - Export the MLS categories to NetLabel
609 : : * @context: the security context
610 : : * @secattr: the NetLabel security attributes
611 : : *
612 : : * Description:
613 : : * Given the security context copy the low MLS categories into the NetLabel
614 : : * MLS category field. Returns zero on success, negative values on failure.
615 : : *
616 : : */
617 : 0 : int mls_export_netlbl_cat(struct context *context,
618 : : struct netlbl_lsm_secattr *secattr)
619 : : {
620 : : int rc;
621 : :
622 [ # # ]: 0 : if (!policydb.mls_enabled)
623 : : return 0;
624 : :
625 : 0 : rc = ebitmap_netlbl_export(&context->range.level[0].cat,
626 : : &secattr->attr.mls.cat);
627 [ # # ][ # # ]: 0 : if (rc == 0 && secattr->attr.mls.cat != NULL)
628 : 0 : secattr->flags |= NETLBL_SECATTR_MLS_CAT;
629 : :
630 : 0 : return rc;
631 : : }
632 : :
633 : : /**
634 : : * mls_import_netlbl_cat - Import the MLS categories from NetLabel
635 : : * @context: the security context
636 : : * @secattr: the NetLabel security attributes
637 : : *
638 : : * Description:
639 : : * Copy the NetLabel security attributes into the SELinux context; since the
640 : : * NetLabel security attribute only contains a single MLS category use it for
641 : : * both the low and high categories of the context. Returns zero on success,
642 : : * negative values on failure.
643 : : *
644 : : */
645 : 0 : int mls_import_netlbl_cat(struct context *context,
646 : : struct netlbl_lsm_secattr *secattr)
647 : : {
648 : : int rc;
649 : :
650 [ # # ]: 0 : if (!policydb.mls_enabled)
651 : : return 0;
652 : :
653 : 0 : rc = ebitmap_netlbl_import(&context->range.level[0].cat,
654 : : secattr->attr.mls.cat);
655 [ # # ]: 0 : if (rc != 0)
656 : : goto import_netlbl_cat_failure;
657 : :
658 : 0 : rc = ebitmap_cpy(&context->range.level[1].cat,
659 : : &context->range.level[0].cat);
660 [ # # ]: 0 : if (rc != 0)
661 : : goto import_netlbl_cat_failure;
662 : :
663 : : return 0;
664 : :
665 : : import_netlbl_cat_failure:
666 : 0 : ebitmap_destroy(&context->range.level[0].cat);
667 : 0 : ebitmap_destroy(&context->range.level[1].cat);
668 : 0 : return rc;
669 : : }
670 : : #endif /* CONFIG_NETLABEL */
|