1 /*
2 * Implementation of the security services.
3 *
4 * Authors : Stephen Smalley, <sds@epoch.ncsc.mil>
5 * James Morris <jmorris@redhat.com>
6 *
7 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
8 *
9 * Support for enhanced MLS infrastructure.
10 *
11 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
12 *
13 * Added conditional policy language extensions
14 *
15 * Updated: Hewlett-Packard <paul.moore@hp.com>
16 *
17 * Added support for the policy capability bitmap
18 *
19 * Updated: Chad Sellers <csellers@tresys.com>
20 *
21 * Added validation of kernel classes and permissions
22 *
23 * Updated: KaiGai Kohei <kaigai@ak.jp.nec.com>
24 *
25 * Added support for bounds domain and audit messaged on masked permissions
26 *
27 * Copyright (C) 2008, 2009 NEC Corporation
28 * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
29 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
30 * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC
31 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
32 * This program is free software; you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation, version 2.
35 */
36
37 /* Ported to Xen 3.0, George Coker, <gscoker@alpha.ncsc.mil> */
38
39 #include <xen/lib.h>
40 #include <xen/xmalloc.h>
41 #include <xen/string.h>
42 #include <xen/spinlock.h>
43 #include <xen/rwlock.h>
44 #include <xen/errno.h>
45 #include "flask.h"
46 #include "avc.h"
47 #include "avc_ss.h"
48 #include "security.h"
49 #include "context.h"
50 #include "policydb.h"
51 #include "sidtab.h"
52 #include "services.h"
53 #include "conditional.h"
54 #include "mls.h"
55
56 unsigned int policydb_loaded_version;
57
58 static DEFINE_RWLOCK(policy_rwlock);
59 #define POLICY_RDLOCK read_lock(&policy_rwlock)
60 #define POLICY_WRLOCK write_lock(&policy_rwlock)
61 #define POLICY_RDUNLOCK read_unlock(&policy_rwlock)
62 #define POLICY_WRUNLOCK write_unlock(&policy_rwlock)
63
64 static DEFINE_SPINLOCK(load_sem);
65 #define LOAD_LOCK spin_lock(&load_sem)
66 #define LOAD_UNLOCK spin_unlock(&load_sem)
67
68 static struct sidtab sidtab;
69 struct policydb policydb;
70 int ss_initialized = 0;
71
72 /*
73 * The largest sequence number that has been used when
74 * providing an access decision to the access vector cache.
75 * The sequence number only changes when a policy change
76 * occurs.
77 */
78 static u32 latest_granting = 0;
79
80 /* Forward declaration. */
81 static int context_struct_to_string(struct context *context, char **scontext,
82 u32 *scontext_len);
83
84 static int context_struct_compute_av(struct context *scontext,
85 struct context *tcontext,
86 u16 tclass,
87 u32 requested,
88 struct av_decision *avd);
89
90 /*
91 * Return the boolean value of a constraint expression
92 * when it is applied to the specified source and target
93 * security contexts.
94 *
95 * xcontext is a special beast... It is used by the validatetrans rules
96 * only. For these rules, scontext is the context before the transition,
97 * tcontext is the context after the transition, and xcontext is the context
98 * of the process performing the transition. All other callers of
99 * constraint_expr_eval should pass in NULL for xcontext.
100 */
constraint_expr_eval(struct context * scontext,struct context * tcontext,struct context * xcontext,struct constraint_expr * cexpr)101 static int constraint_expr_eval(struct context *scontext,
102 struct context *tcontext, struct context *xcontext,
103 struct constraint_expr *cexpr)
104 {
105 u32 val1, val2;
106 struct context *c;
107 struct role_datum *r1, *r2;
108 struct mls_level *l1, *l2;
109 struct constraint_expr *e;
110 int s[CEXPR_MAXDEPTH];
111 int sp = -1;
112
113 for ( e = cexpr; e; e = e->next )
114 {
115 switch ( e->expr_type )
116 {
117 case CEXPR_NOT:
118 BUG_ON(sp < 0);
119 s[sp] = !s[sp];
120 break;
121 case CEXPR_AND:
122 BUG_ON(sp < 1);
123 sp--;
124 s[sp] &= s[sp+1];
125 break;
126 case CEXPR_OR:
127 BUG_ON(sp < 1);
128 sp--;
129 s[sp] |= s[sp+1];
130 break;
131 case CEXPR_ATTR:
132 if ( sp == (CEXPR_MAXDEPTH-1) )
133 return 0;
134 switch ( e->attr )
135 {
136 case CEXPR_USER:
137 val1 = scontext->user;
138 val2 = tcontext->user;
139 break;
140 case CEXPR_TYPE:
141 val1 = scontext->type;
142 val2 = tcontext->type;
143 break;
144 case CEXPR_ROLE:
145 val1 = scontext->role;
146 val2 = tcontext->role;
147 r1 = policydb.role_val_to_struct[val1 - 1];
148 r2 = policydb.role_val_to_struct[val2 - 1];
149 switch ( e->op )
150 {
151 case CEXPR_DOM:
152 s[++sp] = ebitmap_get_bit(&r1->dominates, val2 - 1);
153 continue;
154 case CEXPR_DOMBY:
155 s[++sp] = ebitmap_get_bit(&r2->dominates, val1 - 1);
156 continue;
157 case CEXPR_INCOMP:
158 s[++sp] = ( !ebitmap_get_bit(&r1->dominates,
159 val2 - 1) &&
160 !ebitmap_get_bit(&r2->dominates,
161 val1 - 1) );
162 continue;
163 default:
164 break;
165 }
166 break;
167 case CEXPR_L1L2:
168 l1 = &(scontext->range.level[0]);
169 l2 = &(tcontext->range.level[0]);
170 goto mls_ops;
171 case CEXPR_L1H2:
172 l1 = &(scontext->range.level[0]);
173 l2 = &(tcontext->range.level[1]);
174 goto mls_ops;
175 case CEXPR_H1L2:
176 l1 = &(scontext->range.level[1]);
177 l2 = &(tcontext->range.level[0]);
178 goto mls_ops;
179 case CEXPR_H1H2:
180 l1 = &(scontext->range.level[1]);
181 l2 = &(tcontext->range.level[1]);
182 goto mls_ops;
183 case CEXPR_L1H1:
184 l1 = &(scontext->range.level[0]);
185 l2 = &(scontext->range.level[1]);
186 goto mls_ops;
187 case CEXPR_L2H2:
188 l1 = &(tcontext->range.level[0]);
189 l2 = &(tcontext->range.level[1]);
190 goto mls_ops;
191 mls_ops:
192 switch ( e->op )
193 {
194 case CEXPR_EQ:
195 s[++sp] = mls_level_eq(l1, l2);
196 continue;
197 case CEXPR_NEQ:
198 s[++sp] = !mls_level_eq(l1, l2);
199 continue;
200 case CEXPR_DOM:
201 s[++sp] = mls_level_dom(l1, l2);
202 continue;
203 case CEXPR_DOMBY:
204 s[++sp] = mls_level_dom(l2, l1);
205 continue;
206 case CEXPR_INCOMP:
207 s[++sp] = mls_level_incomp(l2, l1);
208 continue;
209 default:
210 BUG();
211 return 0;
212 }
213 break;
214 default:
215 BUG();
216 return 0;
217 }
218
219 switch ( e->op )
220 {
221 case CEXPR_EQ:
222 s[++sp] = (val1 == val2);
223 break;
224 case CEXPR_NEQ:
225 s[++sp] = (val1 != val2);
226 break;
227 default:
228 BUG();
229 return 0;
230 }
231 break;
232 case CEXPR_NAMES:
233 if ( sp == (CEXPR_MAXDEPTH-1) )
234 return 0;
235 c = scontext;
236 if ( e->attr & CEXPR_TARGET )
237 c = tcontext;
238 else if ( e->attr & CEXPR_XTARGET )
239 {
240 c = xcontext;
241 if ( !c )
242 {
243 BUG();
244 return 0;
245 }
246 }
247 if ( e->attr & CEXPR_USER )
248 val1 = c->user;
249 else if ( e->attr & CEXPR_ROLE )
250 val1 = c->role;
251 else if ( e->attr & CEXPR_TYPE )
252 val1 = c->type;
253 else
254 {
255 BUG();
256 return 0;
257 }
258
259 switch ( e->op )
260 {
261 case CEXPR_EQ:
262 s[++sp] = ebitmap_get_bit(&e->names, val1 - 1);
263 break;
264 case CEXPR_NEQ:
265 s[++sp] = !ebitmap_get_bit(&e->names, val1 - 1);
266 break;
267 default:
268 BUG();
269 return 0;
270 }
271 break;
272 default:
273 BUG();
274 return 0;
275 }
276 }
277
278 BUG_ON(sp != 0);
279 return s[0];
280 }
281
282 /*
283 * security_dump_masked_av - dumps masked permissions during
284 * security_compute_av due to RBAC, MLS/Constraint and Type bounds.
285 */
dump_masked_av_helper(void * k,void * d,void * args)286 static int dump_masked_av_helper(void *k, void *d, void *args)
287 {
288 struct perm_datum *pdatum = d;
289 char **permission_names = args;
290
291 BUG_ON(pdatum->value < 1 || pdatum->value > 32);
292
293 permission_names[pdatum->value - 1] = (char *)k;
294
295 return 0;
296 }
297
security_dump_masked_av(struct context * scontext,struct context * tcontext,u16 tclass,u32 permissions,const char * reason)298 static void security_dump_masked_av(struct context *scontext,
299 struct context *tcontext,
300 u16 tclass,
301 u32 permissions,
302 const char *reason)
303 {
304 struct common_datum *common_dat;
305 struct class_datum *tclass_dat;
306 char *tclass_name;
307 char *scontext_name = NULL;
308 char *tcontext_name = NULL;
309 char *permission_names[32];
310 int index;
311 u32 length;
312 unsigned char need_comma = 0;
313
314 if ( !permissions )
315 return;
316
317 tclass_name = policydb.p_class_val_to_name[tclass - 1];
318 tclass_dat = policydb.class_val_to_struct[tclass - 1];
319 common_dat = tclass_dat->comdatum;
320
321 /* init permission_names */
322 if ( common_dat &&
323 hashtab_map(common_dat->permissions.table,
324 dump_masked_av_helper, permission_names) < 0 )
325 goto out;
326
327 if ( hashtab_map(tclass_dat->permissions.table,
328 dump_masked_av_helper, permission_names) < 0 )
329 goto out;
330
331 /* get scontext/tcontext in text form */
332 if ( context_struct_to_string(scontext,
333 &scontext_name, &length) < 0 )
334 goto out;
335
336 if ( context_struct_to_string(tcontext,
337 &tcontext_name, &length) < 0 )
338 goto out;
339
340 printk("Flask: op=security_compute_av reason=%s "
341 "scontext=%s tcontext=%s tclass=%s perms=",
342 reason, scontext_name, tcontext_name, tclass_name);
343
344 for ( index = 0; index < 32; index++ )
345 {
346 u32 mask = (1 << index);
347
348 if ( (mask & permissions) == 0 )
349 continue;
350
351 printk("%s%s",
352 need_comma ? "," : "",
353 permission_names[index]
354 ? permission_names[index] : "????");
355 need_comma = 1;
356 }
357 printk("\n");
358 out:
359 /* release scontext/tcontext */
360 xfree(tcontext_name);
361 xfree(scontext_name);
362
363 return;
364 }
365
366 /*
367 * security_boundary_permission - drops violated permissions
368 * on boundary constraint.
369 */
type_attribute_bounds_av(struct context * scontext,struct context * tcontext,u16 tclass,u32 requested,struct av_decision * avd)370 static void type_attribute_bounds_av(struct context *scontext,
371 struct context *tcontext,
372 u16 tclass,
373 u32 requested,
374 struct av_decision *avd)
375 {
376 struct context lo_scontext;
377 struct context lo_tcontext;
378 struct av_decision lo_avd;
379 struct type_datum *source
380 = policydb.type_val_to_struct[scontext->type - 1];
381 struct type_datum *target
382 = policydb.type_val_to_struct[tcontext->type - 1];
383 u32 masked = 0;
384
385 if ( source->bounds )
386 {
387 memset(&lo_avd, 0, sizeof(lo_avd));
388
389 memcpy(&lo_scontext, scontext, sizeof(lo_scontext));
390 lo_scontext.type = source->bounds;
391
392 context_struct_compute_av(&lo_scontext,
393 tcontext,
394 tclass,
395 requested,
396 &lo_avd);
397 if ( (lo_avd.allowed & avd->allowed) == avd->allowed )
398 return; /* no masked permission */
399 masked = ~lo_avd.allowed & avd->allowed;
400 }
401
402 if ( target->bounds )
403 {
404 memset(&lo_avd, 0, sizeof(lo_avd));
405
406 memcpy(&lo_tcontext, tcontext, sizeof(lo_tcontext));
407 lo_tcontext.type = target->bounds;
408
409 context_struct_compute_av(scontext,
410 &lo_tcontext,
411 tclass,
412 requested,
413 &lo_avd);
414 if ( (lo_avd.allowed & avd->allowed) == avd->allowed )
415 return; /* no masked permission */
416 masked = ~lo_avd.allowed & avd->allowed;
417 }
418
419 if ( source->bounds && target->bounds )
420 {
421 memset(&lo_avd, 0, sizeof(lo_avd));
422 /*
423 * lo_scontext and lo_tcontext are already
424 * set up.
425 */
426
427 context_struct_compute_av(&lo_scontext,
428 &lo_tcontext,
429 tclass,
430 requested,
431 &lo_avd);
432 if ( (lo_avd.allowed & avd->allowed) == avd->allowed )
433 return; /* no masked permission */
434 masked = ~lo_avd.allowed & avd->allowed;
435 }
436
437 if ( masked )
438 {
439 /* mask violated permissions */
440 avd->allowed &= ~masked;
441
442 /* audit masked permissions */
443 security_dump_masked_av(scontext, tcontext,
444 tclass, masked, "bounds");
445 }
446 }
447
448 /*
449 * Compute access vectors based on a context structure pair for
450 * the permissions in a particular class.
451 */
context_struct_compute_av(struct context * scontext,struct context * tcontext,u16 tclass,u32 requested,struct av_decision * avd)452 static int context_struct_compute_av(struct context *scontext,
453 struct context *tcontext,
454 u16 tclass,
455 u32 requested,
456 struct av_decision *avd)
457 {
458 struct constraint_node *constraint;
459 struct role_allow *ra;
460 struct avtab_key avkey;
461 struct avtab_node *node;
462 struct class_datum *tclass_datum;
463 struct ebitmap *sattr, *tattr;
464 struct ebitmap_node *snode, *tnode;
465 unsigned int i, j;
466
467 /*
468 * Initialize the access vectors to the default values.
469 */
470 avd->allowed = 0;
471 avd->auditallow = 0;
472 avd->auditdeny = 0xffffffff;
473 avd->seqno = latest_granting;
474 avd->flags = 0;
475
476 /*
477 * We do not presently support policydb.handle_unknown == allow in Xen.
478 */
479 if ( !tclass || tclass > policydb.p_classes.nprim )
480 return -EINVAL;
481
482 tclass_datum = policydb.class_val_to_struct[tclass - 1];
483
484 /*
485 * If a specific type enforcement rule was defined for
486 * this permission check, then use it.
487 */
488 avkey.target_class = tclass;
489 avkey.specified = AVTAB_AV;
490 sattr = &policydb.type_attr_map[scontext->type - 1];
491 tattr = &policydb.type_attr_map[tcontext->type - 1];
492 ebitmap_for_each_positive_bit(sattr, snode, i)
493 {
494 ebitmap_for_each_positive_bit(tattr, tnode, j)
495 {
496 avkey.source_type = i + 1;
497 avkey.target_type = j + 1;
498 for ( node = avtab_search_node(&policydb.te_avtab, &avkey);
499 node != NULL;
500 node = avtab_search_node_next(node, avkey.specified) )
501 {
502 if ( node->key.specified == AVTAB_ALLOWED )
503 avd->allowed |= node->datum.data;
504 else if ( node->key.specified == AVTAB_AUDITALLOW )
505 avd->auditallow |= node->datum.data;
506 else if ( node->key.specified == AVTAB_AUDITDENY )
507 avd->auditdeny &= node->datum.data;
508 }
509
510 /* Check conditional av table for additional permissions */
511 cond_compute_av(&policydb.te_cond_avtab, &avkey, avd);
512
513 }
514 }
515
516 /*
517 * Remove any permissions prohibited by a constraint (this includes
518 * the MLS policy).
519 */
520 constraint = tclass_datum->constraints;
521 while ( constraint )
522 {
523 if ( (constraint->permissions & (avd->allowed) ) &&
524 !constraint_expr_eval(scontext, tcontext, NULL, constraint->expr))
525 {
526 avd->allowed &= ~(constraint->permissions);
527 }
528 constraint = constraint->next;
529 }
530
531 /*
532 * If checking process transition permission and the
533 * role is changing, then check the (current_role, new_role)
534 * pair.
535 */
536 if ( tclass == SECCLASS_DOMAIN &&
537 (avd->allowed & DOMAIN__TRANSITION) &&
538 scontext->role != tcontext->role )
539 {
540 for ( ra = policydb.role_allow; ra; ra = ra->next )
541 {
542 if ( scontext->role == ra->role && tcontext->role == ra->new_role )
543 break;
544 }
545 if (!ra)
546 avd->allowed &= ~DOMAIN__TRANSITION;
547 }
548
549 /*
550 * If the given source and target types have boundary
551 * constraint, lazy checks have to mask any violated
552 * permission and notice it to userspace via audit.
553 */
554 type_attribute_bounds_av(scontext, tcontext,
555 tclass, requested, avd);
556 return 0;
557 }
558
security_validtrans_handle_fail(struct context * ocontext,struct context * ncontext,struct context * tcontext,u16 tclass)559 static int security_validtrans_handle_fail(struct context *ocontext,
560 struct context *ncontext, struct context *tcontext, u16 tclass)
561 {
562 char *o = NULL, *n = NULL, *t = NULL;
563 u32 olen, nlen, tlen;
564
565 if ( context_struct_to_string(ocontext, &o, &olen) < 0 )
566 goto out;
567 if ( context_struct_to_string(ncontext, &n, &nlen) < 0 )
568 goto out;
569 if ( context_struct_to_string(tcontext, &t, &tlen) < 0 )
570 goto out;
571 printk("security_validate_transition: denied for"
572 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
573 o, n, t, policydb.p_class_val_to_name[tclass-1]);
574 out:
575 xfree(o);
576 xfree(n);
577 xfree(t);
578
579 if ( !flask_enforcing )
580 return 0;
581 return -EPERM;
582 }
583
security_validate_transition(u32 oldsid,u32 newsid,u32 tasksid,u16 tclass)584 int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
585 u16 tclass)
586 {
587 struct context *ocontext;
588 struct context *ncontext;
589 struct context *tcontext;
590 struct class_datum *tclass_datum;
591 struct constraint_node *constraint;
592 int rc = 0;
593
594 if ( !ss_initialized )
595 return 0;
596
597 POLICY_RDLOCK;
598
599 if ( !tclass || tclass > policydb.p_classes.nprim )
600 {
601 printk(KERN_ERR "security_validate_transition: "
602 "unrecognized class %d\n", tclass);
603 rc = -EINVAL;
604 goto out;
605 }
606 tclass_datum = policydb.class_val_to_struct[tclass - 1];
607
608 ocontext = sidtab_search(&sidtab, oldsid);
609 if ( !ocontext )
610 {
611 printk(KERN_ERR "security_validate_transition: "
612 " unrecognized SID %d\n", oldsid);
613 rc = -EINVAL;
614 goto out;
615 }
616
617 ncontext = sidtab_search(&sidtab, newsid);
618 if ( !ncontext )
619 {
620 printk(KERN_ERR "security_validate_transition: "
621 " unrecognized SID %d\n", newsid);
622 rc = -EINVAL;
623 goto out;
624 }
625
626 tcontext = sidtab_search(&sidtab, tasksid);
627 if ( !tcontext )
628 {
629 printk(KERN_ERR "security_validate_transition: "
630 " unrecognized SID %d\n", tasksid);
631 rc = -EINVAL;
632 goto out;
633 }
634
635 constraint = tclass_datum->validatetrans;
636 while ( constraint )
637 {
638 if ( !constraint_expr_eval(ocontext, ncontext, tcontext,
639 constraint->expr) )
640 {
641 rc = security_validtrans_handle_fail(ocontext, ncontext,
642 tcontext, tclass);
643 goto out;
644 }
645 constraint = constraint->next;
646 }
647
648 out:
649 POLICY_RDUNLOCK;
650 return rc;
651 }
652
653 /**
654 * security_compute_av - Compute access vector decisions.
655 * @ssid: source security identifier
656 * @tsid: target security identifier
657 * @tclass: target security class
658 * @requested: requested permissions
659 * @avd: access vector decisions
660 *
661 * Compute a set of access vector decisions based on the
662 * SID pair (@ssid, @tsid) for the permissions in @tclass.
663 * Return -%EINVAL if any of the parameters are invalid or %0
664 * if the access vector decisions were computed successfully.
665 */
security_compute_av(u32 ssid,u32 tsid,u16 tclass,u32 requested,struct av_decision * avd)666 int security_compute_av(u32 ssid, u32 tsid, u16 tclass, u32 requested,
667 struct av_decision *avd)
668 {
669 struct context *scontext = NULL, *tcontext = NULL;
670 int rc = 0;
671
672 if ( !ss_initialized )
673 {
674 avd->allowed = 0xffffffff;
675 avd->auditallow = 0;
676 avd->auditdeny = 0xffffffff;
677 avd->seqno = latest_granting;
678 return 0;
679 }
680
681 POLICY_RDLOCK;
682
683 scontext = sidtab_search(&sidtab, ssid);
684 if ( !scontext )
685 {
686 printk("security_compute_av: unrecognized SID %d\n", ssid);
687 rc = -EINVAL;
688 goto out;
689 }
690 tcontext = sidtab_search(&sidtab, tsid);
691 if ( !tcontext )
692 {
693 printk("security_compute_av: unrecognized SID %d\n", tsid);
694 rc = -EINVAL;
695 goto out;
696 }
697
698 rc = context_struct_compute_av(scontext, tcontext, tclass, requested, avd);
699
700 /* permissive domain? */
701 if ( ebitmap_get_bit(&policydb.permissive_map, scontext->type) )
702 avd->flags |= AVD_FLAGS_PERMISSIVE;
703 out:
704 POLICY_RDUNLOCK;
705 return rc;
706 }
707
708 /*
709 * Write the security context string representation of
710 * the context structure `context' into a dynamically
711 * allocated string of the correct size. Set `*scontext'
712 * to point to this string and set `*scontext_len' to
713 * the length of the string.
714 */
context_struct_to_string(struct context * context,char ** scontext,u32 * scontext_len)715 static int context_struct_to_string(struct context *context, char **scontext, u32 *scontext_len)
716 {
717 char *scontextp;
718
719 *scontext = NULL;
720 *scontext_len = 0;
721
722 /* Compute the size of the context. */
723 *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1;
724 *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1;
725 *scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1;
726 *scontext_len += mls_compute_context_len(context);
727
728 /* Allocate space for the context; caller must free this space. */
729 scontextp = xmalloc_array(char, *scontext_len);
730 if ( !scontextp )
731 return -ENOMEM;
732
733 *scontext = scontextp;
734
735 /*
736 * Copy the user name, role name and type name into the context.
737 */
738 snprintf(scontextp, *scontext_len, "%s:%s:%s",
739 policydb.p_user_val_to_name[context->user - 1],
740 policydb.p_role_val_to_name[context->role - 1],
741 policydb.p_type_val_to_name[context->type - 1]);
742 scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) +
743 1 + strlen(policydb.p_role_val_to_name[context->role - 1]) +
744 1 + strlen(policydb.p_type_val_to_name[context->type - 1]);
745
746 mls_sid_to_context(context, &scontextp);
747
748 *scontextp = 0;
749
750 return 0;
751 }
752
753 #include "initial_sid_to_string.h"
754
755 /**
756 * security_sid_to_context - Obtain a context for a given SID.
757 * @sid: security identifier, SID
758 * @scontext: security context
759 * @scontext_len: length in bytes
760 *
761 * Write the string representation of the context associated with @sid
762 * into a dynamically allocated string of the correct size. Set @scontext
763 * to point to this string and set @scontext_len to the length of the string.
764 */
security_sid_to_context(u32 sid,char ** scontext,u32 * scontext_len)765 int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
766 {
767 struct context *context;
768 int rc = 0;
769
770 if ( !ss_initialized )
771 {
772 if ( sid <= SECINITSID_NUM )
773 {
774 char *scontextp;
775
776 *scontext_len = strlen(initial_sid_to_string[sid]) + 1;
777 scontextp = xmalloc_array(char, *scontext_len);
778 if ( !scontextp )
779 return -ENOMEM;
780 strlcpy(scontextp, initial_sid_to_string[sid], *scontext_len);
781 *scontext = scontextp;
782 goto out;
783 }
784 printk(KERN_ERR "security_sid_to_context: called before initial "
785 "load_policy on unknown SID %d\n", sid);
786 rc = -EINVAL;
787 goto out;
788 }
789 POLICY_RDLOCK;
790 context = sidtab_search(&sidtab, sid);
791 if ( !context )
792 {
793 printk(KERN_ERR "security_sid_to_context: unrecognized SID "
794 "%d\n", sid);
795 rc = -EINVAL;
796 goto out_unlock;
797 }
798 rc = context_struct_to_string(context, scontext, scontext_len);
799 out_unlock:
800 POLICY_RDUNLOCK;
801 out:
802 return rc;
803
804 }
805
806 /**
807 * security_context_to_sid - Obtain a SID for a given security context.
808 * @scontext: security context
809 * @scontext_len: length in bytes
810 * @sid: security identifier, SID
811 *
812 * Obtains a SID associated with the security context that
813 * has the string representation specified by @scontext.
814 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
815 * memory is available, or 0 on success.
816 */
security_context_to_sid(char * scontext,u32 scontext_len,u32 * sid)817 int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
818 {
819 char *scontext2;
820 struct context context;
821 struct role_datum *role;
822 struct type_datum *typdatum;
823 struct user_datum *usrdatum;
824 char *scontextp, *p, oldc;
825 int rc = 0;
826
827 if ( !ss_initialized )
828 {
829 int i;
830
831 for ( i = 1; i < SECINITSID_NUM; i++ )
832 {
833 if ( !strcmp(initial_sid_to_string[i], scontext) )
834 {
835 *sid = i;
836 goto out;
837 }
838 }
839 *sid = SECINITSID_XEN;
840 goto out;
841 }
842 *sid = SECSID_NULL;
843
844 /* Copy the string so that we can modify the copy as we parse it.
845 The string should already by null terminated, but we append a
846 null suffix to the copy to avoid problems with the existing
847 attr package, which doesn't view the null terminator as part
848 of the attribute value. */
849 scontext2 = xmalloc_array(char, scontext_len+1);
850 if ( !scontext2 )
851 {
852 rc = -ENOMEM;
853 goto out;
854 }
855 memcpy(scontext2, scontext, scontext_len);
856 scontext2[scontext_len] = 0;
857
858 context_init(&context);
859 *sid = SECSID_NULL;
860
861 POLICY_RDLOCK;
862
863 /* Parse the security context. */
864
865 rc = -EINVAL;
866 scontextp = (char *) scontext2;
867
868 /* Extract the user. */
869 p = scontextp;
870 while ( *p && *p != ':' )
871 p++;
872
873 if (*p == 0)
874 goto out_unlock;
875
876 *p++ = 0;
877
878 usrdatum = hashtab_search(policydb.p_users.table, scontextp);
879 if ( !usrdatum )
880 goto out_unlock;
881
882 context.user = usrdatum->value;
883
884 /* Extract role. */
885 scontextp = p;
886 while ( *p && *p != ':' )
887 p++;
888
889 if ( *p == 0 )
890 goto out_unlock;
891
892 *p++ = 0;
893
894 role = hashtab_search(policydb.p_roles.table, scontextp);
895 if ( !role )
896 goto out_unlock;
897 context.role = role->value;
898
899 /* Extract type. */
900 scontextp = p;
901 while ( *p && *p != ':' )
902 p++;
903 oldc = *p;
904 *p++ = 0;
905
906 typdatum = hashtab_search(policydb.p_types.table, scontextp);
907 if ( !typdatum || typdatum->attribute )
908 goto out_unlock;
909
910 context.type = typdatum->value;
911
912 rc = mls_context_to_sid(oldc, &p, &context, &sidtab);
913 if ( rc )
914 goto out_unlock;
915
916 if ( (p - scontext2) < scontext_len )
917 {
918 rc = -EINVAL;
919 goto out_unlock;
920 }
921
922 /* Check the validity of the new context. */
923 if ( !policydb_context_isvalid(&policydb, &context) )
924 {
925 rc = -EINVAL;
926 goto out_unlock;
927 }
928 /* Obtain the new sid. */
929 rc = sidtab_context_to_sid(&sidtab, &context, sid);
930 out_unlock:
931 POLICY_RDUNLOCK;
932 context_destroy(&context);
933 xfree(scontext2);
934 out:
935 return rc;
936 }
937
compute_sid_handle_invalid_context(struct context * scontext,struct context * tcontext,u16 tclass,struct context * newcontext)938 static int compute_sid_handle_invalid_context(
939 struct context *scontext, struct context *tcontext, u16 tclass,
940 struct context *newcontext)
941 {
942 char *s = NULL, *t = NULL, *n = NULL;
943 u32 slen, tlen, nlen;
944
945 if ( context_struct_to_string(scontext, &s, &slen) < 0 )
946 goto out;
947 if ( context_struct_to_string(tcontext, &t, &tlen) < 0 )
948 goto out;
949 if ( context_struct_to_string(newcontext, &n, &nlen) < 0 )
950 goto out;
951 printk("security_compute_sid: invalid context %s"
952 " for scontext=%s"
953 " tcontext=%s"
954 " tclass=%s",
955 n, s, t, policydb.p_class_val_to_name[tclass-1]);
956 out:
957 xfree(s);
958 xfree(t);
959 xfree(n);
960 if ( !flask_enforcing )
961 return 0;
962 return -EACCES;
963 }
964
security_compute_sid(u32 ssid,u32 tsid,u16 tclass,u32 specified,u32 * out_sid)965 static int security_compute_sid(u32 ssid,
966 u32 tsid,
967 u16 tclass,
968 u32 specified,
969 u32 *out_sid)
970 {
971 struct context *scontext = NULL, *tcontext = NULL, newcontext;
972 struct role_trans *roletr = NULL;
973 struct avtab_key avkey;
974 struct avtab_datum *avdatum;
975 struct avtab_node *node;
976 int rc = 0;
977
978 if ( !ss_initialized )
979 {
980 switch ( tclass )
981 {
982 case SECCLASS_DOMAIN:
983 *out_sid = ssid;
984 break;
985 default:
986 *out_sid = tsid;
987 break;
988 }
989 goto out;
990 }
991
992 POLICY_RDLOCK;
993
994 scontext = sidtab_search(&sidtab, ssid);
995 if ( !scontext )
996 {
997 printk(KERN_ERR "security_compute_sid: unrecognized SID %d\n", ssid);
998 rc = -EINVAL;
999 goto out_unlock;
1000 }
1001 tcontext = sidtab_search(&sidtab, tsid);
1002 if ( !tcontext )
1003 {
1004 printk(KERN_ERR "security_compute_sid: unrecognized SID %d\n", tsid);
1005 rc = -EINVAL;
1006 goto out_unlock;
1007 }
1008
1009 context_init(&newcontext);
1010
1011 /* Set the user identity. */
1012 switch ( specified )
1013 {
1014 case AVTAB_TRANSITION:
1015 case AVTAB_CHANGE:
1016 /* Use the process user identity. */
1017 newcontext.user = scontext->user;
1018 break;
1019 case AVTAB_MEMBER:
1020 /* Use the related object owner. */
1021 newcontext.user = tcontext->user;
1022 break;
1023 }
1024
1025 /* Set the role and type to default values. */
1026 switch ( tclass )
1027 {
1028 case SECCLASS_DOMAIN:
1029 /* Use the current role and type of process. */
1030 newcontext.role = scontext->role;
1031 newcontext.type = scontext->type;
1032 break;
1033 default:
1034 /* Use the well-defined object role. */
1035 newcontext.role = OBJECT_R_VAL;
1036 /* Use the type of the related object. */
1037 newcontext.type = tcontext->type;
1038 }
1039
1040 /* Look for a type transition/member/change rule. */
1041 avkey.source_type = scontext->type;
1042 avkey.target_type = tcontext->type;
1043 avkey.target_class = tclass;
1044 avkey.specified = specified;
1045 avdatum = avtab_search(&policydb.te_avtab, &avkey);
1046
1047 /* If no permanent rule, also check for enabled conditional rules */
1048 if ( !avdatum )
1049 {
1050 node = avtab_search_node(&policydb.te_cond_avtab, &avkey);
1051 for ( ; node != NULL; node = avtab_search_node_next(node, specified) )
1052 {
1053 if ( node->key.specified & AVTAB_ENABLED )
1054 {
1055 avdatum = &node->datum;
1056 break;
1057 }
1058 }
1059 }
1060
1061 if ( avdatum )
1062 {
1063 /* Use the type from the type transition/member/change rule. */
1064 newcontext.type = avdatum->data;
1065 }
1066
1067 /* Check for class-specific changes. */
1068 switch ( tclass )
1069 {
1070 case SECCLASS_DOMAIN:
1071 if ( specified & AVTAB_TRANSITION )
1072 {
1073 /* Look for a role transition rule. */
1074 for ( roletr = policydb.role_tr; roletr; roletr = roletr->next )
1075 {
1076 if ( roletr->role == scontext->role &&
1077 roletr->type == tcontext->type )
1078 {
1079 /* Use the role transition rule. */
1080 newcontext.role = roletr->new_role;
1081 break;
1082 }
1083 }
1084 }
1085 break;
1086 default:
1087 break;
1088 }
1089
1090 /* Set the MLS attributes.
1091 This is done last because it may allocate memory. */
1092 rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext);
1093 if ( rc )
1094 goto out_unlock;
1095
1096 /* Check the validity of the context. */
1097 if ( !policydb_context_isvalid(&policydb, &newcontext) )
1098 {
1099 rc = compute_sid_handle_invalid_context(scontext, tcontext, tclass,
1100 &newcontext);
1101 if ( rc )
1102 goto out_unlock;
1103 }
1104 /* Obtain the sid for the context. */
1105 rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid);
1106 out_unlock:
1107 POLICY_RDUNLOCK;
1108 context_destroy(&newcontext);
1109 out:
1110 return rc;
1111 }
1112
1113 /**
1114 * security_transition_sid - Compute the SID for a new subject/object.
1115 * @ssid: source security identifier
1116 * @tsid: target security identifier
1117 * @tclass: target security class
1118 * @out_sid: security identifier for new subject/object
1119 *
1120 * Compute a SID to use for labeling a new subject or object in the
1121 * class @tclass based on a SID pair (@ssid, @tsid).
1122 * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
1123 * if insufficient memory is available, or %0 if the new SID was
1124 * computed successfully.
1125 */
security_transition_sid(u32 ssid,u32 tsid,u16 tclass,u32 * out_sid)1126 int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid)
1127 {
1128 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid);
1129 }
1130
1131 /**
1132 * security_member_sid - Compute the SID for member selection.
1133 * @ssid: source security identifier
1134 * @tsid: target security identifier
1135 * @tclass: target security class
1136 * @out_sid: security identifier for selected member
1137 *
1138 * Compute a SID to use when selecting a member of a polyinstantiated
1139 * object of class @tclass based on a SID pair (@ssid, @tsid).
1140 * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
1141 * if insufficient memory is available, or %0 if the SID was
1142 * computed successfully.
1143 */
security_member_sid(u32 ssid,u32 tsid,u16 tclass,u32 * out_sid)1144 int security_member_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid)
1145 {
1146 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid);
1147 }
1148
1149 /**
1150 * security_change_sid - Compute the SID for object relabeling.
1151 * @ssid: source security identifier
1152 * @tsid: target security identifier
1153 * @tclass: target security class
1154 * @out_sid: security identifier for selected member
1155 *
1156 * Compute a SID to use for relabeling an object of class @tclass
1157 * based on a SID pair (@ssid, @tsid).
1158 * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
1159 * if insufficient memory is available, or %0 if the SID was
1160 * computed successfully.
1161 */
security_change_sid(u32 ssid,u32 tsid,u16 tclass,u32 * out_sid)1162 int security_change_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid)
1163 {
1164 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid);
1165 }
1166
1167 /*
1168 * Verify that each kernel class that is defined in the
1169 * policy is correct
1170 */
validate_classes(struct policydb * p)1171 static int validate_classes(struct policydb *p)
1172 {
1173 int i;
1174 struct class_datum *cladatum;
1175 struct perm_datum *perdatum;
1176 u32 nprim, perm_val, pol_val;
1177 u16 class_val;
1178 const struct selinux_class_perm *kdefs = &selinux_class_perm;
1179 const char *def_class, *def_perm, *pol_class;
1180 struct symtab *perms;
1181
1182 for ( i = 1; i < kdefs->cts_len; i++ )
1183 {
1184 def_class = kdefs->class_to_string[i];
1185 if ( !def_class )
1186 continue;
1187 if ( i > p->p_classes.nprim )
1188 {
1189 printk(KERN_INFO
1190 "Flask: class %s not defined in policy\n",
1191 def_class);
1192 return -EINVAL;
1193 }
1194 pol_class = p->p_class_val_to_name[i-1];
1195 if ( strcmp(pol_class, def_class) )
1196 {
1197 printk(KERN_ERR
1198 "Flask: class %d is incorrect, found %s but should be %s\n",
1199 i, pol_class, def_class);
1200 return -EINVAL;
1201 }
1202 }
1203 for ( i = 0; i < kdefs->av_pts_len; i++ )
1204 {
1205 class_val = kdefs->av_perm_to_string[i].tclass;
1206 perm_val = kdefs->av_perm_to_string[i].value;
1207 def_perm = kdefs->av_perm_to_string[i].name;
1208 if ( class_val > p->p_classes.nprim )
1209 continue;
1210 pol_class = p->p_class_val_to_name[class_val-1];
1211 cladatum = hashtab_search(p->p_classes.table, pol_class);
1212 BUG_ON( !cladatum );
1213 perms = &cladatum->permissions;
1214 nprim = 1 << (perms->nprim - 1);
1215 if ( perm_val > nprim )
1216 {
1217 printk(KERN_INFO
1218 "Flask: permission %s in class %s not defined in policy\n",
1219 def_perm, pol_class);
1220 return -EINVAL;
1221 }
1222 perdatum = hashtab_search(perms->table, def_perm);
1223 if ( perdatum == NULL )
1224 {
1225 printk(KERN_ERR
1226 "Flask: permission %s in class %s not found in policy\n",
1227 def_perm, pol_class);
1228 return -EINVAL;
1229 }
1230 pol_val = 1 << (perdatum->value - 1);
1231 if ( pol_val != perm_val )
1232 {
1233 printk(KERN_ERR
1234 "Flask: permission %s in class %s has incorrect value\n",
1235 def_perm, pol_class);
1236 return -EINVAL;
1237 }
1238 }
1239 return 0;
1240 }
1241
1242 /* Clone the SID into the new SID table. */
clone_sid(u32 sid,struct context * context,void * arg)1243 static int clone_sid(u32 sid, struct context *context, void *arg)
1244 {
1245 struct sidtab *s = arg;
1246
1247 return sidtab_insert(s, sid, context);
1248 }
1249
convert_context_handle_invalid_context(struct context * context)1250 static inline int convert_context_handle_invalid_context(struct context *context)
1251 {
1252 int rc = 0;
1253
1254 if ( flask_enforcing )
1255 rc = -EINVAL;
1256 else
1257 {
1258 char *s;
1259 u32 len;
1260
1261 context_struct_to_string(context, &s, &len);
1262 printk(KERN_ERR "Flask: context %s is invalid\n", s);
1263 xfree(s);
1264 }
1265 return rc;
1266 }
1267
1268 struct convert_context_args {
1269 struct policydb *oldp;
1270 struct policydb *newp;
1271 };
1272
1273 /*
1274 * Convert the values in the security context
1275 * structure `c' from the values specified
1276 * in the policy `p->oldp' to the values specified
1277 * in the policy `p->newp'. Verify that the
1278 * context is valid under the new policy.
1279 */
convert_context(u32 key,struct context * c,void * p)1280 static int convert_context(u32 key, struct context *c, void *p)
1281 {
1282 struct convert_context_args *args;
1283 struct context oldc;
1284 struct role_datum *role;
1285 struct type_datum *typdatum;
1286 struct user_datum *usrdatum;
1287 char *s;
1288 u32 len;
1289 int rc;
1290
1291 args = p;
1292
1293 rc = context_cpy(&oldc, c);
1294 if ( rc )
1295 goto out;
1296
1297 rc = -EINVAL;
1298
1299 /* Convert the user. */
1300 usrdatum = hashtab_search(args->newp->p_users.table,
1301 args->oldp->p_user_val_to_name[c->user - 1]);
1302 if ( !usrdatum )
1303 goto bad;
1304
1305 c->user = usrdatum->value;
1306
1307 /* Convert the role. */
1308 role = hashtab_search(args->newp->p_roles.table,
1309 args->oldp->p_role_val_to_name[c->role - 1]);
1310 if ( !role )
1311 goto bad;
1312
1313 c->role = role->value;
1314
1315 /* Convert the type. */
1316 typdatum = hashtab_search(args->newp->p_types.table,
1317 args->oldp->p_type_val_to_name[c->type - 1]);
1318 if ( !typdatum )
1319 goto bad;
1320
1321 c->type = typdatum->value;
1322
1323 rc = mls_convert_context(args->oldp, args->newp, c);
1324 if ( rc )
1325 goto bad;
1326
1327 /* Check the validity of the new context. */
1328 if ( !policydb_context_isvalid(args->newp, c) )
1329 {
1330 rc = convert_context_handle_invalid_context(&oldc);
1331 if ( rc )
1332 goto bad;
1333 }
1334
1335 context_destroy(&oldc);
1336 out:
1337 return rc;
1338 bad:
1339 context_struct_to_string(&oldc, &s, &len);
1340 context_destroy(&oldc);
1341 printk(KERN_ERR "Flask: invalidating context %s\n", s);
1342 xfree(s);
1343 goto out;
1344 }
1345
1346 static int security_preserve_bools(struct policydb *p);
1347
1348 /**
1349 * security_load_policy - Load a security policy configuration.
1350 * @data: binary policy data
1351 * @len: length of data in bytes
1352 *
1353 * Load a new set of security policy configuration data,
1354 * validate it and convert the SID table as necessary.
1355 * This function will flush the access vector cache after
1356 * loading the new policy.
1357 */
security_load_policy(const void * data,size_t len)1358 int security_load_policy(const void *data, size_t len)
1359 {
1360 struct policydb oldpolicydb, newpolicydb;
1361 struct sidtab oldsidtab, newsidtab;
1362 struct convert_context_args args;
1363 u32 seqno;
1364 int rc = 0;
1365 struct policy_file file = { data, len }, *fp = &file;
1366
1367 LOAD_LOCK;
1368
1369 if ( !ss_initialized )
1370 {
1371 if ( policydb_read(&policydb, fp) )
1372 {
1373 LOAD_UNLOCK;
1374 return -EINVAL;
1375 }
1376 if ( policydb_load_isids(&policydb, &sidtab) )
1377 {
1378 LOAD_UNLOCK;
1379 policydb_destroy(&policydb);
1380 return -EINVAL;
1381 }
1382 if ( validate_classes(&policydb) )
1383 {
1384 LOAD_UNLOCK;
1385 printk(KERN_ERR
1386 "Flask: the definition of a class is incorrect\n");
1387 sidtab_destroy(&sidtab);
1388 policydb_destroy(&policydb);
1389 return -EINVAL;
1390 }
1391 policydb_loaded_version = policydb.policyvers;
1392 ss_initialized = 1;
1393 seqno = ++latest_granting;
1394 LOAD_UNLOCK;
1395 avc_ss_reset(seqno);
1396 return 0;
1397 }
1398
1399 #if 0
1400 sidtab_hash_eval(&sidtab, "sids");
1401 #endif
1402
1403 if ( policydb_read(&newpolicydb, fp) )
1404 {
1405 LOAD_UNLOCK;
1406 return -EINVAL;
1407 }
1408
1409 sidtab_init(&newsidtab);
1410
1411 /* Verify that the kernel defined classes are correct. */
1412 if ( validate_classes(&newpolicydb) )
1413 {
1414 printk(KERN_ERR
1415 "Flask: the definition of a class is incorrect\n");
1416 rc = -EINVAL;
1417 goto err;
1418 }
1419
1420 rc = security_preserve_bools(&newpolicydb);
1421 if ( rc )
1422 {
1423 printk(KERN_ERR "Flask: unable to preserve booleans\n");
1424 goto err;
1425 }
1426
1427 /* Clone the SID table. */
1428 sidtab_shutdown(&sidtab);
1429 if ( sidtab_map(&sidtab, clone_sid, &newsidtab) )
1430 {
1431 rc = -ENOMEM;
1432 goto err;
1433 }
1434
1435 /* Convert the internal representations of contexts
1436 in the new SID table and remove invalid SIDs. */
1437 args.oldp = &policydb;
1438 args.newp = &newpolicydb;
1439 sidtab_map_remove_on_error(&newsidtab, convert_context, &args);
1440
1441 /* Save the old policydb and SID table to free later. */
1442 memcpy(&oldpolicydb, &policydb, sizeof policydb);
1443 sidtab_set(&oldsidtab, &sidtab);
1444
1445 /* Install the new policydb and SID table. */
1446 POLICY_WRLOCK;
1447 memcpy(&policydb, &newpolicydb, sizeof policydb);
1448 sidtab_set(&sidtab, &newsidtab);
1449 seqno = ++latest_granting;
1450 policydb_loaded_version = policydb.policyvers;
1451 POLICY_WRUNLOCK;
1452 LOAD_UNLOCK;
1453
1454 /* Free the old policydb and SID table. */
1455 policydb_destroy(&oldpolicydb);
1456 sidtab_destroy(&oldsidtab);
1457
1458 avc_ss_reset(seqno);
1459
1460 return 0;
1461
1462 err:
1463 LOAD_UNLOCK;
1464 sidtab_destroy(&newsidtab);
1465 policydb_destroy(&newpolicydb);
1466 return rc;
1467
1468 }
1469
security_get_allow_unknown(void)1470 int security_get_allow_unknown(void)
1471 {
1472 return policydb.allow_unknown;
1473 }
1474
1475 /**
1476 * security_irq_sid - Obtain the SID for a physical irq.
1477 * @pirq: physical irq
1478 * @out_sid: security identifier
1479 */
security_irq_sid(int pirq,u32 * out_sid)1480 int security_irq_sid(int pirq, u32 *out_sid)
1481 {
1482 int rc = 0;
1483 struct ocontext *c;
1484
1485 POLICY_RDLOCK;
1486
1487 c = policydb.ocontexts[OCON_PIRQ];
1488
1489 while ( c )
1490 {
1491 if ( c->u.pirq == pirq )
1492 break;
1493 c = c->next;
1494 }
1495
1496 if ( c )
1497 {
1498 if ( !c->sid )
1499 {
1500 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1501 if ( rc )
1502 goto out;
1503 }
1504 *out_sid = c->sid;
1505 }
1506 else
1507 {
1508 *out_sid = SECINITSID_IRQ;
1509 }
1510
1511 out:
1512 POLICY_RDUNLOCK;
1513 return rc;
1514 }
1515
1516 /**
1517 * security_iomem_sid - Obtain the SID for a page of iomem.
1518 * @mfn: iomem mfn
1519 * @out_sid: security identifier
1520 */
security_iomem_sid(unsigned long mfn,u32 * out_sid)1521 int security_iomem_sid(unsigned long mfn, u32 *out_sid)
1522 {
1523 struct ocontext *c;
1524 int rc = 0;
1525
1526 POLICY_RDLOCK;
1527
1528 c = policydb.ocontexts[OCON_IOMEM];
1529 while ( c )
1530 {
1531 if ( c->u.iomem.low_iomem <= mfn && c->u.iomem.high_iomem >= mfn )
1532 break;
1533 c = c->next;
1534 }
1535
1536 if ( c )
1537 {
1538 if ( !c->sid )
1539 {
1540 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1541 if ( rc )
1542 goto out;
1543 }
1544 *out_sid = c->sid;
1545 }
1546 else
1547 {
1548 *out_sid = SECINITSID_IOMEM;
1549 }
1550
1551 out:
1552 POLICY_RDUNLOCK;
1553 return rc;
1554 }
1555
security_iterate_iomem_sids(unsigned long start,unsigned long end,security_iterate_fn fn,void * data)1556 int security_iterate_iomem_sids(unsigned long start, unsigned long end,
1557 security_iterate_fn fn, void *data)
1558 {
1559 struct ocontext *c;
1560 int rc = 0;
1561
1562 POLICY_RDLOCK;
1563
1564 c = policydb.ocontexts[OCON_IOMEM];
1565 while (c && c->u.iomem.high_iomem < start)
1566 c = c->next;
1567
1568 while (c && c->u.iomem.low_iomem <= end) {
1569 if (!c->sid)
1570 {
1571 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1572 if ( rc )
1573 goto out;
1574 }
1575 if (start < c->u.iomem.low_iomem) {
1576 /* found a gap */
1577 rc = fn(data, SECINITSID_IOMEM, start, c->u.iomem.low_iomem - 1);
1578 if (rc)
1579 goto out;
1580 start = c->u.iomem.low_iomem;
1581 }
1582 if (end <= c->u.iomem.high_iomem) {
1583 /* iteration ends in the middle of this range */
1584 rc = fn(data, c->sid, start, end);
1585 goto out;
1586 }
1587
1588 rc = fn(data, c->sid, start, c->u.iomem.high_iomem);
1589 if (rc)
1590 goto out;
1591 start = c->u.iomem.high_iomem + 1;
1592
1593 c = c->next;
1594 }
1595
1596 rc = fn(data, SECINITSID_IOMEM, start, end);
1597
1598 out:
1599 POLICY_RDUNLOCK;
1600 return rc;
1601 }
1602
1603 /**
1604 * security_ioport_sid - Obtain the SID for an ioport.
1605 * @ioport: ioport
1606 * @out_sid: security identifier
1607 */
security_ioport_sid(u32 ioport,u32 * out_sid)1608 int security_ioport_sid(u32 ioport, u32 *out_sid)
1609 {
1610 struct ocontext *c;
1611 int rc = 0;
1612
1613 POLICY_RDLOCK;
1614
1615 c = policydb.ocontexts[OCON_IOPORT];
1616 while ( c )
1617 {
1618 if ( c->u.ioport.low_ioport <= ioport &&
1619 c->u.ioport.high_ioport >= ioport )
1620 break;
1621 c = c->next;
1622 }
1623
1624 if ( c )
1625 {
1626 if ( !c->sid )
1627 {
1628 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1629 if ( rc )
1630 goto out;
1631 }
1632 *out_sid = c->sid;
1633 }
1634 else
1635 {
1636 *out_sid = SECINITSID_IOPORT;
1637 }
1638
1639 out:
1640 POLICY_RDUNLOCK;
1641 return rc;
1642 }
1643
security_iterate_ioport_sids(u32 start,u32 end,security_iterate_fn fn,void * data)1644 int security_iterate_ioport_sids(u32 start, u32 end,
1645 security_iterate_fn fn, void *data)
1646 {
1647 struct ocontext *c;
1648 int rc = 0;
1649
1650 POLICY_RDLOCK;
1651
1652 c = policydb.ocontexts[OCON_IOPORT];
1653 while (c && c->u.ioport.high_ioport < start)
1654 c = c->next;
1655
1656 while (c && c->u.ioport.low_ioport <= end) {
1657 if (!c->sid)
1658 {
1659 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1660 if ( rc )
1661 goto out;
1662 }
1663 if (start < c->u.ioport.low_ioport) {
1664 /* found a gap */
1665 rc = fn(data, SECINITSID_IOPORT, start, c->u.ioport.low_ioport - 1);
1666 if (rc)
1667 goto out;
1668 start = c->u.ioport.low_ioport;
1669 }
1670 if (end <= c->u.ioport.high_ioport) {
1671 /* iteration ends in the middle of this range */
1672 rc = fn(data, c->sid, start, end);
1673 goto out;
1674 }
1675
1676 rc = fn(data, c->sid, start, c->u.ioport.high_ioport);
1677 if (rc)
1678 goto out;
1679 start = c->u.ioport.high_ioport + 1;
1680
1681 c = c->next;
1682 }
1683
1684 rc = fn(data, SECINITSID_IOPORT, start, end);
1685
1686 out:
1687 POLICY_RDUNLOCK;
1688 return rc;
1689 }
1690
1691 /**
1692 * security_device_sid - Obtain the SID for a PCI device.
1693 * @ioport: device
1694 * @out_sid: security identifier
1695 */
security_device_sid(u32 device,u32 * out_sid)1696 int security_device_sid(u32 device, u32 *out_sid)
1697 {
1698 struct ocontext *c;
1699 int rc = 0;
1700
1701 POLICY_RDLOCK;
1702
1703 c = policydb.ocontexts[OCON_DEVICE];
1704 while ( c )
1705 {
1706 if ( c->u.device == device )
1707 break;
1708 c = c->next;
1709 }
1710
1711 if ( c )
1712 {
1713 if ( !c->sid )
1714 {
1715 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1716 if ( rc )
1717 goto out;
1718 }
1719 *out_sid = c->sid;
1720 }
1721 else
1722 {
1723 *out_sid = SECINITSID_DEVICE;
1724 }
1725
1726 out:
1727 POLICY_RDUNLOCK;
1728 return rc;
1729 }
1730
security_devicetree_sid(const char * path,u32 * out_sid)1731 int security_devicetree_sid(const char *path, u32 *out_sid)
1732 {
1733 struct ocontext *c;
1734 int rc = 0;
1735
1736 POLICY_RDLOCK;
1737
1738 c = policydb.ocontexts[OCON_DTREE];
1739 while ( c )
1740 {
1741 if ( strcmp(c->u.name, path) == 0 )
1742 break;
1743 c = c->next;
1744 }
1745
1746 if ( c )
1747 {
1748 if ( !c->sid )
1749 {
1750 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1751 if ( rc )
1752 goto out;
1753 }
1754 *out_sid = c->sid;
1755 }
1756 else
1757 {
1758 *out_sid = SECINITSID_DEVICE;
1759 }
1760
1761 out:
1762 POLICY_RDUNLOCK;
1763 return rc;
1764 }
1765
security_find_bool(const char * name)1766 int security_find_bool(const char *name)
1767 {
1768 int i, rv = -ENOENT;
1769 POLICY_RDLOCK;
1770 for ( i = 0; i < policydb.p_bools.nprim; i++ )
1771 {
1772 if (!strcmp(name, policydb.p_bool_val_to_name[i]))
1773 {
1774 rv = i;
1775 break;
1776 }
1777 }
1778
1779 POLICY_RDUNLOCK;
1780 return rv;
1781 }
1782
security_get_bools(int * len,char *** names,int ** values,size_t * maxstr)1783 int security_get_bools(int *len, char ***names, int **values, size_t *maxstr)
1784 {
1785 int i, rc = -ENOMEM;
1786
1787 POLICY_RDLOCK;
1788 if ( names )
1789 *names = NULL;
1790 *values = NULL;
1791 if ( maxstr )
1792 *maxstr = 0;
1793
1794 *len = policydb.p_bools.nprim;
1795 if ( !*len )
1796 {
1797 rc = 0;
1798 goto out;
1799 }
1800
1801 if ( names )
1802 {
1803 *names = xzalloc_array(char *, *len);
1804 if ( !*names )
1805 goto err;
1806 }
1807
1808 *values = xmalloc_array(int, *len);
1809 if ( !*values )
1810 goto err;
1811
1812 for ( i = 0; i < *len; i++ )
1813 {
1814 size_t name_len = strlen(policydb.p_bool_val_to_name[i]);
1815
1816 (*values)[i] = policydb.bool_val_to_struct[i]->state;
1817 if ( names ) {
1818 (*names)[i] = xmalloc_array(char, name_len + 1);
1819 if ( !(*names)[i] )
1820 goto err;
1821 strlcpy((*names)[i], policydb.p_bool_val_to_name[i], name_len + 1);
1822 }
1823 if ( maxstr && name_len > *maxstr )
1824 *maxstr = name_len;
1825 }
1826 rc = 0;
1827 out:
1828 POLICY_RDUNLOCK;
1829 return rc;
1830 err:
1831 if ( names && *names )
1832 {
1833 for ( i = 0; i < *len; i++ )
1834 xfree((*names)[i]);
1835 xfree(*names);
1836 }
1837 xfree(*values);
1838 goto out;
1839 }
1840
1841
security_set_bools(int len,int * values)1842 int security_set_bools(int len, int *values)
1843 {
1844 int i, rc = 0;
1845 int lenp, seqno = 0;
1846 struct cond_node *cur;
1847
1848 POLICY_WRLOCK;
1849
1850 lenp = policydb.p_bools.nprim;
1851 if ( len != lenp )
1852 {
1853 rc = -EFAULT;
1854 goto out;
1855 }
1856
1857 printk(KERN_INFO "Flask: committed booleans { ");
1858 for ( i = 0; i < len; i++ )
1859 {
1860 if ( values[i] )
1861 {
1862 policydb.bool_val_to_struct[i]->state = 1;
1863 }
1864 else
1865 {
1866 policydb.bool_val_to_struct[i]->state = 0;
1867 }
1868 if ( i != 0 )
1869 printk(", ");
1870 printk("%s:%d", policydb.p_bool_val_to_name[i],
1871 policydb.bool_val_to_struct[i]->state);
1872 }
1873 printk(" }\n");
1874
1875 for ( cur = policydb.cond_list; cur != NULL; cur = cur->next )
1876 {
1877 rc = evaluate_cond_node(&policydb, cur);
1878 if ( rc )
1879 goto out;
1880 }
1881
1882 seqno = ++latest_granting;
1883
1884 out:
1885 POLICY_WRUNLOCK;
1886 if ( !rc )
1887 {
1888 avc_ss_reset(seqno);
1889 }
1890 return rc;
1891 }
1892
security_get_bool_value(unsigned int b)1893 int security_get_bool_value(unsigned int b)
1894 {
1895 int rc = 0;
1896 unsigned int len;
1897
1898 POLICY_RDLOCK;
1899
1900 len = policydb.p_bools.nprim;
1901 if ( b >= len )
1902 {
1903 rc = -ENOENT;
1904 goto out;
1905 }
1906
1907 rc = policydb.bool_val_to_struct[b]->state;
1908 out:
1909 POLICY_RDUNLOCK;
1910 return rc;
1911 }
1912
security_get_bool_name(unsigned int b)1913 char *security_get_bool_name(unsigned int b)
1914 {
1915 unsigned int len;
1916 char *rv = NULL;
1917
1918 POLICY_RDLOCK;
1919
1920 len = policydb.p_bools.nprim;
1921 if ( b >= len )
1922 {
1923 goto out;
1924 }
1925
1926 len = strlen(policydb.p_bool_val_to_name[b]) + 1;
1927 rv = xmalloc_array(char, len);
1928 if ( !rv )
1929 goto out;
1930 memcpy(rv, policydb.p_bool_val_to_name[b], len);
1931 out:
1932 POLICY_RDUNLOCK;
1933 return rv;
1934 }
1935
security_preserve_bools(struct policydb * p)1936 static int security_preserve_bools(struct policydb *p)
1937 {
1938 int rc, nbools = 0, *bvalues = NULL, i;
1939 char **bnames = NULL;
1940 struct cond_bool_datum *booldatum;
1941 struct cond_node *cur;
1942
1943 rc = security_get_bools(&nbools, &bnames, &bvalues, NULL);
1944 if ( rc )
1945 return rc;
1946 for ( i = 0; i < nbools; i++ )
1947 {
1948 booldatum = hashtab_search(p->p_bools.table, bnames[i]);
1949 if ( booldatum )
1950 booldatum->state = bvalues[i];
1951 }
1952 for ( cur = p->cond_list; cur; cur = cur->next )
1953 {
1954 rc = evaluate_cond_node(p, cur);
1955 if ( rc )
1956 goto out;
1957 }
1958
1959 out:
1960 if ( bnames )
1961 {
1962 for ( i = 0; i < nbools; i++ )
1963 xfree(bnames[i]);
1964 }
1965 xfree(bnames);
1966 xfree(bvalues);
1967 return rc;
1968 }
1969
security_ocontext_add(u32 ocon,unsigned long low,unsigned long high,u32 sid)1970 int security_ocontext_add( u32 ocon, unsigned long low, unsigned long high
1971 ,u32 sid )
1972 {
1973 int ret = 0;
1974 struct ocontext *c;
1975 struct ocontext *prev;
1976 struct ocontext *add;
1977
1978 if ( (add = xzalloc(struct ocontext)) == NULL )
1979 return -ENOMEM;
1980 add->sid = sid;
1981
1982 POLICY_WRLOCK;
1983 switch( ocon )
1984 {
1985 case OCON_PIRQ:
1986 add->u.pirq = (u16)low;
1987 if ( high != low )
1988 {
1989 ret = -EINVAL;
1990 break;
1991 }
1992
1993 c = policydb.ocontexts[OCON_PIRQ];
1994 while ( c )
1995 {
1996 if ( c->u.pirq == add->u.pirq )
1997 {
1998 if ( c->sid == sid )
1999 break;
2000 printk("flask: Duplicate pirq %d\n", add->u.pirq);
2001 ret = -EEXIST;
2002 break;
2003 }
2004 c = c->next;
2005 }
2006
2007 if ( ret == 0 )
2008 {
2009 add->next = policydb.ocontexts[OCON_PIRQ];
2010 policydb.ocontexts[OCON_PIRQ] = add;
2011 }
2012 break;
2013
2014 case OCON_IOPORT:
2015 add->u.ioport.low_ioport = low;
2016 add->u.ioport.high_ioport = high;
2017
2018 prev = NULL;
2019 c = policydb.ocontexts[OCON_IOPORT];
2020
2021 while ( c && c->u.ioport.high_ioport < low ) {
2022 prev = c;
2023 c = c->next;
2024 }
2025
2026 if (c && c->u.ioport.low_ioport <= high)
2027 {
2028 if (c->u.ioport.low_ioport == low &&
2029 c->u.ioport.high_ioport == high && c->sid == sid)
2030 break;
2031
2032 printk("flask: IO Port overlap with entry %#x - %#x\n",
2033 c->u.ioport.low_ioport, c->u.ioport.high_ioport);
2034 ret = -EEXIST;
2035 break;
2036 }
2037
2038 if (prev) {
2039 add->next = prev->next;
2040 prev->next = add;
2041 } else {
2042 add->next = policydb.ocontexts[OCON_IOPORT];
2043 policydb.ocontexts[OCON_IOPORT] = add;
2044 }
2045 break;
2046
2047 case OCON_IOMEM:
2048 add->u.iomem.low_iomem = low;
2049 add->u.iomem.high_iomem = high;
2050
2051 prev = NULL;
2052 c = policydb.ocontexts[OCON_IOMEM];
2053
2054 while ( c && c->u.iomem.high_iomem < low ) {
2055 prev = c;
2056 c = c->next;
2057 }
2058
2059 if (c && c->u.iomem.low_iomem <= high)
2060 {
2061 if (c->u.iomem.low_iomem == low &&
2062 c->u.iomem.high_iomem == high && c->sid == sid)
2063 break;
2064
2065 printk("flask: IO Memory overlap with entry %#"PRIx64" - %#"PRIx64"\n",
2066 c->u.iomem.low_iomem, c->u.iomem.high_iomem);
2067 ret = -EEXIST;
2068 break;
2069 }
2070
2071 if (prev) {
2072 add->next = prev->next;
2073 prev->next = add;
2074 } else {
2075 add->next = policydb.ocontexts[OCON_IOMEM];
2076 policydb.ocontexts[OCON_IOMEM] = add;
2077 }
2078 break;
2079
2080 case OCON_DEVICE:
2081 add->u.device = low;
2082 if ( high != low )
2083 {
2084 ret = -EINVAL;
2085 break;
2086 }
2087
2088 c = policydb.ocontexts[OCON_DEVICE];
2089 while ( c )
2090 {
2091 if ( c->u.device == add->u.device )
2092 {
2093 if ( c->sid == sid )
2094 break;
2095
2096 printk("flask: Duplicate PCI Device %#x\n", add->u.device);
2097 ret = -EEXIST;
2098 break;
2099 }
2100 c = c->next;
2101 }
2102
2103 if ( ret == 0 )
2104 {
2105 add->next = policydb.ocontexts[OCON_DEVICE];
2106 policydb.ocontexts[OCON_DEVICE] = add;
2107 }
2108 break;
2109
2110 default:
2111 ret = -EINVAL;
2112 }
2113 POLICY_WRUNLOCK;
2114
2115 if ( ret != 0 )
2116 xfree(add);
2117 return ret;
2118 }
2119
security_ocontext_del(u32 ocon,unsigned long low,unsigned long high)2120 int security_ocontext_del( u32 ocon, unsigned long low, unsigned long high )
2121 {
2122 int ret = 0;
2123 struct ocontext *c, *before_c;
2124
2125 POLICY_WRLOCK;
2126 switch( ocon )
2127 {
2128 case OCON_PIRQ:
2129 for ( before_c = NULL, c = policydb.ocontexts[OCON_PIRQ];
2130 c; before_c = c, c = c->next )
2131 {
2132 if ( c->u.pirq == low )
2133 {
2134 if ( before_c == NULL )
2135 {
2136 policydb.ocontexts[OCON_PIRQ] = c->next;
2137 xfree(c);
2138 goto out;
2139 }
2140 else
2141 {
2142 before_c->next = c->next;
2143 xfree(c);
2144 goto out;
2145 }
2146 }
2147 }
2148
2149 printk("flask: ocontext not found: pirq %ld\n", low);
2150 ret = -ENOENT;
2151 break;
2152
2153 case OCON_IOPORT:
2154 for ( before_c = NULL, c = policydb.ocontexts[OCON_IOPORT];
2155 c; before_c = c, c = c->next )
2156 {
2157 if ( c->u.ioport.low_ioport == low &&
2158 c->u.ioport.high_ioport == high )
2159 {
2160 if ( before_c == NULL )
2161 {
2162 policydb.ocontexts[OCON_IOPORT] = c->next;
2163 xfree(c);
2164 goto out;
2165 }
2166 else
2167 {
2168 before_c->next = c->next;
2169 xfree(c);
2170 goto out;
2171 }
2172 }
2173 }
2174
2175 printk("flask: ocontext not found: ioport %#lx - %#lx\n", low, high);
2176 ret = -ENOENT;
2177 break;
2178
2179 case OCON_IOMEM:
2180 for ( before_c = NULL, c = policydb.ocontexts[OCON_IOMEM];
2181 c; before_c = c, c = c->next )
2182 {
2183 if ( c->u.iomem.low_iomem == low &&
2184 c->u.iomem.high_iomem == high )
2185 {
2186 if ( before_c == NULL )
2187 {
2188 policydb.ocontexts[OCON_IOMEM] = c->next;
2189 xfree(c);
2190 goto out;
2191 }
2192 else
2193 {
2194 before_c->next = c->next;
2195 xfree(c);
2196 goto out;
2197 }
2198 }
2199 }
2200
2201 printk("flask: ocontext not found: iomem %#lx - %#lx\n", low, high);
2202 ret = -ENOENT;
2203 break;
2204
2205 case OCON_DEVICE:
2206 for ( before_c = NULL, c = policydb.ocontexts[OCON_DEVICE];
2207 c; before_c = c, c = c->next )
2208 {
2209 if ( c->u.device == low )
2210 {
2211 if ( before_c == NULL )
2212 {
2213 policydb.ocontexts[OCON_DEVICE] = c->next;
2214 xfree(c);
2215 goto out;
2216 }
2217 else
2218 {
2219 before_c->next = c->next;
2220 xfree(c);
2221 goto out;
2222 }
2223 }
2224 }
2225
2226 printk("flask: ocontext not found: pcidevice %#lx\n", low);
2227 ret = -ENOENT;
2228 break;
2229
2230 default:
2231 ret = -EINVAL;
2232 }
2233
2234 out:
2235 POLICY_WRUNLOCK;
2236 return ret;
2237 }
2238
security_devicetree_setlabel(char * path,u32 sid)2239 int security_devicetree_setlabel(char *path, u32 sid)
2240 {
2241 int ret = 0;
2242 struct ocontext *c;
2243 struct ocontext **pcurr;
2244 struct ocontext *add = NULL;
2245
2246 if ( sid )
2247 {
2248 add = xzalloc(struct ocontext);
2249 if ( add == NULL )
2250 {
2251 xfree(path);
2252 return -ENOMEM;
2253 }
2254 add->sid = sid;
2255 add->u.name = path;
2256 }
2257 else
2258 {
2259 ret = -ENOENT;
2260 }
2261
2262 POLICY_WRLOCK;
2263
2264 pcurr = &policydb.ocontexts[OCON_DTREE];
2265 c = *pcurr;
2266 while ( c )
2267 {
2268 if ( strcmp(c->u.name, path) == 0 )
2269 {
2270 if ( sid )
2271 {
2272 ret = -EEXIST;
2273 break;
2274 }
2275 else
2276 {
2277 *pcurr = c->next;
2278 xfree(c->u.name);
2279 xfree(c);
2280 ret = 0;
2281 break;
2282 }
2283 }
2284 pcurr = &c->next;
2285 c = *pcurr;
2286 }
2287
2288 if ( add && ret == 0 )
2289 {
2290 add->next = policydb.ocontexts[OCON_DTREE];
2291 policydb.ocontexts[OCON_DTREE] = add;
2292 add = NULL;
2293 path = NULL;
2294 }
2295
2296 POLICY_WRUNLOCK;
2297
2298 xfree(add);
2299 xfree(path);
2300 return ret;
2301 }
2302