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 strlcpy(scontextp, initial_sid_to_string[sid], *scontext_len);
779 *scontext = scontextp;
780 goto out;
781 }
782 printk(KERN_ERR "security_sid_to_context: called before initial "
783 "load_policy on unknown SID %d\n", sid);
784 rc = -EINVAL;
785 goto out;
786 }
787 POLICY_RDLOCK;
788 context = sidtab_search(&sidtab, sid);
789 if ( !context )
790 {
791 printk(KERN_ERR "security_sid_to_context: unrecognized SID "
792 "%d\n", sid);
793 rc = -EINVAL;
794 goto out_unlock;
795 }
796 rc = context_struct_to_string(context, scontext, scontext_len);
797 out_unlock:
798 POLICY_RDUNLOCK;
799 out:
800 return rc;
801
802 }
803
804 /**
805 * security_context_to_sid - Obtain a SID for a given security context.
806 * @scontext: security context
807 * @scontext_len: length in bytes
808 * @sid: security identifier, SID
809 *
810 * Obtains a SID associated with the security context that
811 * has the string representation specified by @scontext.
812 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
813 * memory is available, or 0 on success.
814 */
security_context_to_sid(char * scontext,u32 scontext_len,u32 * sid)815 int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
816 {
817 char *scontext2;
818 struct context context;
819 struct role_datum *role;
820 struct type_datum *typdatum;
821 struct user_datum *usrdatum;
822 char *scontextp, *p, oldc;
823 int rc = 0;
824
825 if ( !ss_initialized )
826 {
827 int i;
828
829 for ( i = 1; i < SECINITSID_NUM; i++ )
830 {
831 if ( !strcmp(initial_sid_to_string[i], scontext) )
832 {
833 *sid = i;
834 goto out;
835 }
836 }
837 *sid = SECINITSID_XEN;
838 goto out;
839 }
840 *sid = SECSID_NULL;
841
842 /* Copy the string so that we can modify the copy as we parse it.
843 The string should already by null terminated, but we append a
844 null suffix to the copy to avoid problems with the existing
845 attr package, which doesn't view the null terminator as part
846 of the attribute value. */
847 scontext2 = xmalloc_array(char, scontext_len+1);
848 if ( !scontext2 )
849 {
850 rc = -ENOMEM;
851 goto out;
852 }
853 memcpy(scontext2, scontext, scontext_len);
854 scontext2[scontext_len] = 0;
855
856 context_init(&context);
857 *sid = SECSID_NULL;
858
859 POLICY_RDLOCK;
860
861 /* Parse the security context. */
862
863 rc = -EINVAL;
864 scontextp = (char *) scontext2;
865
866 /* Extract the user. */
867 p = scontextp;
868 while ( *p && *p != ':' )
869 p++;
870
871 if (*p == 0)
872 goto out_unlock;
873
874 *p++ = 0;
875
876 usrdatum = hashtab_search(policydb.p_users.table, scontextp);
877 if ( !usrdatum )
878 goto out_unlock;
879
880 context.user = usrdatum->value;
881
882 /* Extract role. */
883 scontextp = p;
884 while ( *p && *p != ':' )
885 p++;
886
887 if ( *p == 0 )
888 goto out_unlock;
889
890 *p++ = 0;
891
892 role = hashtab_search(policydb.p_roles.table, scontextp);
893 if ( !role )
894 goto out_unlock;
895 context.role = role->value;
896
897 /* Extract type. */
898 scontextp = p;
899 while ( *p && *p != ':' )
900 p++;
901 oldc = *p;
902 *p++ = 0;
903
904 typdatum = hashtab_search(policydb.p_types.table, scontextp);
905 if ( !typdatum || typdatum->attribute )
906 goto out_unlock;
907
908 context.type = typdatum->value;
909
910 rc = mls_context_to_sid(oldc, &p, &context, &sidtab);
911 if ( rc )
912 goto out_unlock;
913
914 if ( (p - scontext2) < scontext_len )
915 {
916 rc = -EINVAL;
917 goto out_unlock;
918 }
919
920 /* Check the validity of the new context. */
921 if ( !policydb_context_isvalid(&policydb, &context) )
922 {
923 rc = -EINVAL;
924 goto out_unlock;
925 }
926 /* Obtain the new sid. */
927 rc = sidtab_context_to_sid(&sidtab, &context, sid);
928 out_unlock:
929 POLICY_RDUNLOCK;
930 context_destroy(&context);
931 xfree(scontext2);
932 out:
933 return rc;
934 }
935
compute_sid_handle_invalid_context(struct context * scontext,struct context * tcontext,u16 tclass,struct context * newcontext)936 static int compute_sid_handle_invalid_context(
937 struct context *scontext, struct context *tcontext, u16 tclass,
938 struct context *newcontext)
939 {
940 char *s = NULL, *t = NULL, *n = NULL;
941 u32 slen, tlen, nlen;
942
943 if ( context_struct_to_string(scontext, &s, &slen) < 0 )
944 goto out;
945 if ( context_struct_to_string(tcontext, &t, &tlen) < 0 )
946 goto out;
947 if ( context_struct_to_string(newcontext, &n, &nlen) < 0 )
948 goto out;
949 printk("security_compute_sid: invalid context %s"
950 " for scontext=%s"
951 " tcontext=%s"
952 " tclass=%s",
953 n, s, t, policydb.p_class_val_to_name[tclass-1]);
954 out:
955 xfree(s);
956 xfree(t);
957 xfree(n);
958 if ( !flask_enforcing )
959 return 0;
960 return -EACCES;
961 }
962
security_compute_sid(u32 ssid,u32 tsid,u16 tclass,u32 specified,u32 * out_sid)963 static int security_compute_sid(u32 ssid,
964 u32 tsid,
965 u16 tclass,
966 u32 specified,
967 u32 *out_sid)
968 {
969 struct context *scontext = NULL, *tcontext = NULL, newcontext;
970 struct role_trans *roletr = NULL;
971 struct avtab_key avkey;
972 struct avtab_datum *avdatum;
973 struct avtab_node *node;
974 int rc = 0;
975
976 if ( !ss_initialized )
977 {
978 switch ( tclass )
979 {
980 case SECCLASS_DOMAIN:
981 *out_sid = ssid;
982 break;
983 default:
984 *out_sid = tsid;
985 break;
986 }
987 goto out;
988 }
989
990 POLICY_RDLOCK;
991
992 scontext = sidtab_search(&sidtab, ssid);
993 if ( !scontext )
994 {
995 printk(KERN_ERR "security_compute_sid: unrecognized SID %d\n", ssid);
996 rc = -EINVAL;
997 goto out_unlock;
998 }
999 tcontext = sidtab_search(&sidtab, tsid);
1000 if ( !tcontext )
1001 {
1002 printk(KERN_ERR "security_compute_sid: unrecognized SID %d\n", tsid);
1003 rc = -EINVAL;
1004 goto out_unlock;
1005 }
1006
1007 context_init(&newcontext);
1008
1009 /* Set the user identity. */
1010 switch ( specified )
1011 {
1012 case AVTAB_TRANSITION:
1013 case AVTAB_CHANGE:
1014 /* Use the process user identity. */
1015 newcontext.user = scontext->user;
1016 break;
1017 case AVTAB_MEMBER:
1018 /* Use the related object owner. */
1019 newcontext.user = tcontext->user;
1020 break;
1021 }
1022
1023 /* Set the role and type to default values. */
1024 switch ( tclass )
1025 {
1026 case SECCLASS_DOMAIN:
1027 /* Use the current role and type of process. */
1028 newcontext.role = scontext->role;
1029 newcontext.type = scontext->type;
1030 break;
1031 default:
1032 /* Use the well-defined object role. */
1033 newcontext.role = OBJECT_R_VAL;
1034 /* Use the type of the related object. */
1035 newcontext.type = tcontext->type;
1036 }
1037
1038 /* Look for a type transition/member/change rule. */
1039 avkey.source_type = scontext->type;
1040 avkey.target_type = tcontext->type;
1041 avkey.target_class = tclass;
1042 avkey.specified = specified;
1043 avdatum = avtab_search(&policydb.te_avtab, &avkey);
1044
1045 /* If no permanent rule, also check for enabled conditional rules */
1046 if ( !avdatum )
1047 {
1048 node = avtab_search_node(&policydb.te_cond_avtab, &avkey);
1049 for ( ; node != NULL; node = avtab_search_node_next(node, specified) )
1050 {
1051 if ( node->key.specified & AVTAB_ENABLED )
1052 {
1053 avdatum = &node->datum;
1054 break;
1055 }
1056 }
1057 }
1058
1059 if ( avdatum )
1060 {
1061 /* Use the type from the type transition/member/change rule. */
1062 newcontext.type = avdatum->data;
1063 }
1064
1065 /* Check for class-specific changes. */
1066 switch ( tclass )
1067 {
1068 case SECCLASS_DOMAIN:
1069 if ( specified & AVTAB_TRANSITION )
1070 {
1071 /* Look for a role transition rule. */
1072 for ( roletr = policydb.role_tr; roletr; roletr = roletr->next )
1073 {
1074 if ( roletr->role == scontext->role &&
1075 roletr->type == tcontext->type )
1076 {
1077 /* Use the role transition rule. */
1078 newcontext.role = roletr->new_role;
1079 break;
1080 }
1081 }
1082 }
1083 break;
1084 default:
1085 break;
1086 }
1087
1088 /* Set the MLS attributes.
1089 This is done last because it may allocate memory. */
1090 rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext);
1091 if ( rc )
1092 goto out_unlock;
1093
1094 /* Check the validity of the context. */
1095 if ( !policydb_context_isvalid(&policydb, &newcontext) )
1096 {
1097 rc = compute_sid_handle_invalid_context(scontext, tcontext, tclass,
1098 &newcontext);
1099 if ( rc )
1100 goto out_unlock;
1101 }
1102 /* Obtain the sid for the context. */
1103 rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid);
1104 out_unlock:
1105 POLICY_RDUNLOCK;
1106 context_destroy(&newcontext);
1107 out:
1108 return rc;
1109 }
1110
1111 /**
1112 * security_transition_sid - Compute the SID for a new subject/object.
1113 * @ssid: source security identifier
1114 * @tsid: target security identifier
1115 * @tclass: target security class
1116 * @out_sid: security identifier for new subject/object
1117 *
1118 * Compute a SID to use for labeling a new subject or object in the
1119 * class @tclass based on a SID pair (@ssid, @tsid).
1120 * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
1121 * if insufficient memory is available, or %0 if the new SID was
1122 * computed successfully.
1123 */
security_transition_sid(u32 ssid,u32 tsid,u16 tclass,u32 * out_sid)1124 int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid)
1125 {
1126 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid);
1127 }
1128
1129 /**
1130 * security_member_sid - Compute the SID for member selection.
1131 * @ssid: source security identifier
1132 * @tsid: target security identifier
1133 * @tclass: target security class
1134 * @out_sid: security identifier for selected member
1135 *
1136 * Compute a SID to use when selecting a member of a polyinstantiated
1137 * object of class @tclass based on a SID pair (@ssid, @tsid).
1138 * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
1139 * if insufficient memory is available, or %0 if the SID was
1140 * computed successfully.
1141 */
security_member_sid(u32 ssid,u32 tsid,u16 tclass,u32 * out_sid)1142 int security_member_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid)
1143 {
1144 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid);
1145 }
1146
1147 /**
1148 * security_change_sid - Compute the SID for object relabeling.
1149 * @ssid: source security identifier
1150 * @tsid: target security identifier
1151 * @tclass: target security class
1152 * @out_sid: security identifier for selected member
1153 *
1154 * Compute a SID to use for relabeling an object of class @tclass
1155 * based on a SID pair (@ssid, @tsid).
1156 * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
1157 * if insufficient memory is available, or %0 if the SID was
1158 * computed successfully.
1159 */
security_change_sid(u32 ssid,u32 tsid,u16 tclass,u32 * out_sid)1160 int security_change_sid(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid)
1161 {
1162 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid);
1163 }
1164
1165 /*
1166 * Verify that each kernel class that is defined in the
1167 * policy is correct
1168 */
validate_classes(struct policydb * p)1169 static int validate_classes(struct policydb *p)
1170 {
1171 int i;
1172 struct class_datum *cladatum;
1173 struct perm_datum *perdatum;
1174 u32 nprim, perm_val, pol_val;
1175 u16 class_val;
1176 const struct selinux_class_perm *kdefs = &selinux_class_perm;
1177 const char *def_class, *def_perm, *pol_class;
1178 struct symtab *perms;
1179
1180 for ( i = 1; i < kdefs->cts_len; i++ )
1181 {
1182 def_class = kdefs->class_to_string[i];
1183 if ( !def_class )
1184 continue;
1185 if ( i > p->p_classes.nprim )
1186 {
1187 printk(KERN_INFO
1188 "Flask: class %s not defined in policy\n",
1189 def_class);
1190 return -EINVAL;
1191 }
1192 pol_class = p->p_class_val_to_name[i-1];
1193 if ( strcmp(pol_class, def_class) )
1194 {
1195 printk(KERN_ERR
1196 "Flask: class %d is incorrect, found %s but should be %s\n",
1197 i, pol_class, def_class);
1198 return -EINVAL;
1199 }
1200 }
1201 for ( i = 0; i < kdefs->av_pts_len; i++ )
1202 {
1203 class_val = kdefs->av_perm_to_string[i].tclass;
1204 perm_val = kdefs->av_perm_to_string[i].value;
1205 def_perm = kdefs->av_perm_to_string[i].name;
1206 if ( class_val > p->p_classes.nprim )
1207 continue;
1208 pol_class = p->p_class_val_to_name[class_val-1];
1209 cladatum = hashtab_search(p->p_classes.table, pol_class);
1210 BUG_ON( !cladatum );
1211 perms = &cladatum->permissions;
1212 nprim = 1 << (perms->nprim - 1);
1213 if ( perm_val > nprim )
1214 {
1215 printk(KERN_INFO
1216 "Flask: permission %s in class %s not defined in policy\n",
1217 def_perm, pol_class);
1218 return -EINVAL;
1219 }
1220 perdatum = hashtab_search(perms->table, def_perm);
1221 if ( perdatum == NULL )
1222 {
1223 printk(KERN_ERR
1224 "Flask: permission %s in class %s not found in policy\n",
1225 def_perm, pol_class);
1226 return -EINVAL;
1227 }
1228 pol_val = 1 << (perdatum->value - 1);
1229 if ( pol_val != perm_val )
1230 {
1231 printk(KERN_ERR
1232 "Flask: permission %s in class %s has incorrect value\n",
1233 def_perm, pol_class);
1234 return -EINVAL;
1235 }
1236 }
1237 return 0;
1238 }
1239
1240 /* Clone the SID into the new SID table. */
clone_sid(u32 sid,struct context * context,void * arg)1241 static int clone_sid(u32 sid, struct context *context, void *arg)
1242 {
1243 struct sidtab *s = arg;
1244
1245 return sidtab_insert(s, sid, context);
1246 }
1247
convert_context_handle_invalid_context(struct context * context)1248 static inline int convert_context_handle_invalid_context(struct context *context)
1249 {
1250 int rc = 0;
1251
1252 if ( flask_enforcing )
1253 rc = -EINVAL;
1254 else
1255 {
1256 char *s;
1257 u32 len;
1258
1259 context_struct_to_string(context, &s, &len);
1260 printk(KERN_ERR "Flask: context %s is invalid\n", s);
1261 xfree(s);
1262 }
1263 return rc;
1264 }
1265
1266 struct convert_context_args {
1267 struct policydb *oldp;
1268 struct policydb *newp;
1269 };
1270
1271 /*
1272 * Convert the values in the security context
1273 * structure `c' from the values specified
1274 * in the policy `p->oldp' to the values specified
1275 * in the policy `p->newp'. Verify that the
1276 * context is valid under the new policy.
1277 */
convert_context(u32 key,struct context * c,void * p)1278 static int convert_context(u32 key, struct context *c, void *p)
1279 {
1280 struct convert_context_args *args;
1281 struct context oldc;
1282 struct role_datum *role;
1283 struct type_datum *typdatum;
1284 struct user_datum *usrdatum;
1285 char *s;
1286 u32 len;
1287 int rc;
1288
1289 args = p;
1290
1291 rc = context_cpy(&oldc, c);
1292 if ( rc )
1293 goto out;
1294
1295 rc = -EINVAL;
1296
1297 /* Convert the user. */
1298 usrdatum = hashtab_search(args->newp->p_users.table,
1299 args->oldp->p_user_val_to_name[c->user - 1]);
1300 if ( !usrdatum )
1301 goto bad;
1302
1303 c->user = usrdatum->value;
1304
1305 /* Convert the role. */
1306 role = hashtab_search(args->newp->p_roles.table,
1307 args->oldp->p_role_val_to_name[c->role - 1]);
1308 if ( !role )
1309 goto bad;
1310
1311 c->role = role->value;
1312
1313 /* Convert the type. */
1314 typdatum = hashtab_search(args->newp->p_types.table,
1315 args->oldp->p_type_val_to_name[c->type - 1]);
1316 if ( !typdatum )
1317 goto bad;
1318
1319 c->type = typdatum->value;
1320
1321 rc = mls_convert_context(args->oldp, args->newp, c);
1322 if ( rc )
1323 goto bad;
1324
1325 /* Check the validity of the new context. */
1326 if ( !policydb_context_isvalid(args->newp, c) )
1327 {
1328 rc = convert_context_handle_invalid_context(&oldc);
1329 if ( rc )
1330 goto bad;
1331 }
1332
1333 context_destroy(&oldc);
1334 out:
1335 return rc;
1336 bad:
1337 context_struct_to_string(&oldc, &s, &len);
1338 context_destroy(&oldc);
1339 printk(KERN_ERR "Flask: invalidating context %s\n", s);
1340 xfree(s);
1341 goto out;
1342 }
1343
1344 static int security_preserve_bools(struct policydb *p);
1345
1346 /**
1347 * security_load_policy - Load a security policy configuration.
1348 * @data: binary policy data
1349 * @len: length of data in bytes
1350 *
1351 * Load a new set of security policy configuration data,
1352 * validate it and convert the SID table as necessary.
1353 * This function will flush the access vector cache after
1354 * loading the new policy.
1355 */
security_load_policy(const void * data,size_t len)1356 int security_load_policy(const void *data, size_t len)
1357 {
1358 struct policydb oldpolicydb, newpolicydb;
1359 struct sidtab oldsidtab, newsidtab;
1360 struct convert_context_args args;
1361 u32 seqno;
1362 int rc = 0;
1363 struct policy_file file = { data, len }, *fp = &file;
1364
1365 LOAD_LOCK;
1366
1367 if ( !ss_initialized )
1368 {
1369 if ( policydb_read(&policydb, fp) )
1370 {
1371 LOAD_UNLOCK;
1372 return -EINVAL;
1373 }
1374 if ( policydb_load_isids(&policydb, &sidtab) )
1375 {
1376 LOAD_UNLOCK;
1377 policydb_destroy(&policydb);
1378 return -EINVAL;
1379 }
1380 if ( validate_classes(&policydb) )
1381 {
1382 LOAD_UNLOCK;
1383 printk(KERN_ERR
1384 "Flask: the definition of a class is incorrect\n");
1385 sidtab_destroy(&sidtab);
1386 policydb_destroy(&policydb);
1387 return -EINVAL;
1388 }
1389 policydb_loaded_version = policydb.policyvers;
1390 ss_initialized = 1;
1391 seqno = ++latest_granting;
1392 LOAD_UNLOCK;
1393 avc_ss_reset(seqno);
1394 return 0;
1395 }
1396
1397 #if 0
1398 sidtab_hash_eval(&sidtab, "sids");
1399 #endif
1400
1401 if ( policydb_read(&newpolicydb, fp) )
1402 {
1403 LOAD_UNLOCK;
1404 return -EINVAL;
1405 }
1406
1407 sidtab_init(&newsidtab);
1408
1409 /* Verify that the kernel defined classes are correct. */
1410 if ( validate_classes(&newpolicydb) )
1411 {
1412 printk(KERN_ERR
1413 "Flask: the definition of a class is incorrect\n");
1414 rc = -EINVAL;
1415 goto err;
1416 }
1417
1418 rc = security_preserve_bools(&newpolicydb);
1419 if ( rc )
1420 {
1421 printk(KERN_ERR "Flask: unable to preserve booleans\n");
1422 goto err;
1423 }
1424
1425 /* Clone the SID table. */
1426 sidtab_shutdown(&sidtab);
1427 if ( sidtab_map(&sidtab, clone_sid, &newsidtab) )
1428 {
1429 rc = -ENOMEM;
1430 goto err;
1431 }
1432
1433 /* Convert the internal representations of contexts
1434 in the new SID table and remove invalid SIDs. */
1435 args.oldp = &policydb;
1436 args.newp = &newpolicydb;
1437 sidtab_map_remove_on_error(&newsidtab, convert_context, &args);
1438
1439 /* Save the old policydb and SID table to free later. */
1440 memcpy(&oldpolicydb, &policydb, sizeof policydb);
1441 sidtab_set(&oldsidtab, &sidtab);
1442
1443 /* Install the new policydb and SID table. */
1444 POLICY_WRLOCK;
1445 memcpy(&policydb, &newpolicydb, sizeof policydb);
1446 sidtab_set(&sidtab, &newsidtab);
1447 seqno = ++latest_granting;
1448 policydb_loaded_version = policydb.policyvers;
1449 POLICY_WRUNLOCK;
1450 LOAD_UNLOCK;
1451
1452 /* Free the old policydb and SID table. */
1453 policydb_destroy(&oldpolicydb);
1454 sidtab_destroy(&oldsidtab);
1455
1456 avc_ss_reset(seqno);
1457
1458 return 0;
1459
1460 err:
1461 LOAD_UNLOCK;
1462 sidtab_destroy(&newsidtab);
1463 policydb_destroy(&newpolicydb);
1464 return rc;
1465
1466 }
1467
security_get_allow_unknown(void)1468 int security_get_allow_unknown(void)
1469 {
1470 return policydb.allow_unknown;
1471 }
1472
1473 /**
1474 * security_irq_sid - Obtain the SID for a physical irq.
1475 * @pirq: physical irq
1476 * @out_sid: security identifier
1477 */
security_irq_sid(int pirq,u32 * out_sid)1478 int security_irq_sid(int pirq, u32 *out_sid)
1479 {
1480 int rc = 0;
1481 struct ocontext *c;
1482
1483 POLICY_RDLOCK;
1484
1485 c = policydb.ocontexts[OCON_PIRQ];
1486
1487 while ( c )
1488 {
1489 if ( c->u.pirq == pirq )
1490 break;
1491 c = c->next;
1492 }
1493
1494 if ( c )
1495 {
1496 if ( !c->sid )
1497 {
1498 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1499 if ( rc )
1500 goto out;
1501 }
1502 *out_sid = c->sid;
1503 }
1504 else
1505 {
1506 *out_sid = SECINITSID_IRQ;
1507 }
1508
1509 out:
1510 POLICY_RDUNLOCK;
1511 return rc;
1512 }
1513
1514 /**
1515 * security_iomem_sid - Obtain the SID for a page of iomem.
1516 * @mfn: iomem mfn
1517 * @out_sid: security identifier
1518 */
security_iomem_sid(unsigned long mfn,u32 * out_sid)1519 int security_iomem_sid(unsigned long mfn, u32 *out_sid)
1520 {
1521 struct ocontext *c;
1522 int rc = 0;
1523
1524 POLICY_RDLOCK;
1525
1526 c = policydb.ocontexts[OCON_IOMEM];
1527 while ( c )
1528 {
1529 if ( c->u.iomem.low_iomem <= mfn && c->u.iomem.high_iomem >= mfn )
1530 break;
1531 c = c->next;
1532 }
1533
1534 if ( c )
1535 {
1536 if ( !c->sid )
1537 {
1538 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1539 if ( rc )
1540 goto out;
1541 }
1542 *out_sid = c->sid;
1543 }
1544 else
1545 {
1546 *out_sid = SECINITSID_IOMEM;
1547 }
1548
1549 out:
1550 POLICY_RDUNLOCK;
1551 return rc;
1552 }
1553
security_iterate_iomem_sids(unsigned long start,unsigned long end,security_iterate_fn fn,void * data)1554 int security_iterate_iomem_sids(unsigned long start, unsigned long end,
1555 security_iterate_fn fn, void *data)
1556 {
1557 struct ocontext *c;
1558 int rc = 0;
1559
1560 POLICY_RDLOCK;
1561
1562 c = policydb.ocontexts[OCON_IOMEM];
1563 while (c && c->u.iomem.high_iomem < start)
1564 c = c->next;
1565
1566 while (c && c->u.iomem.low_iomem <= end) {
1567 if (!c->sid)
1568 {
1569 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1570 if ( rc )
1571 goto out;
1572 }
1573 if (start < c->u.iomem.low_iomem) {
1574 /* found a gap */
1575 rc = fn(data, SECINITSID_IOMEM, start, c->u.iomem.low_iomem - 1);
1576 if (rc)
1577 goto out;
1578 start = c->u.iomem.low_iomem;
1579 }
1580 if (end <= c->u.iomem.high_iomem) {
1581 /* iteration ends in the middle of this range */
1582 rc = fn(data, c->sid, start, end);
1583 goto out;
1584 }
1585
1586 rc = fn(data, c->sid, start, c->u.iomem.high_iomem);
1587 if (rc)
1588 goto out;
1589 start = c->u.iomem.high_iomem + 1;
1590
1591 c = c->next;
1592 }
1593
1594 rc = fn(data, SECINITSID_IOMEM, start, end);
1595
1596 out:
1597 POLICY_RDUNLOCK;
1598 return rc;
1599 }
1600
1601 /**
1602 * security_ioport_sid - Obtain the SID for an ioport.
1603 * @ioport: ioport
1604 * @out_sid: security identifier
1605 */
security_ioport_sid(u32 ioport,u32 * out_sid)1606 int security_ioport_sid(u32 ioport, u32 *out_sid)
1607 {
1608 struct ocontext *c;
1609 int rc = 0;
1610
1611 POLICY_RDLOCK;
1612
1613 c = policydb.ocontexts[OCON_IOPORT];
1614 while ( c )
1615 {
1616 if ( c->u.ioport.low_ioport <= ioport &&
1617 c->u.ioport.high_ioport >= ioport )
1618 break;
1619 c = c->next;
1620 }
1621
1622 if ( c )
1623 {
1624 if ( !c->sid )
1625 {
1626 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1627 if ( rc )
1628 goto out;
1629 }
1630 *out_sid = c->sid;
1631 }
1632 else
1633 {
1634 *out_sid = SECINITSID_IOPORT;
1635 }
1636
1637 out:
1638 POLICY_RDUNLOCK;
1639 return rc;
1640 }
1641
security_iterate_ioport_sids(u32 start,u32 end,security_iterate_fn fn,void * data)1642 int security_iterate_ioport_sids(u32 start, u32 end,
1643 security_iterate_fn fn, void *data)
1644 {
1645 struct ocontext *c;
1646 int rc = 0;
1647
1648 POLICY_RDLOCK;
1649
1650 c = policydb.ocontexts[OCON_IOPORT];
1651 while (c && c->u.ioport.high_ioport < start)
1652 c = c->next;
1653
1654 while (c && c->u.ioport.low_ioport <= end) {
1655 if (!c->sid)
1656 {
1657 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1658 if ( rc )
1659 goto out;
1660 }
1661 if (start < c->u.ioport.low_ioport) {
1662 /* found a gap */
1663 rc = fn(data, SECINITSID_IOPORT, start, c->u.ioport.low_ioport - 1);
1664 if (rc)
1665 goto out;
1666 start = c->u.ioport.low_ioport;
1667 }
1668 if (end <= c->u.ioport.high_ioport) {
1669 /* iteration ends in the middle of this range */
1670 rc = fn(data, c->sid, start, end);
1671 goto out;
1672 }
1673
1674 rc = fn(data, c->sid, start, c->u.ioport.high_ioport);
1675 if (rc)
1676 goto out;
1677 start = c->u.ioport.high_ioport + 1;
1678
1679 c = c->next;
1680 }
1681
1682 rc = fn(data, SECINITSID_IOPORT, start, end);
1683
1684 out:
1685 POLICY_RDUNLOCK;
1686 return rc;
1687 }
1688
1689 /**
1690 * security_device_sid - Obtain the SID for a PCI device.
1691 * @ioport: device
1692 * @out_sid: security identifier
1693 */
security_device_sid(u32 device,u32 * out_sid)1694 int security_device_sid(u32 device, u32 *out_sid)
1695 {
1696 struct ocontext *c;
1697 int rc = 0;
1698
1699 POLICY_RDLOCK;
1700
1701 c = policydb.ocontexts[OCON_DEVICE];
1702 while ( c )
1703 {
1704 if ( c->u.device == device )
1705 break;
1706 c = c->next;
1707 }
1708
1709 if ( c )
1710 {
1711 if ( !c->sid )
1712 {
1713 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1714 if ( rc )
1715 goto out;
1716 }
1717 *out_sid = c->sid;
1718 }
1719 else
1720 {
1721 *out_sid = SECINITSID_DEVICE;
1722 }
1723
1724 out:
1725 POLICY_RDUNLOCK;
1726 return rc;
1727 }
1728
security_devicetree_sid(const char * path,u32 * out_sid)1729 int security_devicetree_sid(const char *path, u32 *out_sid)
1730 {
1731 struct ocontext *c;
1732 int rc = 0;
1733
1734 POLICY_RDLOCK;
1735
1736 c = policydb.ocontexts[OCON_DTREE];
1737 while ( c )
1738 {
1739 if ( strcmp(c->u.name, path) == 0 )
1740 break;
1741 c = c->next;
1742 }
1743
1744 if ( c )
1745 {
1746 if ( !c->sid )
1747 {
1748 rc = sidtab_context_to_sid(&sidtab, &c->context, &c->sid);
1749 if ( rc )
1750 goto out;
1751 }
1752 *out_sid = c->sid;
1753 }
1754 else
1755 {
1756 *out_sid = SECINITSID_DEVICE;
1757 }
1758
1759 out:
1760 POLICY_RDUNLOCK;
1761 return rc;
1762 }
1763
security_find_bool(const char * name)1764 int security_find_bool(const char *name)
1765 {
1766 int i, rv = -ENOENT;
1767 POLICY_RDLOCK;
1768 for ( i = 0; i < policydb.p_bools.nprim; i++ )
1769 {
1770 if (!strcmp(name, policydb.p_bool_val_to_name[i]))
1771 {
1772 rv = i;
1773 break;
1774 }
1775 }
1776
1777 POLICY_RDUNLOCK;
1778 return rv;
1779 }
1780
security_get_bools(int * len,char *** names,int ** values,size_t * maxstr)1781 int security_get_bools(int *len, char ***names, int **values, size_t *maxstr)
1782 {
1783 int i, rc = -ENOMEM;
1784
1785 POLICY_RDLOCK;
1786 if ( names )
1787 *names = NULL;
1788 *values = NULL;
1789 if ( maxstr )
1790 *maxstr = 0;
1791
1792 *len = policydb.p_bools.nprim;
1793 if ( !*len )
1794 {
1795 rc = 0;
1796 goto out;
1797 }
1798
1799 if ( names )
1800 {
1801 *names = xzalloc_array(char *, *len);
1802 if ( !*names )
1803 goto err;
1804 }
1805
1806 *values = xmalloc_array(int, *len);
1807 if ( !*values )
1808 goto err;
1809
1810 for ( i = 0; i < *len; i++ )
1811 {
1812 size_t name_len = strlen(policydb.p_bool_val_to_name[i]);
1813
1814 (*values)[i] = policydb.bool_val_to_struct[i]->state;
1815 if ( names ) {
1816 (*names)[i] = xmalloc_array(char, name_len + 1);
1817 if ( !(*names)[i] )
1818 goto err;
1819 strlcpy((*names)[i], policydb.p_bool_val_to_name[i], name_len + 1);
1820 }
1821 if ( maxstr && name_len > *maxstr )
1822 *maxstr = name_len;
1823 }
1824 rc = 0;
1825 out:
1826 POLICY_RDUNLOCK;
1827 return rc;
1828 err:
1829 if ( names && *names )
1830 {
1831 for ( i = 0; i < *len; i++ )
1832 xfree((*names)[i]);
1833 xfree(*names);
1834 }
1835 xfree(*values);
1836 goto out;
1837 }
1838
1839
security_set_bools(int len,int * values)1840 int security_set_bools(int len, int *values)
1841 {
1842 int i, rc = 0;
1843 int lenp, seqno = 0;
1844 struct cond_node *cur;
1845
1846 POLICY_WRLOCK;
1847
1848 lenp = policydb.p_bools.nprim;
1849 if ( len != lenp )
1850 {
1851 rc = -EFAULT;
1852 goto out;
1853 }
1854
1855 printk(KERN_INFO "Flask: committed booleans { ");
1856 for ( i = 0; i < len; i++ )
1857 {
1858 if ( values[i] )
1859 {
1860 policydb.bool_val_to_struct[i]->state = 1;
1861 }
1862 else
1863 {
1864 policydb.bool_val_to_struct[i]->state = 0;
1865 }
1866 if ( i != 0 )
1867 printk(", ");
1868 printk("%s:%d", policydb.p_bool_val_to_name[i],
1869 policydb.bool_val_to_struct[i]->state);
1870 }
1871 printk(" }\n");
1872
1873 for ( cur = policydb.cond_list; cur != NULL; cur = cur->next )
1874 {
1875 rc = evaluate_cond_node(&policydb, cur);
1876 if ( rc )
1877 goto out;
1878 }
1879
1880 seqno = ++latest_granting;
1881
1882 out:
1883 POLICY_WRUNLOCK;
1884 if ( !rc )
1885 {
1886 avc_ss_reset(seqno);
1887 }
1888 return rc;
1889 }
1890
security_get_bool_value(unsigned int b)1891 int security_get_bool_value(unsigned int b)
1892 {
1893 int rc = 0;
1894 unsigned int len;
1895
1896 POLICY_RDLOCK;
1897
1898 len = policydb.p_bools.nprim;
1899 if ( b >= len )
1900 {
1901 rc = -ENOENT;
1902 goto out;
1903 }
1904
1905 rc = policydb.bool_val_to_struct[b]->state;
1906 out:
1907 POLICY_RDUNLOCK;
1908 return rc;
1909 }
1910
security_get_bool_name(unsigned int b)1911 char *security_get_bool_name(unsigned int b)
1912 {
1913 unsigned int len;
1914 char *rv = NULL;
1915
1916 POLICY_RDLOCK;
1917
1918 len = policydb.p_bools.nprim;
1919 if ( b >= len )
1920 {
1921 goto out;
1922 }
1923
1924 len = strlen(policydb.p_bool_val_to_name[b]) + 1;
1925 rv = xmalloc_array(char, len);
1926 if ( !rv )
1927 goto out;
1928 memcpy(rv, policydb.p_bool_val_to_name[b], len);
1929 out:
1930 POLICY_RDUNLOCK;
1931 return rv;
1932 }
1933
security_preserve_bools(struct policydb * p)1934 static int security_preserve_bools(struct policydb *p)
1935 {
1936 int rc, nbools = 0, *bvalues = NULL, i;
1937 char **bnames = NULL;
1938 struct cond_bool_datum *booldatum;
1939 struct cond_node *cur;
1940
1941 rc = security_get_bools(&nbools, &bnames, &bvalues, NULL);
1942 if ( rc )
1943 return rc;
1944 for ( i = 0; i < nbools; i++ )
1945 {
1946 booldatum = hashtab_search(p->p_bools.table, bnames[i]);
1947 if ( booldatum )
1948 booldatum->state = bvalues[i];
1949 }
1950 for ( cur = p->cond_list; cur; cur = cur->next )
1951 {
1952 rc = evaluate_cond_node(p, cur);
1953 if ( rc )
1954 goto out;
1955 }
1956
1957 out:
1958 if ( bnames )
1959 {
1960 for ( i = 0; i < nbools; i++ )
1961 xfree(bnames[i]);
1962 }
1963 xfree(bnames);
1964 xfree(bvalues);
1965 return rc;
1966 }
1967
security_ocontext_add(u32 ocon,unsigned long low,unsigned long high,u32 sid)1968 int security_ocontext_add( u32 ocon, unsigned long low, unsigned long high
1969 ,u32 sid )
1970 {
1971 int ret = 0;
1972 struct ocontext *c;
1973 struct ocontext *prev;
1974 struct ocontext *add;
1975
1976 if ( (add = xzalloc(struct ocontext)) == NULL )
1977 return -ENOMEM;
1978 add->sid = sid;
1979
1980 POLICY_WRLOCK;
1981 switch( ocon )
1982 {
1983 case OCON_PIRQ:
1984 add->u.pirq = (u16)low;
1985 if ( high != low )
1986 {
1987 ret = -EINVAL;
1988 break;
1989 }
1990
1991 c = policydb.ocontexts[OCON_PIRQ];
1992 while ( c )
1993 {
1994 if ( c->u.pirq == add->u.pirq )
1995 {
1996 if ( c->sid == sid )
1997 break;
1998 printk("flask: Duplicate pirq %d\n", add->u.pirq);
1999 ret = -EEXIST;
2000 break;
2001 }
2002 c = c->next;
2003 }
2004
2005 if ( ret == 0 )
2006 {
2007 add->next = policydb.ocontexts[OCON_PIRQ];
2008 policydb.ocontexts[OCON_PIRQ] = add;
2009 }
2010 break;
2011
2012 case OCON_IOPORT:
2013 add->u.ioport.low_ioport = low;
2014 add->u.ioport.high_ioport = high;
2015
2016 prev = NULL;
2017 c = policydb.ocontexts[OCON_IOPORT];
2018
2019 while ( c && c->u.ioport.high_ioport < low ) {
2020 prev = c;
2021 c = c->next;
2022 }
2023
2024 if (c && c->u.ioport.low_ioport <= high)
2025 {
2026 if (c->u.ioport.low_ioport == low &&
2027 c->u.ioport.high_ioport == high && c->sid == sid)
2028 break;
2029
2030 printk("flask: IO Port overlap with entry %#x - %#x\n",
2031 c->u.ioport.low_ioport, c->u.ioport.high_ioport);
2032 ret = -EEXIST;
2033 break;
2034 }
2035
2036 if (prev) {
2037 add->next = prev->next;
2038 prev->next = add;
2039 } else {
2040 add->next = policydb.ocontexts[OCON_IOPORT];
2041 policydb.ocontexts[OCON_IOPORT] = add;
2042 }
2043 break;
2044
2045 case OCON_IOMEM:
2046 add->u.iomem.low_iomem = low;
2047 add->u.iomem.high_iomem = high;
2048
2049 prev = NULL;
2050 c = policydb.ocontexts[OCON_IOMEM];
2051
2052 while ( c && c->u.iomem.high_iomem < low ) {
2053 prev = c;
2054 c = c->next;
2055 }
2056
2057 if (c && c->u.iomem.low_iomem <= high)
2058 {
2059 if (c->u.iomem.low_iomem == low &&
2060 c->u.iomem.high_iomem == high && c->sid == sid)
2061 break;
2062
2063 printk("flask: IO Memory overlap with entry %#"PRIx64" - %#"PRIx64"\n",
2064 c->u.iomem.low_iomem, c->u.iomem.high_iomem);
2065 ret = -EEXIST;
2066 break;
2067 }
2068
2069 if (prev) {
2070 add->next = prev->next;
2071 prev->next = add;
2072 } else {
2073 add->next = policydb.ocontexts[OCON_IOMEM];
2074 policydb.ocontexts[OCON_IOMEM] = add;
2075 }
2076 break;
2077
2078 case OCON_DEVICE:
2079 add->u.device = low;
2080 if ( high != low )
2081 {
2082 ret = -EINVAL;
2083 break;
2084 }
2085
2086 c = policydb.ocontexts[OCON_DEVICE];
2087 while ( c )
2088 {
2089 if ( c->u.device == add->u.device )
2090 {
2091 if ( c->sid == sid )
2092 break;
2093
2094 printk("flask: Duplicate PCI Device %#x\n", add->u.device);
2095 ret = -EEXIST;
2096 break;
2097 }
2098 c = c->next;
2099 }
2100
2101 if ( ret == 0 )
2102 {
2103 add->next = policydb.ocontexts[OCON_DEVICE];
2104 policydb.ocontexts[OCON_DEVICE] = add;
2105 }
2106 break;
2107
2108 default:
2109 ret = -EINVAL;
2110 }
2111 POLICY_WRUNLOCK;
2112
2113 if ( ret != 0 )
2114 xfree(add);
2115 return ret;
2116 }
2117
security_ocontext_del(u32 ocon,unsigned long low,unsigned long high)2118 int security_ocontext_del( u32 ocon, unsigned long low, unsigned long high )
2119 {
2120 int ret = 0;
2121 struct ocontext *c, *before_c;
2122
2123 POLICY_WRLOCK;
2124 switch( ocon )
2125 {
2126 case OCON_PIRQ:
2127 for ( before_c = NULL, c = policydb.ocontexts[OCON_PIRQ];
2128 c; before_c = c, c = c->next )
2129 {
2130 if ( c->u.pirq == low )
2131 {
2132 if ( before_c == NULL )
2133 {
2134 policydb.ocontexts[OCON_PIRQ] = c->next;
2135 xfree(c);
2136 goto out;
2137 }
2138 else
2139 {
2140 before_c->next = c->next;
2141 xfree(c);
2142 goto out;
2143 }
2144 }
2145 }
2146
2147 printk("flask: ocontext not found: pirq %ld\n", low);
2148 ret = -ENOENT;
2149 break;
2150
2151 case OCON_IOPORT:
2152 for ( before_c = NULL, c = policydb.ocontexts[OCON_IOPORT];
2153 c; before_c = c, c = c->next )
2154 {
2155 if ( c->u.ioport.low_ioport == low &&
2156 c->u.ioport.high_ioport == high )
2157 {
2158 if ( before_c == NULL )
2159 {
2160 policydb.ocontexts[OCON_IOPORT] = c->next;
2161 xfree(c);
2162 goto out;
2163 }
2164 else
2165 {
2166 before_c->next = c->next;
2167 xfree(c);
2168 goto out;
2169 }
2170 }
2171 }
2172
2173 printk("flask: ocontext not found: ioport %#lx - %#lx\n", low, high);
2174 ret = -ENOENT;
2175 break;
2176
2177 case OCON_IOMEM:
2178 for ( before_c = NULL, c = policydb.ocontexts[OCON_IOMEM];
2179 c; before_c = c, c = c->next )
2180 {
2181 if ( c->u.iomem.low_iomem == low &&
2182 c->u.iomem.high_iomem == high )
2183 {
2184 if ( before_c == NULL )
2185 {
2186 policydb.ocontexts[OCON_IOMEM] = c->next;
2187 xfree(c);
2188 goto out;
2189 }
2190 else
2191 {
2192 before_c->next = c->next;
2193 xfree(c);
2194 goto out;
2195 }
2196 }
2197 }
2198
2199 printk("flask: ocontext not found: iomem %#lx - %#lx\n", low, high);
2200 ret = -ENOENT;
2201 break;
2202
2203 case OCON_DEVICE:
2204 for ( before_c = NULL, c = policydb.ocontexts[OCON_DEVICE];
2205 c; before_c = c, c = c->next )
2206 {
2207 if ( c->u.device == low )
2208 {
2209 if ( before_c == NULL )
2210 {
2211 policydb.ocontexts[OCON_DEVICE] = c->next;
2212 xfree(c);
2213 goto out;
2214 }
2215 else
2216 {
2217 before_c->next = c->next;
2218 xfree(c);
2219 goto out;
2220 }
2221 }
2222 }
2223
2224 printk("flask: ocontext not found: pcidevice %#lx\n", low);
2225 ret = -ENOENT;
2226 break;
2227
2228 default:
2229 ret = -EINVAL;
2230 }
2231
2232 out:
2233 POLICY_WRUNLOCK;
2234 return ret;
2235 }
2236
security_devicetree_setlabel(char * path,u32 sid)2237 int security_devicetree_setlabel(char *path, u32 sid)
2238 {
2239 int ret = 0;
2240 struct ocontext *c;
2241 struct ocontext **pcurr;
2242 struct ocontext *add = NULL;
2243
2244 if ( sid )
2245 {
2246 add = xzalloc(struct ocontext);
2247 if ( add == NULL )
2248 {
2249 xfree(path);
2250 return -ENOMEM;
2251 }
2252 add->sid = sid;
2253 add->u.name = path;
2254 }
2255 else
2256 {
2257 ret = -ENOENT;
2258 }
2259
2260 POLICY_WRLOCK;
2261
2262 pcurr = &policydb.ocontexts[OCON_DTREE];
2263 c = *pcurr;
2264 while ( c )
2265 {
2266 if ( strcmp(c->u.name, path) == 0 )
2267 {
2268 if ( sid )
2269 {
2270 ret = -EEXIST;
2271 break;
2272 }
2273 else
2274 {
2275 *pcurr = c->next;
2276 xfree(c->u.name);
2277 xfree(c);
2278 ret = 0;
2279 break;
2280 }
2281 }
2282 pcurr = &c->next;
2283 c = *pcurr;
2284 }
2285
2286 if ( add && ret == 0 )
2287 {
2288 add->next = policydb.ocontexts[OCON_DTREE];
2289 policydb.ocontexts[OCON_DTREE] = add;
2290 add = NULL;
2291 path = NULL;
2292 }
2293
2294 POLICY_WRUNLOCK;
2295
2296 xfree(add);
2297 xfree(path);
2298 return ret;
2299 }
2300