Merge git://oss.sgi.com:8090/oss/git/xfs-2.6
[pandora-kernel.git] / security / selinux / ss / services.c
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  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
16  * Copyright (C) 2003 - 2004 Tresys Technology, LLC
17  * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
18  *      This program is free software; you can redistribute it and/or modify
19  *      it under the terms of the GNU General Public License as published by
20  *      the Free Software Foundation, version 2.
21  */
22 #include <linux/kernel.h>
23 #include <linux/slab.h>
24 #include <linux/string.h>
25 #include <linux/spinlock.h>
26 #include <linux/errno.h>
27 #include <linux/in.h>
28 #include <linux/sched.h>
29 #include <linux/audit.h>
30 #include <linux/mutex.h>
31
32 #include "flask.h"
33 #include "avc.h"
34 #include "avc_ss.h"
35 #include "security.h"
36 #include "context.h"
37 #include "policydb.h"
38 #include "sidtab.h"
39 #include "services.h"
40 #include "conditional.h"
41 #include "mls.h"
42
43 extern void selnl_notify_policyload(u32 seqno);
44 unsigned int policydb_loaded_version;
45
46 static DEFINE_RWLOCK(policy_rwlock);
47 #define POLICY_RDLOCK read_lock(&policy_rwlock)
48 #define POLICY_WRLOCK write_lock_irq(&policy_rwlock)
49 #define POLICY_RDUNLOCK read_unlock(&policy_rwlock)
50 #define POLICY_WRUNLOCK write_unlock_irq(&policy_rwlock)
51
52 static DEFINE_MUTEX(load_mutex);
53 #define LOAD_LOCK mutex_lock(&load_mutex)
54 #define LOAD_UNLOCK mutex_unlock(&load_mutex)
55
56 static struct sidtab sidtab;
57 struct policydb policydb;
58 int ss_initialized = 0;
59
60 /*
61  * The largest sequence number that has been used when
62  * providing an access decision to the access vector cache.
63  * The sequence number only changes when a policy change
64  * occurs.
65  */
66 static u32 latest_granting = 0;
67
68 /* Forward declaration. */
69 static int context_struct_to_string(struct context *context, char **scontext,
70                                     u32 *scontext_len);
71
72 /*
73  * Return the boolean value of a constraint expression
74  * when it is applied to the specified source and target
75  * security contexts.
76  *
77  * xcontext is a special beast...  It is used by the validatetrans rules
78  * only.  For these rules, scontext is the context before the transition,
79  * tcontext is the context after the transition, and xcontext is the context
80  * of the process performing the transition.  All other callers of
81  * constraint_expr_eval should pass in NULL for xcontext.
82  */
83 static int constraint_expr_eval(struct context *scontext,
84                                 struct context *tcontext,
85                                 struct context *xcontext,
86                                 struct constraint_expr *cexpr)
87 {
88         u32 val1, val2;
89         struct context *c;
90         struct role_datum *r1, *r2;
91         struct mls_level *l1, *l2;
92         struct constraint_expr *e;
93         int s[CEXPR_MAXDEPTH];
94         int sp = -1;
95
96         for (e = cexpr; e; e = e->next) {
97                 switch (e->expr_type) {
98                 case CEXPR_NOT:
99                         BUG_ON(sp < 0);
100                         s[sp] = !s[sp];
101                         break;
102                 case CEXPR_AND:
103                         BUG_ON(sp < 1);
104                         sp--;
105                         s[sp] &= s[sp+1];
106                         break;
107                 case CEXPR_OR:
108                         BUG_ON(sp < 1);
109                         sp--;
110                         s[sp] |= s[sp+1];
111                         break;
112                 case CEXPR_ATTR:
113                         if (sp == (CEXPR_MAXDEPTH-1))
114                                 return 0;
115                         switch (e->attr) {
116                         case CEXPR_USER:
117                                 val1 = scontext->user;
118                                 val2 = tcontext->user;
119                                 break;
120                         case CEXPR_TYPE:
121                                 val1 = scontext->type;
122                                 val2 = tcontext->type;
123                                 break;
124                         case CEXPR_ROLE:
125                                 val1 = scontext->role;
126                                 val2 = tcontext->role;
127                                 r1 = policydb.role_val_to_struct[val1 - 1];
128                                 r2 = policydb.role_val_to_struct[val2 - 1];
129                                 switch (e->op) {
130                                 case CEXPR_DOM:
131                                         s[++sp] = ebitmap_get_bit(&r1->dominates,
132                                                                   val2 - 1);
133                                         continue;
134                                 case CEXPR_DOMBY:
135                                         s[++sp] = ebitmap_get_bit(&r2->dominates,
136                                                                   val1 - 1);
137                                         continue;
138                                 case CEXPR_INCOMP:
139                                         s[++sp] = ( !ebitmap_get_bit(&r1->dominates,
140                                                                      val2 - 1) &&
141                                                     !ebitmap_get_bit(&r2->dominates,
142                                                                      val1 - 1) );
143                                         continue;
144                                 default:
145                                         break;
146                                 }
147                                 break;
148                         case CEXPR_L1L2:
149                                 l1 = &(scontext->range.level[0]);
150                                 l2 = &(tcontext->range.level[0]);
151                                 goto mls_ops;
152                         case CEXPR_L1H2:
153                                 l1 = &(scontext->range.level[0]);
154                                 l2 = &(tcontext->range.level[1]);
155                                 goto mls_ops;
156                         case CEXPR_H1L2:
157                                 l1 = &(scontext->range.level[1]);
158                                 l2 = &(tcontext->range.level[0]);
159                                 goto mls_ops;
160                         case CEXPR_H1H2:
161                                 l1 = &(scontext->range.level[1]);
162                                 l2 = &(tcontext->range.level[1]);
163                                 goto mls_ops;
164                         case CEXPR_L1H1:
165                                 l1 = &(scontext->range.level[0]);
166                                 l2 = &(scontext->range.level[1]);
167                                 goto mls_ops;
168                         case CEXPR_L2H2:
169                                 l1 = &(tcontext->range.level[0]);
170                                 l2 = &(tcontext->range.level[1]);
171                                 goto mls_ops;
172 mls_ops:
173                         switch (e->op) {
174                         case CEXPR_EQ:
175                                 s[++sp] = mls_level_eq(l1, l2);
176                                 continue;
177                         case CEXPR_NEQ:
178                                 s[++sp] = !mls_level_eq(l1, l2);
179                                 continue;
180                         case CEXPR_DOM:
181                                 s[++sp] = mls_level_dom(l1, l2);
182                                 continue;
183                         case CEXPR_DOMBY:
184                                 s[++sp] = mls_level_dom(l2, l1);
185                                 continue;
186                         case CEXPR_INCOMP:
187                                 s[++sp] = mls_level_incomp(l2, l1);
188                                 continue;
189                         default:
190                                 BUG();
191                                 return 0;
192                         }
193                         break;
194                         default:
195                                 BUG();
196                                 return 0;
197                         }
198
199                         switch (e->op) {
200                         case CEXPR_EQ:
201                                 s[++sp] = (val1 == val2);
202                                 break;
203                         case CEXPR_NEQ:
204                                 s[++sp] = (val1 != val2);
205                                 break;
206                         default:
207                                 BUG();
208                                 return 0;
209                         }
210                         break;
211                 case CEXPR_NAMES:
212                         if (sp == (CEXPR_MAXDEPTH-1))
213                                 return 0;
214                         c = scontext;
215                         if (e->attr & CEXPR_TARGET)
216                                 c = tcontext;
217                         else if (e->attr & CEXPR_XTARGET) {
218                                 c = xcontext;
219                                 if (!c) {
220                                         BUG();
221                                         return 0;
222                                 }
223                         }
224                         if (e->attr & CEXPR_USER)
225                                 val1 = c->user;
226                         else if (e->attr & CEXPR_ROLE)
227                                 val1 = c->role;
228                         else if (e->attr & CEXPR_TYPE)
229                                 val1 = c->type;
230                         else {
231                                 BUG();
232                                 return 0;
233                         }
234
235                         switch (e->op) {
236                         case CEXPR_EQ:
237                                 s[++sp] = ebitmap_get_bit(&e->names, val1 - 1);
238                                 break;
239                         case CEXPR_NEQ:
240                                 s[++sp] = !ebitmap_get_bit(&e->names, val1 - 1);
241                                 break;
242                         default:
243                                 BUG();
244                                 return 0;
245                         }
246                         break;
247                 default:
248                         BUG();
249                         return 0;
250                 }
251         }
252
253         BUG_ON(sp != 0);
254         return s[0];
255 }
256
257 /*
258  * Compute access vectors based on a context structure pair for
259  * the permissions in a particular class.
260  */
261 static int context_struct_compute_av(struct context *scontext,
262                                      struct context *tcontext,
263                                      u16 tclass,
264                                      u32 requested,
265                                      struct av_decision *avd)
266 {
267         struct constraint_node *constraint;
268         struct role_allow *ra;
269         struct avtab_key avkey;
270         struct avtab_node *node;
271         struct class_datum *tclass_datum;
272         struct ebitmap *sattr, *tattr;
273         struct ebitmap_node *snode, *tnode;
274         unsigned int i, j;
275
276         /*
277          * Remap extended Netlink classes for old policy versions.
278          * Do this here rather than socket_type_to_security_class()
279          * in case a newer policy version is loaded, allowing sockets
280          * to remain in the correct class.
281          */
282         if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
283                 if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
284                     tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
285                         tclass = SECCLASS_NETLINK_SOCKET;
286
287         if (!tclass || tclass > policydb.p_classes.nprim) {
288                 printk(KERN_ERR "security_compute_av:  unrecognized class %d\n",
289                        tclass);
290                 return -EINVAL;
291         }
292         tclass_datum = policydb.class_val_to_struct[tclass - 1];
293
294         /*
295          * Initialize the access vectors to the default values.
296          */
297         avd->allowed = 0;
298         avd->decided = 0xffffffff;
299         avd->auditallow = 0;
300         avd->auditdeny = 0xffffffff;
301         avd->seqno = latest_granting;
302
303         /*
304          * If a specific type enforcement rule was defined for
305          * this permission check, then use it.
306          */
307         avkey.target_class = tclass;
308         avkey.specified = AVTAB_AV;
309         sattr = &policydb.type_attr_map[scontext->type - 1];
310         tattr = &policydb.type_attr_map[tcontext->type - 1];
311         ebitmap_for_each_bit(sattr, snode, i) {
312                 if (!ebitmap_node_get_bit(snode, i))
313                         continue;
314                 ebitmap_for_each_bit(tattr, tnode, j) {
315                         if (!ebitmap_node_get_bit(tnode, j))
316                                 continue;
317                         avkey.source_type = i + 1;
318                         avkey.target_type = j + 1;
319                         for (node = avtab_search_node(&policydb.te_avtab, &avkey);
320                              node != NULL;
321                              node = avtab_search_node_next(node, avkey.specified)) {
322                                 if (node->key.specified == AVTAB_ALLOWED)
323                                         avd->allowed |= node->datum.data;
324                                 else if (node->key.specified == AVTAB_AUDITALLOW)
325                                         avd->auditallow |= node->datum.data;
326                                 else if (node->key.specified == AVTAB_AUDITDENY)
327                                         avd->auditdeny &= node->datum.data;
328                         }
329
330                         /* Check conditional av table for additional permissions */
331                         cond_compute_av(&policydb.te_cond_avtab, &avkey, avd);
332
333                 }
334         }
335
336         /*
337          * Remove any permissions prohibited by a constraint (this includes
338          * the MLS policy).
339          */
340         constraint = tclass_datum->constraints;
341         while (constraint) {
342                 if ((constraint->permissions & (avd->allowed)) &&
343                     !constraint_expr_eval(scontext, tcontext, NULL,
344                                           constraint->expr)) {
345                         avd->allowed = (avd->allowed) & ~(constraint->permissions);
346                 }
347                 constraint = constraint->next;
348         }
349
350         /*
351          * If checking process transition permission and the
352          * role is changing, then check the (current_role, new_role)
353          * pair.
354          */
355         if (tclass == SECCLASS_PROCESS &&
356             (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) &&
357             scontext->role != tcontext->role) {
358                 for (ra = policydb.role_allow; ra; ra = ra->next) {
359                         if (scontext->role == ra->role &&
360                             tcontext->role == ra->new_role)
361                                 break;
362                 }
363                 if (!ra)
364                         avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION |
365                                                         PROCESS__DYNTRANSITION);
366         }
367
368         return 0;
369 }
370
371 static int security_validtrans_handle_fail(struct context *ocontext,
372                                            struct context *ncontext,
373                                            struct context *tcontext,
374                                            u16 tclass)
375 {
376         char *o = NULL, *n = NULL, *t = NULL;
377         u32 olen, nlen, tlen;
378
379         if (context_struct_to_string(ocontext, &o, &olen) < 0)
380                 goto out;
381         if (context_struct_to_string(ncontext, &n, &nlen) < 0)
382                 goto out;
383         if (context_struct_to_string(tcontext, &t, &tlen) < 0)
384                 goto out;
385         audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
386                   "security_validate_transition:  denied for"
387                   " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
388                   o, n, t, policydb.p_class_val_to_name[tclass-1]);
389 out:
390         kfree(o);
391         kfree(n);
392         kfree(t);
393
394         if (!selinux_enforcing)
395                 return 0;
396         return -EPERM;
397 }
398
399 int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
400                                  u16 tclass)
401 {
402         struct context *ocontext;
403         struct context *ncontext;
404         struct context *tcontext;
405         struct class_datum *tclass_datum;
406         struct constraint_node *constraint;
407         int rc = 0;
408
409         if (!ss_initialized)
410                 return 0;
411
412         POLICY_RDLOCK;
413
414         /*
415          * Remap extended Netlink classes for old policy versions.
416          * Do this here rather than socket_type_to_security_class()
417          * in case a newer policy version is loaded, allowing sockets
418          * to remain in the correct class.
419          */
420         if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
421                 if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
422                     tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
423                         tclass = SECCLASS_NETLINK_SOCKET;
424
425         if (!tclass || tclass > policydb.p_classes.nprim) {
426                 printk(KERN_ERR "security_validate_transition:  "
427                        "unrecognized class %d\n", tclass);
428                 rc = -EINVAL;
429                 goto out;
430         }
431         tclass_datum = policydb.class_val_to_struct[tclass - 1];
432
433         ocontext = sidtab_search(&sidtab, oldsid);
434         if (!ocontext) {
435                 printk(KERN_ERR "security_validate_transition: "
436                        " unrecognized SID %d\n", oldsid);
437                 rc = -EINVAL;
438                 goto out;
439         }
440
441         ncontext = sidtab_search(&sidtab, newsid);
442         if (!ncontext) {
443                 printk(KERN_ERR "security_validate_transition: "
444                        " unrecognized SID %d\n", newsid);
445                 rc = -EINVAL;
446                 goto out;
447         }
448
449         tcontext = sidtab_search(&sidtab, tasksid);
450         if (!tcontext) {
451                 printk(KERN_ERR "security_validate_transition: "
452                        " unrecognized SID %d\n", tasksid);
453                 rc = -EINVAL;
454                 goto out;
455         }
456
457         constraint = tclass_datum->validatetrans;
458         while (constraint) {
459                 if (!constraint_expr_eval(ocontext, ncontext, tcontext,
460                                           constraint->expr)) {
461                         rc = security_validtrans_handle_fail(ocontext, ncontext,
462                                                              tcontext, tclass);
463                         goto out;
464                 }
465                 constraint = constraint->next;
466         }
467
468 out:
469         POLICY_RDUNLOCK;
470         return rc;
471 }
472
473 /**
474  * security_compute_av - Compute access vector decisions.
475  * @ssid: source security identifier
476  * @tsid: target security identifier
477  * @tclass: target security class
478  * @requested: requested permissions
479  * @avd: access vector decisions
480  *
481  * Compute a set of access vector decisions based on the
482  * SID pair (@ssid, @tsid) for the permissions in @tclass.
483  * Return -%EINVAL if any of the parameters are invalid or %0
484  * if the access vector decisions were computed successfully.
485  */
486 int security_compute_av(u32 ssid,
487                         u32 tsid,
488                         u16 tclass,
489                         u32 requested,
490                         struct av_decision *avd)
491 {
492         struct context *scontext = NULL, *tcontext = NULL;
493         int rc = 0;
494
495         if (!ss_initialized) {
496                 avd->allowed = 0xffffffff;
497                 avd->decided = 0xffffffff;
498                 avd->auditallow = 0;
499                 avd->auditdeny = 0xffffffff;
500                 avd->seqno = latest_granting;
501                 return 0;
502         }
503
504         POLICY_RDLOCK;
505
506         scontext = sidtab_search(&sidtab, ssid);
507         if (!scontext) {
508                 printk(KERN_ERR "security_compute_av:  unrecognized SID %d\n",
509                        ssid);
510                 rc = -EINVAL;
511                 goto out;
512         }
513         tcontext = sidtab_search(&sidtab, tsid);
514         if (!tcontext) {
515                 printk(KERN_ERR "security_compute_av:  unrecognized SID %d\n",
516                        tsid);
517                 rc = -EINVAL;
518                 goto out;
519         }
520
521         rc = context_struct_compute_av(scontext, tcontext, tclass,
522                                        requested, avd);
523 out:
524         POLICY_RDUNLOCK;
525         return rc;
526 }
527
528 /*
529  * Write the security context string representation of
530  * the context structure `context' into a dynamically
531  * allocated string of the correct size.  Set `*scontext'
532  * to point to this string and set `*scontext_len' to
533  * the length of the string.
534  */
535 static int context_struct_to_string(struct context *context, char **scontext, u32 *scontext_len)
536 {
537         char *scontextp;
538
539         *scontext = NULL;
540         *scontext_len = 0;
541
542         /* Compute the size of the context. */
543         *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1;
544         *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1;
545         *scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1;
546         *scontext_len += mls_compute_context_len(context);
547
548         /* Allocate space for the context; caller must free this space. */
549         scontextp = kmalloc(*scontext_len, GFP_ATOMIC);
550         if (!scontextp) {
551                 return -ENOMEM;
552         }
553         *scontext = scontextp;
554
555         /*
556          * Copy the user name, role name and type name into the context.
557          */
558         sprintf(scontextp, "%s:%s:%s",
559                 policydb.p_user_val_to_name[context->user - 1],
560                 policydb.p_role_val_to_name[context->role - 1],
561                 policydb.p_type_val_to_name[context->type - 1]);
562         scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) +
563                      1 + strlen(policydb.p_role_val_to_name[context->role - 1]) +
564                      1 + strlen(policydb.p_type_val_to_name[context->type - 1]);
565
566         mls_sid_to_context(context, &scontextp);
567
568         *scontextp = 0;
569
570         return 0;
571 }
572
573 #include "initial_sid_to_string.h"
574
575 /**
576  * security_sid_to_context - Obtain a context for a given SID.
577  * @sid: security identifier, SID
578  * @scontext: security context
579  * @scontext_len: length in bytes
580  *
581  * Write the string representation of the context associated with @sid
582  * into a dynamically allocated string of the correct size.  Set @scontext
583  * to point to this string and set @scontext_len to the length of the string.
584  */
585 int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
586 {
587         struct context *context;
588         int rc = 0;
589
590         if (!ss_initialized) {
591                 if (sid <= SECINITSID_NUM) {
592                         char *scontextp;
593
594                         *scontext_len = strlen(initial_sid_to_string[sid]) + 1;
595                         scontextp = kmalloc(*scontext_len,GFP_ATOMIC);
596                         strcpy(scontextp, initial_sid_to_string[sid]);
597                         *scontext = scontextp;
598                         goto out;
599                 }
600                 printk(KERN_ERR "security_sid_to_context:  called before initial "
601                        "load_policy on unknown SID %d\n", sid);
602                 rc = -EINVAL;
603                 goto out;
604         }
605         POLICY_RDLOCK;
606         context = sidtab_search(&sidtab, sid);
607         if (!context) {
608                 printk(KERN_ERR "security_sid_to_context:  unrecognized SID "
609                        "%d\n", sid);
610                 rc = -EINVAL;
611                 goto out_unlock;
612         }
613         rc = context_struct_to_string(context, scontext, scontext_len);
614 out_unlock:
615         POLICY_RDUNLOCK;
616 out:
617         return rc;
618
619 }
620
621 static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid)
622 {
623         char *scontext2;
624         struct context context;
625         struct role_datum *role;
626         struct type_datum *typdatum;
627         struct user_datum *usrdatum;
628         char *scontextp, *p, oldc;
629         int rc = 0;
630
631         if (!ss_initialized) {
632                 int i;
633
634                 for (i = 1; i < SECINITSID_NUM; i++) {
635                         if (!strcmp(initial_sid_to_string[i], scontext)) {
636                                 *sid = i;
637                                 goto out;
638                         }
639                 }
640                 *sid = SECINITSID_KERNEL;
641                 goto out;
642         }
643         *sid = SECSID_NULL;
644
645         /* Copy the string so that we can modify the copy as we parse it.
646            The string should already by null terminated, but we append a
647            null suffix to the copy to avoid problems with the existing
648            attr package, which doesn't view the null terminator as part
649            of the attribute value. */
650         scontext2 = kmalloc(scontext_len+1,GFP_KERNEL);
651         if (!scontext2) {
652                 rc = -ENOMEM;
653                 goto out;
654         }
655         memcpy(scontext2, scontext, scontext_len);
656         scontext2[scontext_len] = 0;
657
658         context_init(&context);
659         *sid = SECSID_NULL;
660
661         POLICY_RDLOCK;
662
663         /* Parse the security context. */
664
665         rc = -EINVAL;
666         scontextp = (char *) scontext2;
667
668         /* Extract the user. */
669         p = scontextp;
670         while (*p && *p != ':')
671                 p++;
672
673         if (*p == 0)
674                 goto out_unlock;
675
676         *p++ = 0;
677
678         usrdatum = hashtab_search(policydb.p_users.table, scontextp);
679         if (!usrdatum)
680                 goto out_unlock;
681
682         context.user = usrdatum->value;
683
684         /* Extract role. */
685         scontextp = p;
686         while (*p && *p != ':')
687                 p++;
688
689         if (*p == 0)
690                 goto out_unlock;
691
692         *p++ = 0;
693
694         role = hashtab_search(policydb.p_roles.table, scontextp);
695         if (!role)
696                 goto out_unlock;
697         context.role = role->value;
698
699         /* Extract type. */
700         scontextp = p;
701         while (*p && *p != ':')
702                 p++;
703         oldc = *p;
704         *p++ = 0;
705
706         typdatum = hashtab_search(policydb.p_types.table, scontextp);
707         if (!typdatum)
708                 goto out_unlock;
709
710         context.type = typdatum->value;
711
712         rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid);
713         if (rc)
714                 goto out_unlock;
715
716         if ((p - scontext2) < scontext_len) {
717                 rc = -EINVAL;
718                 goto out_unlock;
719         }
720
721         /* Check the validity of the new context. */
722         if (!policydb_context_isvalid(&policydb, &context)) {
723                 rc = -EINVAL;
724                 goto out_unlock;
725         }
726         /* Obtain the new sid. */
727         rc = sidtab_context_to_sid(&sidtab, &context, sid);
728 out_unlock:
729         POLICY_RDUNLOCK;
730         context_destroy(&context);
731         kfree(scontext2);
732 out:
733         return rc;
734 }
735
736 /**
737  * security_context_to_sid - Obtain a SID for a given security context.
738  * @scontext: security context
739  * @scontext_len: length in bytes
740  * @sid: security identifier, SID
741  *
742  * Obtains a SID associated with the security context that
743  * has the string representation specified by @scontext.
744  * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
745  * memory is available, or 0 on success.
746  */
747 int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
748 {
749         return security_context_to_sid_core(scontext, scontext_len,
750                                             sid, SECSID_NULL);
751 }
752
753 /**
754  * security_context_to_sid_default - Obtain a SID for a given security context,
755  * falling back to specified default if needed.
756  *
757  * @scontext: security context
758  * @scontext_len: length in bytes
759  * @sid: security identifier, SID
760  * @def_sid: default SID to assign on errror
761  *
762  * Obtains a SID associated with the security context that
763  * has the string representation specified by @scontext.
764  * The default SID is passed to the MLS layer to be used to allow
765  * kernel labeling of the MLS field if the MLS field is not present
766  * (for upgrading to MLS without full relabel).
767  * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
768  * memory is available, or 0 on success.
769  */
770 int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid)
771 {
772         return security_context_to_sid_core(scontext, scontext_len,
773                                             sid, def_sid);
774 }
775
776 static int compute_sid_handle_invalid_context(
777         struct context *scontext,
778         struct context *tcontext,
779         u16 tclass,
780         struct context *newcontext)
781 {
782         char *s = NULL, *t = NULL, *n = NULL;
783         u32 slen, tlen, nlen;
784
785         if (context_struct_to_string(scontext, &s, &slen) < 0)
786                 goto out;
787         if (context_struct_to_string(tcontext, &t, &tlen) < 0)
788                 goto out;
789         if (context_struct_to_string(newcontext, &n, &nlen) < 0)
790                 goto out;
791         audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
792                   "security_compute_sid:  invalid context %s"
793                   " for scontext=%s"
794                   " tcontext=%s"
795                   " tclass=%s",
796                   n, s, t, policydb.p_class_val_to_name[tclass-1]);
797 out:
798         kfree(s);
799         kfree(t);
800         kfree(n);
801         if (!selinux_enforcing)
802                 return 0;
803         return -EACCES;
804 }
805
806 static int security_compute_sid(u32 ssid,
807                                 u32 tsid,
808                                 u16 tclass,
809                                 u32 specified,
810                                 u32 *out_sid)
811 {
812         struct context *scontext = NULL, *tcontext = NULL, newcontext;
813         struct role_trans *roletr = NULL;
814         struct avtab_key avkey;
815         struct avtab_datum *avdatum;
816         struct avtab_node *node;
817         int rc = 0;
818
819         if (!ss_initialized) {
820                 switch (tclass) {
821                 case SECCLASS_PROCESS:
822                         *out_sid = ssid;
823                         break;
824                 default:
825                         *out_sid = tsid;
826                         break;
827                 }
828                 goto out;
829         }
830
831         POLICY_RDLOCK;
832
833         scontext = sidtab_search(&sidtab, ssid);
834         if (!scontext) {
835                 printk(KERN_ERR "security_compute_sid:  unrecognized SID %d\n",
836                        ssid);
837                 rc = -EINVAL;
838                 goto out_unlock;
839         }
840         tcontext = sidtab_search(&sidtab, tsid);
841         if (!tcontext) {
842                 printk(KERN_ERR "security_compute_sid:  unrecognized SID %d\n",
843                        tsid);
844                 rc = -EINVAL;
845                 goto out_unlock;
846         }
847
848         context_init(&newcontext);
849
850         /* Set the user identity. */
851         switch (specified) {
852         case AVTAB_TRANSITION:
853         case AVTAB_CHANGE:
854                 /* Use the process user identity. */
855                 newcontext.user = scontext->user;
856                 break;
857         case AVTAB_MEMBER:
858                 /* Use the related object owner. */
859                 newcontext.user = tcontext->user;
860                 break;
861         }
862
863         /* Set the role and type to default values. */
864         switch (tclass) {
865         case SECCLASS_PROCESS:
866                 /* Use the current role and type of process. */
867                 newcontext.role = scontext->role;
868                 newcontext.type = scontext->type;
869                 break;
870         default:
871                 /* Use the well-defined object role. */
872                 newcontext.role = OBJECT_R_VAL;
873                 /* Use the type of the related object. */
874                 newcontext.type = tcontext->type;
875         }
876
877         /* Look for a type transition/member/change rule. */
878         avkey.source_type = scontext->type;
879         avkey.target_type = tcontext->type;
880         avkey.target_class = tclass;
881         avkey.specified = specified;
882         avdatum = avtab_search(&policydb.te_avtab, &avkey);
883
884         /* If no permanent rule, also check for enabled conditional rules */
885         if(!avdatum) {
886                 node = avtab_search_node(&policydb.te_cond_avtab, &avkey);
887                 for (; node != NULL; node = avtab_search_node_next(node, specified)) {
888                         if (node->key.specified & AVTAB_ENABLED) {
889                                 avdatum = &node->datum;
890                                 break;
891                         }
892                 }
893         }
894
895         if (avdatum) {
896                 /* Use the type from the type transition/member/change rule. */
897                 newcontext.type = avdatum->data;
898         }
899
900         /* Check for class-specific changes. */
901         switch (tclass) {
902         case SECCLASS_PROCESS:
903                 if (specified & AVTAB_TRANSITION) {
904                         /* Look for a role transition rule. */
905                         for (roletr = policydb.role_tr; roletr;
906                              roletr = roletr->next) {
907                                 if (roletr->role == scontext->role &&
908                                     roletr->type == tcontext->type) {
909                                         /* Use the role transition rule. */
910                                         newcontext.role = roletr->new_role;
911                                         break;
912                                 }
913                         }
914                 }
915                 break;
916         default:
917                 break;
918         }
919
920         /* Set the MLS attributes.
921            This is done last because it may allocate memory. */
922         rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext);
923         if (rc)
924                 goto out_unlock;
925
926         /* Check the validity of the context. */
927         if (!policydb_context_isvalid(&policydb, &newcontext)) {
928                 rc = compute_sid_handle_invalid_context(scontext,
929                                                         tcontext,
930                                                         tclass,
931                                                         &newcontext);
932                 if (rc)
933                         goto out_unlock;
934         }
935         /* Obtain the sid for the context. */
936         rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid);
937 out_unlock:
938         POLICY_RDUNLOCK;
939         context_destroy(&newcontext);
940 out:
941         return rc;
942 }
943
944 /**
945  * security_transition_sid - Compute the SID for a new subject/object.
946  * @ssid: source security identifier
947  * @tsid: target security identifier
948  * @tclass: target security class
949  * @out_sid: security identifier for new subject/object
950  *
951  * Compute a SID to use for labeling a new subject or object in the
952  * class @tclass based on a SID pair (@ssid, @tsid).
953  * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
954  * if insufficient memory is available, or %0 if the new SID was
955  * computed successfully.
956  */
957 int security_transition_sid(u32 ssid,
958                             u32 tsid,
959                             u16 tclass,
960                             u32 *out_sid)
961 {
962         return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid);
963 }
964
965 /**
966  * security_member_sid - Compute the SID for member selection.
967  * @ssid: source security identifier
968  * @tsid: target security identifier
969  * @tclass: target security class
970  * @out_sid: security identifier for selected member
971  *
972  * Compute a SID to use when selecting a member of a polyinstantiated
973  * object of class @tclass based on a SID pair (@ssid, @tsid).
974  * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
975  * if insufficient memory is available, or %0 if the SID was
976  * computed successfully.
977  */
978 int security_member_sid(u32 ssid,
979                         u32 tsid,
980                         u16 tclass,
981                         u32 *out_sid)
982 {
983         return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid);
984 }
985
986 /**
987  * security_change_sid - Compute the SID for object relabeling.
988  * @ssid: source security identifier
989  * @tsid: target security identifier
990  * @tclass: target security class
991  * @out_sid: security identifier for selected member
992  *
993  * Compute a SID to use for relabeling an object of class @tclass
994  * based on a SID pair (@ssid, @tsid).
995  * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
996  * if insufficient memory is available, or %0 if the SID was
997  * computed successfully.
998  */
999 int security_change_sid(u32 ssid,
1000                         u32 tsid,
1001                         u16 tclass,
1002                         u32 *out_sid)
1003 {
1004         return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid);
1005 }
1006
1007 /*
1008  * Verify that each permission that is defined under the
1009  * existing policy is still defined with the same value
1010  * in the new policy.
1011  */
1012 static int validate_perm(void *key, void *datum, void *p)
1013 {
1014         struct hashtab *h;
1015         struct perm_datum *perdatum, *perdatum2;
1016         int rc = 0;
1017
1018
1019         h = p;
1020         perdatum = datum;
1021
1022         perdatum2 = hashtab_search(h, key);
1023         if (!perdatum2) {
1024                 printk(KERN_ERR "security:  permission %s disappeared",
1025                        (char *)key);
1026                 rc = -ENOENT;
1027                 goto out;
1028         }
1029         if (perdatum->value != perdatum2->value) {
1030                 printk(KERN_ERR "security:  the value of permission %s changed",
1031                        (char *)key);
1032                 rc = -EINVAL;
1033         }
1034 out:
1035         return rc;
1036 }
1037
1038 /*
1039  * Verify that each class that is defined under the
1040  * existing policy is still defined with the same
1041  * attributes in the new policy.
1042  */
1043 static int validate_class(void *key, void *datum, void *p)
1044 {
1045         struct policydb *newp;
1046         struct class_datum *cladatum, *cladatum2;
1047         int rc;
1048
1049         newp = p;
1050         cladatum = datum;
1051
1052         cladatum2 = hashtab_search(newp->p_classes.table, key);
1053         if (!cladatum2) {
1054                 printk(KERN_ERR "security:  class %s disappeared\n",
1055                        (char *)key);
1056                 rc = -ENOENT;
1057                 goto out;
1058         }
1059         if (cladatum->value != cladatum2->value) {
1060                 printk(KERN_ERR "security:  the value of class %s changed\n",
1061                        (char *)key);
1062                 rc = -EINVAL;
1063                 goto out;
1064         }
1065         if ((cladatum->comdatum && !cladatum2->comdatum) ||
1066             (!cladatum->comdatum && cladatum2->comdatum)) {
1067                 printk(KERN_ERR "security:  the inherits clause for the access "
1068                        "vector definition for class %s changed\n", (char *)key);
1069                 rc = -EINVAL;
1070                 goto out;
1071         }
1072         if (cladatum->comdatum) {
1073                 rc = hashtab_map(cladatum->comdatum->permissions.table, validate_perm,
1074                                  cladatum2->comdatum->permissions.table);
1075                 if (rc) {
1076                         printk(" in the access vector definition for class "
1077                                "%s\n", (char *)key);
1078                         goto out;
1079                 }
1080         }
1081         rc = hashtab_map(cladatum->permissions.table, validate_perm,
1082                          cladatum2->permissions.table);
1083         if (rc)
1084                 printk(" in access vector definition for class %s\n",
1085                        (char *)key);
1086 out:
1087         return rc;
1088 }
1089
1090 /* Clone the SID into the new SID table. */
1091 static int clone_sid(u32 sid,
1092                      struct context *context,
1093                      void *arg)
1094 {
1095         struct sidtab *s = arg;
1096
1097         return sidtab_insert(s, sid, context);
1098 }
1099
1100 static inline int convert_context_handle_invalid_context(struct context *context)
1101 {
1102         int rc = 0;
1103
1104         if (selinux_enforcing) {
1105                 rc = -EINVAL;
1106         } else {
1107                 char *s;
1108                 u32 len;
1109
1110                 context_struct_to_string(context, &s, &len);
1111                 printk(KERN_ERR "security:  context %s is invalid\n", s);
1112                 kfree(s);
1113         }
1114         return rc;
1115 }
1116
1117 struct convert_context_args {
1118         struct policydb *oldp;
1119         struct policydb *newp;
1120 };
1121
1122 /*
1123  * Convert the values in the security context
1124  * structure `c' from the values specified
1125  * in the policy `p->oldp' to the values specified
1126  * in the policy `p->newp'.  Verify that the
1127  * context is valid under the new policy.
1128  */
1129 static int convert_context(u32 key,
1130                            struct context *c,
1131                            void *p)
1132 {
1133         struct convert_context_args *args;
1134         struct context oldc;
1135         struct role_datum *role;
1136         struct type_datum *typdatum;
1137         struct user_datum *usrdatum;
1138         char *s;
1139         u32 len;
1140         int rc;
1141
1142         args = p;
1143
1144         rc = context_cpy(&oldc, c);
1145         if (rc)
1146                 goto out;
1147
1148         rc = -EINVAL;
1149
1150         /* Convert the user. */
1151         usrdatum = hashtab_search(args->newp->p_users.table,
1152                                   args->oldp->p_user_val_to_name[c->user - 1]);
1153         if (!usrdatum) {
1154                 goto bad;
1155         }
1156         c->user = usrdatum->value;
1157
1158         /* Convert the role. */
1159         role = hashtab_search(args->newp->p_roles.table,
1160                               args->oldp->p_role_val_to_name[c->role - 1]);
1161         if (!role) {
1162                 goto bad;
1163         }
1164         c->role = role->value;
1165
1166         /* Convert the type. */
1167         typdatum = hashtab_search(args->newp->p_types.table,
1168                                   args->oldp->p_type_val_to_name[c->type - 1]);
1169         if (!typdatum) {
1170                 goto bad;
1171         }
1172         c->type = typdatum->value;
1173
1174         rc = mls_convert_context(args->oldp, args->newp, c);
1175         if (rc)
1176                 goto bad;
1177
1178         /* Check the validity of the new context. */
1179         if (!policydb_context_isvalid(args->newp, c)) {
1180                 rc = convert_context_handle_invalid_context(&oldc);
1181                 if (rc)
1182                         goto bad;
1183         }
1184
1185         context_destroy(&oldc);
1186 out:
1187         return rc;
1188 bad:
1189         context_struct_to_string(&oldc, &s, &len);
1190         context_destroy(&oldc);
1191         printk(KERN_ERR "security:  invalidating context %s\n", s);
1192         kfree(s);
1193         goto out;
1194 }
1195
1196 extern void selinux_complete_init(void);
1197
1198 /**
1199  * security_load_policy - Load a security policy configuration.
1200  * @data: binary policy data
1201  * @len: length of data in bytes
1202  *
1203  * Load a new set of security policy configuration data,
1204  * validate it and convert the SID table as necessary.
1205  * This function will flush the access vector cache after
1206  * loading the new policy.
1207  */
1208 int security_load_policy(void *data, size_t len)
1209 {
1210         struct policydb oldpolicydb, newpolicydb;
1211         struct sidtab oldsidtab, newsidtab;
1212         struct convert_context_args args;
1213         u32 seqno;
1214         int rc = 0;
1215         struct policy_file file = { data, len }, *fp = &file;
1216
1217         LOAD_LOCK;
1218
1219         if (!ss_initialized) {
1220                 avtab_cache_init();
1221                 if (policydb_read(&policydb, fp)) {
1222                         LOAD_UNLOCK;
1223                         avtab_cache_destroy();
1224                         return -EINVAL;
1225                 }
1226                 if (policydb_load_isids(&policydb, &sidtab)) {
1227                         LOAD_UNLOCK;
1228                         policydb_destroy(&policydb);
1229                         avtab_cache_destroy();
1230                         return -EINVAL;
1231                 }
1232                 policydb_loaded_version = policydb.policyvers;
1233                 ss_initialized = 1;
1234                 seqno = ++latest_granting;
1235                 LOAD_UNLOCK;
1236                 selinux_complete_init();
1237                 avc_ss_reset(seqno);
1238                 selnl_notify_policyload(seqno);
1239                 return 0;
1240         }
1241
1242 #if 0
1243         sidtab_hash_eval(&sidtab, "sids");
1244 #endif
1245
1246         if (policydb_read(&newpolicydb, fp)) {
1247                 LOAD_UNLOCK;
1248                 return -EINVAL;
1249         }
1250
1251         sidtab_init(&newsidtab);
1252
1253         /* Verify that the existing classes did not change. */
1254         if (hashtab_map(policydb.p_classes.table, validate_class, &newpolicydb)) {
1255                 printk(KERN_ERR "security:  the definition of an existing "
1256                        "class changed\n");
1257                 rc = -EINVAL;
1258                 goto err;
1259         }
1260
1261         /* Clone the SID table. */
1262         sidtab_shutdown(&sidtab);
1263         if (sidtab_map(&sidtab, clone_sid, &newsidtab)) {
1264                 rc = -ENOMEM;
1265                 goto err;
1266         }
1267
1268         /* Convert the internal representations of contexts
1269            in the new SID table and remove invalid SIDs. */
1270         args.oldp = &policydb;
1271         args.newp = &newpolicydb;
1272         sidtab_map_remove_on_error(&newsidtab, convert_context, &args);
1273
1274         /* Save the old policydb and SID table to free later. */
1275         memcpy(&oldpolicydb, &policydb, sizeof policydb);
1276         sidtab_set(&oldsidtab, &sidtab);
1277
1278         /* Install the new policydb and SID table. */
1279         POLICY_WRLOCK;
1280         memcpy(&policydb, &newpolicydb, sizeof policydb);
1281         sidtab_set(&sidtab, &newsidtab);
1282         seqno = ++latest_granting;
1283         policydb_loaded_version = policydb.policyvers;
1284         POLICY_WRUNLOCK;
1285         LOAD_UNLOCK;
1286
1287         /* Free the old policydb and SID table. */
1288         policydb_destroy(&oldpolicydb);
1289         sidtab_destroy(&oldsidtab);
1290
1291         avc_ss_reset(seqno);
1292         selnl_notify_policyload(seqno);
1293
1294         return 0;
1295
1296 err:
1297         LOAD_UNLOCK;
1298         sidtab_destroy(&newsidtab);
1299         policydb_destroy(&newpolicydb);
1300         return rc;
1301
1302 }
1303
1304 /**
1305  * security_port_sid - Obtain the SID for a port.
1306  * @domain: communication domain aka address family
1307  * @type: socket type
1308  * @protocol: protocol number
1309  * @port: port number
1310  * @out_sid: security identifier
1311  */
1312 int security_port_sid(u16 domain,
1313                       u16 type,
1314                       u8 protocol,
1315                       u16 port,
1316                       u32 *out_sid)
1317 {
1318         struct ocontext *c;
1319         int rc = 0;
1320
1321         POLICY_RDLOCK;
1322
1323         c = policydb.ocontexts[OCON_PORT];
1324         while (c) {
1325                 if (c->u.port.protocol == protocol &&
1326                     c->u.port.low_port <= port &&
1327                     c->u.port.high_port >= port)
1328                         break;
1329                 c = c->next;
1330         }
1331
1332         if (c) {
1333                 if (!c->sid[0]) {
1334                         rc = sidtab_context_to_sid(&sidtab,
1335                                                    &c->context[0],
1336                                                    &c->sid[0]);
1337                         if (rc)
1338                                 goto out;
1339                 }
1340                 *out_sid = c->sid[0];
1341         } else {
1342                 *out_sid = SECINITSID_PORT;
1343         }
1344
1345 out:
1346         POLICY_RDUNLOCK;
1347         return rc;
1348 }
1349
1350 /**
1351  * security_netif_sid - Obtain the SID for a network interface.
1352  * @name: interface name
1353  * @if_sid: interface SID
1354  * @msg_sid: default SID for received packets
1355  */
1356 int security_netif_sid(char *name,
1357                        u32 *if_sid,
1358                        u32 *msg_sid)
1359 {
1360         int rc = 0;
1361         struct ocontext *c;
1362
1363         POLICY_RDLOCK;
1364
1365         c = policydb.ocontexts[OCON_NETIF];
1366         while (c) {
1367                 if (strcmp(name, c->u.name) == 0)
1368                         break;
1369                 c = c->next;
1370         }
1371
1372         if (c) {
1373                 if (!c->sid[0] || !c->sid[1]) {
1374                         rc = sidtab_context_to_sid(&sidtab,
1375                                                   &c->context[0],
1376                                                   &c->sid[0]);
1377                         if (rc)
1378                                 goto out;
1379                         rc = sidtab_context_to_sid(&sidtab,
1380                                                    &c->context[1],
1381                                                    &c->sid[1]);
1382                         if (rc)
1383                                 goto out;
1384                 }
1385                 *if_sid = c->sid[0];
1386                 *msg_sid = c->sid[1];
1387         } else {
1388                 *if_sid = SECINITSID_NETIF;
1389                 *msg_sid = SECINITSID_NETMSG;
1390         }
1391
1392 out:
1393         POLICY_RDUNLOCK;
1394         return rc;
1395 }
1396
1397 static int match_ipv6_addrmask(u32 *input, u32 *addr, u32 *mask)
1398 {
1399         int i, fail = 0;
1400
1401         for(i = 0; i < 4; i++)
1402                 if(addr[i] != (input[i] & mask[i])) {
1403                         fail = 1;
1404                         break;
1405                 }
1406
1407         return !fail;
1408 }
1409
1410 /**
1411  * security_node_sid - Obtain the SID for a node (host).
1412  * @domain: communication domain aka address family
1413  * @addrp: address
1414  * @addrlen: address length in bytes
1415  * @out_sid: security identifier
1416  */
1417 int security_node_sid(u16 domain,
1418                       void *addrp,
1419                       u32 addrlen,
1420                       u32 *out_sid)
1421 {
1422         int rc = 0;
1423         struct ocontext *c;
1424
1425         POLICY_RDLOCK;
1426
1427         switch (domain) {
1428         case AF_INET: {
1429                 u32 addr;
1430
1431                 if (addrlen != sizeof(u32)) {
1432                         rc = -EINVAL;
1433                         goto out;
1434                 }
1435
1436                 addr = *((u32 *)addrp);
1437
1438                 c = policydb.ocontexts[OCON_NODE];
1439                 while (c) {
1440                         if (c->u.node.addr == (addr & c->u.node.mask))
1441                                 break;
1442                         c = c->next;
1443                 }
1444                 break;
1445         }
1446
1447         case AF_INET6:
1448                 if (addrlen != sizeof(u64) * 2) {
1449                         rc = -EINVAL;
1450                         goto out;
1451                 }
1452                 c = policydb.ocontexts[OCON_NODE6];
1453                 while (c) {
1454                         if (match_ipv6_addrmask(addrp, c->u.node6.addr,
1455                                                 c->u.node6.mask))
1456                                 break;
1457                         c = c->next;
1458                 }
1459                 break;
1460
1461         default:
1462                 *out_sid = SECINITSID_NODE;
1463                 goto out;
1464         }
1465
1466         if (c) {
1467                 if (!c->sid[0]) {
1468                         rc = sidtab_context_to_sid(&sidtab,
1469                                                    &c->context[0],
1470                                                    &c->sid[0]);
1471                         if (rc)
1472                                 goto out;
1473                 }
1474                 *out_sid = c->sid[0];
1475         } else {
1476                 *out_sid = SECINITSID_NODE;
1477         }
1478
1479 out:
1480         POLICY_RDUNLOCK;
1481         return rc;
1482 }
1483
1484 #define SIDS_NEL 25
1485
1486 /**
1487  * security_get_user_sids - Obtain reachable SIDs for a user.
1488  * @fromsid: starting SID
1489  * @username: username
1490  * @sids: array of reachable SIDs for user
1491  * @nel: number of elements in @sids
1492  *
1493  * Generate the set of SIDs for legal security contexts
1494  * for a given user that can be reached by @fromsid.
1495  * Set *@sids to point to a dynamically allocated
1496  * array containing the set of SIDs.  Set *@nel to the
1497  * number of elements in the array.
1498  */
1499
1500 int security_get_user_sids(u32 fromsid,
1501                            char *username,
1502                            u32 **sids,
1503                            u32 *nel)
1504 {
1505         struct context *fromcon, usercon;
1506         u32 *mysids, *mysids2, sid;
1507         u32 mynel = 0, maxnel = SIDS_NEL;
1508         struct user_datum *user;
1509         struct role_datum *role;
1510         struct av_decision avd;
1511         struct ebitmap_node *rnode, *tnode;
1512         int rc = 0, i, j;
1513
1514         if (!ss_initialized) {
1515                 *sids = NULL;
1516                 *nel = 0;
1517                 goto out;
1518         }
1519
1520         POLICY_RDLOCK;
1521
1522         fromcon = sidtab_search(&sidtab, fromsid);
1523         if (!fromcon) {
1524                 rc = -EINVAL;
1525                 goto out_unlock;
1526         }
1527
1528         user = hashtab_search(policydb.p_users.table, username);
1529         if (!user) {
1530                 rc = -EINVAL;
1531                 goto out_unlock;
1532         }
1533         usercon.user = user->value;
1534
1535         mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
1536         if (!mysids) {
1537                 rc = -ENOMEM;
1538                 goto out_unlock;
1539         }
1540
1541         ebitmap_for_each_bit(&user->roles, rnode, i) {
1542                 if (!ebitmap_node_get_bit(rnode, i))
1543                         continue;
1544                 role = policydb.role_val_to_struct[i];
1545                 usercon.role = i+1;
1546                 ebitmap_for_each_bit(&role->types, tnode, j) {
1547                         if (!ebitmap_node_get_bit(tnode, j))
1548                                 continue;
1549                         usercon.type = j+1;
1550
1551                         if (mls_setup_user_range(fromcon, user, &usercon))
1552                                 continue;
1553
1554                         rc = context_struct_compute_av(fromcon, &usercon,
1555                                                        SECCLASS_PROCESS,
1556                                                        PROCESS__TRANSITION,
1557                                                        &avd);
1558                         if (rc ||  !(avd.allowed & PROCESS__TRANSITION))
1559                                 continue;
1560                         rc = sidtab_context_to_sid(&sidtab, &usercon, &sid);
1561                         if (rc) {
1562                                 kfree(mysids);
1563                                 goto out_unlock;
1564                         }
1565                         if (mynel < maxnel) {
1566                                 mysids[mynel++] = sid;
1567                         } else {
1568                                 maxnel += SIDS_NEL;
1569                                 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
1570                                 if (!mysids2) {
1571                                         rc = -ENOMEM;
1572                                         kfree(mysids);
1573                                         goto out_unlock;
1574                                 }
1575                                 memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
1576                                 kfree(mysids);
1577                                 mysids = mysids2;
1578                                 mysids[mynel++] = sid;
1579                         }
1580                 }
1581         }
1582
1583         *sids = mysids;
1584         *nel = mynel;
1585
1586 out_unlock:
1587         POLICY_RDUNLOCK;
1588 out:
1589         return rc;
1590 }
1591
1592 /**
1593  * security_genfs_sid - Obtain a SID for a file in a filesystem
1594  * @fstype: filesystem type
1595  * @path: path from root of mount
1596  * @sclass: file security class
1597  * @sid: SID for path
1598  *
1599  * Obtain a SID to use for a file in a filesystem that
1600  * cannot support xattr or use a fixed labeling behavior like
1601  * transition SIDs or task SIDs.
1602  */
1603 int security_genfs_sid(const char *fstype,
1604                        char *path,
1605                        u16 sclass,
1606                        u32 *sid)
1607 {
1608         int len;
1609         struct genfs *genfs;
1610         struct ocontext *c;
1611         int rc = 0, cmp = 0;
1612
1613         POLICY_RDLOCK;
1614
1615         for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
1616                 cmp = strcmp(fstype, genfs->fstype);
1617                 if (cmp <= 0)
1618                         break;
1619         }
1620
1621         if (!genfs || cmp) {
1622                 *sid = SECINITSID_UNLABELED;
1623                 rc = -ENOENT;
1624                 goto out;
1625         }
1626
1627         for (c = genfs->head; c; c = c->next) {
1628                 len = strlen(c->u.name);
1629                 if ((!c->v.sclass || sclass == c->v.sclass) &&
1630                     (strncmp(c->u.name, path, len) == 0))
1631                         break;
1632         }
1633
1634         if (!c) {
1635                 *sid = SECINITSID_UNLABELED;
1636                 rc = -ENOENT;
1637                 goto out;
1638         }
1639
1640         if (!c->sid[0]) {
1641                 rc = sidtab_context_to_sid(&sidtab,
1642                                            &c->context[0],
1643                                            &c->sid[0]);
1644                 if (rc)
1645                         goto out;
1646         }
1647
1648         *sid = c->sid[0];
1649 out:
1650         POLICY_RDUNLOCK;
1651         return rc;
1652 }
1653
1654 /**
1655  * security_fs_use - Determine how to handle labeling for a filesystem.
1656  * @fstype: filesystem type
1657  * @behavior: labeling behavior
1658  * @sid: SID for filesystem (superblock)
1659  */
1660 int security_fs_use(
1661         const char *fstype,
1662         unsigned int *behavior,
1663         u32 *sid)
1664 {
1665         int rc = 0;
1666         struct ocontext *c;
1667
1668         POLICY_RDLOCK;
1669
1670         c = policydb.ocontexts[OCON_FSUSE];
1671         while (c) {
1672                 if (strcmp(fstype, c->u.name) == 0)
1673                         break;
1674                 c = c->next;
1675         }
1676
1677         if (c) {
1678                 *behavior = c->v.behavior;
1679                 if (!c->sid[0]) {
1680                         rc = sidtab_context_to_sid(&sidtab,
1681                                                    &c->context[0],
1682                                                    &c->sid[0]);
1683                         if (rc)
1684                                 goto out;
1685                 }
1686                 *sid = c->sid[0];
1687         } else {
1688                 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
1689                 if (rc) {
1690                         *behavior = SECURITY_FS_USE_NONE;
1691                         rc = 0;
1692                 } else {
1693                         *behavior = SECURITY_FS_USE_GENFS;
1694                 }
1695         }
1696
1697 out:
1698         POLICY_RDUNLOCK;
1699         return rc;
1700 }
1701
1702 int security_get_bools(int *len, char ***names, int **values)
1703 {
1704         int i, rc = -ENOMEM;
1705
1706         POLICY_RDLOCK;
1707         *names = NULL;
1708         *values = NULL;
1709
1710         *len = policydb.p_bools.nprim;
1711         if (!*len) {
1712                 rc = 0;
1713                 goto out;
1714         }
1715
1716        *names = kcalloc(*len, sizeof(char*), GFP_ATOMIC);
1717         if (!*names)
1718                 goto err;
1719
1720        *values = kcalloc(*len, sizeof(int), GFP_ATOMIC);
1721         if (!*values)
1722                 goto err;
1723
1724         for (i = 0; i < *len; i++) {
1725                 size_t name_len;
1726                 (*values)[i] = policydb.bool_val_to_struct[i]->state;
1727                 name_len = strlen(policydb.p_bool_val_to_name[i]) + 1;
1728                (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC);
1729                 if (!(*names)[i])
1730                         goto err;
1731                 strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len);
1732                 (*names)[i][name_len - 1] = 0;
1733         }
1734         rc = 0;
1735 out:
1736         POLICY_RDUNLOCK;
1737         return rc;
1738 err:
1739         if (*names) {
1740                 for (i = 0; i < *len; i++)
1741                         kfree((*names)[i]);
1742         }
1743         kfree(*values);
1744         goto out;
1745 }
1746
1747
1748 int security_set_bools(int len, int *values)
1749 {
1750         int i, rc = 0;
1751         int lenp, seqno = 0;
1752         struct cond_node *cur;
1753
1754         POLICY_WRLOCK;
1755
1756         lenp = policydb.p_bools.nprim;
1757         if (len != lenp) {
1758                 rc = -EFAULT;
1759                 goto out;
1760         }
1761
1762         printk(KERN_INFO "security: committed booleans { ");
1763         for (i = 0; i < len; i++) {
1764                 if (values[i]) {
1765                         policydb.bool_val_to_struct[i]->state = 1;
1766                 } else {
1767                         policydb.bool_val_to_struct[i]->state = 0;
1768                 }
1769                 if (i != 0)
1770                         printk(", ");
1771                 printk("%s:%d", policydb.p_bool_val_to_name[i],
1772                        policydb.bool_val_to_struct[i]->state);
1773         }
1774         printk(" }\n");
1775
1776         for (cur = policydb.cond_list; cur != NULL; cur = cur->next) {
1777                 rc = evaluate_cond_node(&policydb, cur);
1778                 if (rc)
1779                         goto out;
1780         }
1781
1782         seqno = ++latest_granting;
1783
1784 out:
1785         POLICY_WRUNLOCK;
1786         if (!rc) {
1787                 avc_ss_reset(seqno);
1788                 selnl_notify_policyload(seqno);
1789         }
1790         return rc;
1791 }
1792
1793 int security_get_bool_value(int bool)
1794 {
1795         int rc = 0;
1796         int len;
1797
1798         POLICY_RDLOCK;
1799
1800         len = policydb.p_bools.nprim;
1801         if (bool >= len) {
1802                 rc = -EFAULT;
1803                 goto out;
1804         }
1805
1806         rc = policydb.bool_val_to_struct[bool]->state;
1807 out:
1808         POLICY_RDUNLOCK;
1809         return rc;
1810 }