b2821d6f55672bee1250e71de8e2d0406cf54187
[linux-flexiantxendom0-3.2.10.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  *  Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
8  *
9  *      This program is free software; you can redistribute it and/or modify
10  *      it under the terms of the GNU General Public License version 2,
11  *      as published by the Free Software Foundation.
12  */
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/string.h>
16 #include <linux/spinlock.h>
17 #include <linux/errno.h>
18 #include <linux/in.h>
19 #include <linux/sched.h>
20 #include <asm/semaphore.h>
21 #include "flask.h"
22 #include "avc.h"
23 #include "avc_ss.h"
24 #include "security.h"
25 #include "context.h"
26 #include "policydb.h"
27 #include "sidtab.h"
28 #include "services.h"
29 #include "mls.h"
30
31 static rwlock_t policy_rwlock = RW_LOCK_UNLOCKED;
32 #define POLICY_RDLOCK read_lock(&policy_rwlock)
33 #define POLICY_WRLOCK write_lock_irq(&policy_rwlock)
34 #define POLICY_RDUNLOCK read_unlock(&policy_rwlock)
35 #define POLICY_WRUNLOCK write_unlock_irq(&policy_rwlock)
36
37 static DECLARE_MUTEX(load_sem);
38 #define LOAD_LOCK down(&load_sem)
39 #define LOAD_UNLOCK up(&load_sem)
40
41 struct sidtab sidtab;
42 struct policydb policydb;
43 int ss_initialized = 0;
44
45 /*
46  * The largest sequence number that has been used when
47  * providing an access decision to the access vector cache.
48  * The sequence number only changes when a policy change
49  * occurs.
50  */
51 static u32 latest_granting = 0;
52
53 /*
54  * Return the boolean value of a constraint expression
55  * when it is applied to the specified source and target
56  * security contexts.
57  */
58 static int constraint_expr_eval(struct context *scontext,
59                                 struct context *tcontext,
60                                 struct constraint_expr *cexpr)
61 {
62         u32 val1, val2;
63         struct context *c;
64         struct role_datum *r1, *r2;
65         struct constraint_expr *e;
66         int s[CEXPR_MAXDEPTH];
67         int sp = -1;
68
69         for (e = cexpr; e; e = e->next) {
70                 switch (e->expr_type) {
71                 case CEXPR_NOT:
72                         BUG_ON(sp < 0);
73                         s[sp] = !s[sp];
74                         break;
75                 case CEXPR_AND:
76                         BUG_ON(sp < 1);
77                         sp--;
78                         s[sp] &= s[sp+1];
79                         break;
80                 case CEXPR_OR:
81                         BUG_ON(sp < 1);
82                         sp--;
83                         s[sp] |= s[sp+1];
84                         break;
85                 case CEXPR_ATTR:
86                         if (sp == (CEXPR_MAXDEPTH-1))
87                                 return 0;
88                         switch (e->attr) {
89                         case CEXPR_USER:
90                                 val1 = scontext->user;
91                                 val2 = tcontext->user;
92                                 break;
93                         case CEXPR_TYPE:
94                                 val1 = scontext->type;
95                                 val2 = tcontext->type;
96                                 break;
97                         case CEXPR_ROLE:
98                                 val1 = scontext->role;
99                                 val2 = tcontext->role;
100                                 r1 = policydb.role_val_to_struct[val1 - 1];
101                                 r2 = policydb.role_val_to_struct[val2 - 1];
102                                 switch (e->op) {
103                                 case CEXPR_DOM:
104                                         s[++sp] = ebitmap_get_bit(&r1->dominates,
105                                                                   val2 - 1);
106                                         continue;
107                                 case CEXPR_DOMBY:
108                                         s[++sp] = ebitmap_get_bit(&r2->dominates,
109                                                                   val1 - 1);
110                                         continue;
111                                 case CEXPR_INCOMP:
112                                         s[++sp] = ( !ebitmap_get_bit(&r1->dominates,
113                                                                      val2 - 1) &&
114                                                     !ebitmap_get_bit(&r2->dominates,
115                                                                      val1 - 1) );
116                                         continue;
117                                 default:
118                                         break;
119                                 }
120                                 break;
121                         default:
122                                 BUG();
123                                 return 0;
124                         }
125
126                         switch (e->op) {
127                         case CEXPR_EQ:
128                                 s[++sp] = (val1 == val2);
129                                 break;
130                         case CEXPR_NEQ:
131                                 s[++sp] = (val1 != val2);
132                                 break;
133                         default:
134                                 BUG();
135                                 return 0;
136                         }
137                         break;
138                 case CEXPR_NAMES:
139                         if (sp == (CEXPR_MAXDEPTH-1))
140                                 return 0;
141                         c = scontext;
142                         if (e->attr & CEXPR_TARGET)
143                                 c = tcontext;
144                         if (e->attr & CEXPR_USER)
145                                 val1 = c->user;
146                         else if (e->attr & CEXPR_ROLE)
147                                 val1 = c->role;
148                         else if (e->attr & CEXPR_TYPE)
149                                 val1 = c->type;
150                         else {
151                                 BUG();
152                                 return 0;
153                         }
154
155                         switch (e->op) {
156                         case CEXPR_EQ:
157                                 s[++sp] = ebitmap_get_bit(&e->names, val1 - 1);
158                                 break;
159                         case CEXPR_NEQ:
160                                 s[++sp] = !ebitmap_get_bit(&e->names, val1 - 1);
161                                 break;
162                         default:
163                                 BUG();
164                                 return 0;
165                         }
166                         break;
167                 default:
168                         BUG();
169                         return 0;
170                 }
171         }
172
173         BUG_ON(sp != 0);
174         return s[0];
175 }
176
177 /*
178  * Compute access vectors based on a context structure pair for
179  * the permissions in a particular class.
180  */
181 static int context_struct_compute_av(struct context *scontext,
182                                      struct context *tcontext,
183                                      u16 tclass,
184                                      u32 requested,
185                                      struct av_decision *avd)
186 {
187         struct constraint_node *constraint;
188         struct role_allow *ra;
189         struct avtab_key avkey;
190         struct avtab_datum *avdatum;
191         struct class_datum *tclass_datum;
192
193         if (!tclass || tclass > policydb.p_classes.nprim) {
194                 printk(KERN_ERR "security_compute_av:  unrecognized class %d\n",
195                        tclass);
196                 return -EINVAL;
197         }
198         tclass_datum = policydb.class_val_to_struct[tclass - 1];
199
200         /*
201          * Initialize the access vectors to the default values.
202          */
203         avd->allowed = 0;
204         avd->decided = 0xffffffff;
205         avd->auditallow = 0;
206         avd->auditdeny = 0xffffffff;
207         avd->seqno = latest_granting;
208
209         /*
210          * If a specific type enforcement rule was defined for
211          * this permission check, then use it.
212          */
213         avkey.source_type = scontext->type;
214         avkey.target_type = tcontext->type;
215         avkey.target_class = tclass;
216         avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_AV);
217         if (avdatum) {
218                 if (avdatum->specified & AVTAB_ALLOWED)
219                         avd->allowed = avtab_allowed(avdatum);
220                 if (avdatum->specified & AVTAB_AUDITDENY)
221                         avd->auditdeny = avtab_auditdeny(avdatum);
222                 if (avdatum->specified & AVTAB_AUDITALLOW)
223                         avd->auditallow = avtab_auditallow(avdatum);
224         }
225
226         /*
227          * Remove any permissions prohibited by the MLS policy.
228          */
229         mls_compute_av(scontext, tcontext, tclass_datum, &avd->allowed);
230
231         /*
232          * Remove any permissions prohibited by a constraint.
233          */
234         constraint = tclass_datum->constraints;
235         while (constraint) {
236                 if ((constraint->permissions & (avd->allowed)) &&
237                     !constraint_expr_eval(scontext, tcontext,
238                                           constraint->expr)) {
239                         avd->allowed = (avd->allowed) & ~(constraint->permissions);
240                 }
241                 constraint = constraint->next;
242         }
243
244         /*
245          * If checking process transition permission and the
246          * role is changing, then check the (current_role, new_role)
247          * pair.
248          */
249         if (tclass == SECCLASS_PROCESS &&
250             avd->allowed && PROCESS__TRANSITION &&
251             scontext->role != tcontext->role) {
252                 for (ra = policydb.role_allow; ra; ra = ra->next) {
253                         if (scontext->role == ra->role &&
254                             tcontext->role == ra->new_role)
255                                 break;
256                 }
257                 if (!ra)
258                         avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION);
259         }
260
261         return 0;
262 }
263
264 /**
265  * security_compute_av - Compute access vector decisions.
266  * @ssid: source security identifier
267  * @tsid: target security identifier
268  * @tclass: target security class
269  * @requested: requested permissions
270  * @avd: access vector decisions
271  *
272  * Compute a set of access vector decisions based on the
273  * SID pair (@ssid, @tsid) for the permissions in @tclass.
274  * Return -%EINVAL if any of the parameters are invalid or %0
275  * if the access vector decisions were computed successfully.
276  */
277 int security_compute_av(u32 ssid,
278                         u32 tsid,
279                         u16 tclass,
280                         u32 requested,
281                         struct av_decision *avd)
282 {
283         struct context *scontext = 0, *tcontext = 0;
284         int rc = 0;
285
286         if (!ss_initialized) {
287                 avd->allowed = requested;
288                 avd->decided = requested;
289                 avd->auditallow = 0;
290                 avd->auditdeny = 0xffffffff;
291                 avd->seqno = latest_granting;
292                 return 0;
293         }
294
295         POLICY_RDLOCK;
296
297         scontext = sidtab_search(&sidtab, ssid);
298         if (!scontext) {
299                 printk(KERN_ERR "security_compute_av:  unrecognized SID %d\n",
300                        ssid);
301                 rc = -EINVAL;
302                 goto out;
303         }
304         tcontext = sidtab_search(&sidtab, tsid);
305         if (!tcontext) {
306                 printk(KERN_ERR "security_compute_av:  unrecognized SID %d\n",
307                        tsid);
308                 rc = -EINVAL;
309                 goto out;
310         }
311
312         rc = context_struct_compute_av(scontext, tcontext, tclass,
313                                        requested, avd);
314 out:
315         POLICY_RDUNLOCK;
316         return rc;
317 }
318
319 /*
320  * Write the security context string representation of
321  * the context structure `context' into a dynamically
322  * allocated string of the correct size.  Set `*scontext'
323  * to point to this string and set `*scontext_len' to
324  * the length of the string.
325  */
326 int context_struct_to_string(struct context *context, char **scontext, u32 *scontext_len)
327 {
328         char *scontextp;
329
330         *scontext = 0;
331         *scontext_len = 0;
332
333         /* Compute the size of the context. */
334         *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1;
335         *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1;
336         *scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1;
337         *scontext_len += mls_compute_context_len(context);
338
339         /* Allocate space for the context; caller must free this space. */
340         scontextp = kmalloc(*scontext_len+1,GFP_ATOMIC);
341         if (!scontextp) {
342                 return -ENOMEM;
343         }
344         *scontext = scontextp;
345
346         /*
347          * Copy the user name, role name and type name into the context.
348          */
349         sprintf(scontextp, "%s:%s:%s:",
350                 policydb.p_user_val_to_name[context->user - 1],
351                 policydb.p_role_val_to_name[context->role - 1],
352                 policydb.p_type_val_to_name[context->type - 1]);
353         scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) +
354                      1 + strlen(policydb.p_role_val_to_name[context->role - 1]) +
355                      1 + strlen(policydb.p_type_val_to_name[context->type - 1]) + 1;
356
357         mls_sid_to_context(context, &scontextp);
358
359         scontextp--;
360         *scontextp = 0;
361
362         return 0;
363 }
364
365 #include "initial_sid_to_string.h"
366
367 /**
368  * security_sid_to_context - Obtain a context for a given SID.
369  * @sid: security identifier, SID
370  * @scontext: security context
371  * @scontext_len: length in bytes
372  *
373  * Write the string representation of the context associated with @sid
374  * into a dynamically allocated string of the correct size.  Set @scontext
375  * to point to this string and set @scontext_len to the length of the string.
376  */
377 int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
378 {
379         struct context *context;
380         int rc = 0;
381
382         if (!ss_initialized) {
383                 if (sid <= SECINITSID_NUM) {
384                         char *scontextp;
385
386                         *scontext_len = strlen(initial_sid_to_string[sid]) + 1;
387                         scontextp = kmalloc(*scontext_len,GFP_KERNEL);
388                         strcpy(scontextp, initial_sid_to_string[sid]);
389                         *scontext = scontextp;
390                         goto out;
391                 }
392                 printk(KERN_ERR "security_sid_to_context:  called before initial "
393                        "load_policy on unknown SID %d\n", sid);
394                 rc = -EINVAL;
395                 goto out;
396         }
397         POLICY_RDLOCK;
398         context = sidtab_search(&sidtab, sid);
399         if (!context) {
400                 printk(KERN_ERR "security_sid_to_context:  unrecognized SID "
401                        "%d\n", sid);
402                 rc = -EINVAL;
403                 goto out_unlock;
404         }
405         rc = context_struct_to_string(context, scontext, scontext_len);
406 out_unlock:
407         POLICY_RDUNLOCK;
408 out:
409         return rc;
410
411 }
412
413 /**
414  * security_context_to_sid - Obtain a SID for a given security context.
415  * @scontext: security context
416  * @scontext_len: length in bytes
417  * @sid: security identifier, SID
418  *
419  * Obtains a SID associated with the security context that
420  * has the string representation specified by @scontext.
421  * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
422  * memory is available, or 0 on success.
423  */
424 int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
425 {
426         char *scontext2;
427         struct context context;
428         struct role_datum *role;
429         struct type_datum *typdatum;
430         struct user_datum *usrdatum;
431         char *scontextp, *p, oldc;
432         int rc = 0;
433
434         if (!ss_initialized) {
435                 int i;
436
437                 for (i = 1; i < SECINITSID_NUM; i++) {
438                         if (!strcmp(initial_sid_to_string[i], scontext)) {
439                                 *sid = i;
440                                 goto out;
441                         }
442                 }
443                 printk(KERN_ERR "security_context_to_sid: called before "
444                        "initial load_policy on unknown context %s\n", scontext);
445                 rc = -EINVAL;
446                 goto out;
447         }
448         *sid = SECSID_NULL;
449
450         /* Copy the string so that we can modify the copy as we parse it.
451            The string should already by null terminated, but we append a
452            null suffix to the copy to avoid problems with the existing
453            attr package, which doesn't view the null terminator as part
454            of the attribute value. */
455         scontext2 = kmalloc(scontext_len+1,GFP_KERNEL);
456         if (!scontext2) {
457                 rc = -ENOMEM;
458                 goto out;
459         }
460         memcpy(scontext2, scontext, scontext_len);
461         scontext2[scontext_len] = 0;
462
463         context_init(&context);
464         *sid = SECSID_NULL;
465
466         POLICY_RDLOCK;
467
468         /* Parse the security context. */
469
470         rc = -EINVAL;
471         scontextp = (char *) scontext2;
472
473         /* Extract the user. */
474         p = scontextp;
475         while (*p && *p != ':')
476                 p++;
477
478         if (*p == 0)
479                 goto out_unlock;
480
481         *p++ = 0;
482
483         usrdatum = hashtab_search(policydb.p_users.table, scontextp);
484         if (!usrdatum)
485                 goto out_unlock;
486
487         context.user = usrdatum->value;
488
489         /* Extract role. */
490         scontextp = p;
491         while (*p && *p != ':')
492                 p++;
493
494         if (*p == 0)
495                 goto out_unlock;
496
497         *p++ = 0;
498
499         role = hashtab_search(policydb.p_roles.table, scontextp);
500         if (!role)
501                 goto out_unlock;
502         context.role = role->value;
503
504         /* Extract type. */
505         scontextp = p;
506         while (*p && *p != ':')
507                 p++;
508         oldc = *p;
509         *p++ = 0;
510
511         typdatum = hashtab_search(policydb.p_types.table, scontextp);
512         if (!typdatum)
513                 goto out_unlock;
514
515         context.type = typdatum->value;
516
517         rc = mls_context_to_sid(oldc, &p, &context);
518         if (rc)
519                 goto out_unlock;
520
521         /* Check the validity of the new context. */
522         if (!policydb_context_isvalid(&policydb, &context)) {
523                 rc = -EINVAL;
524                 goto out_unlock;
525         }
526         /* Obtain the new sid. */
527         rc = sidtab_context_to_sid(&sidtab, &context, sid);
528 out_unlock:
529         POLICY_RDUNLOCK;
530         context_destroy(&context);
531         kfree(scontext2);
532 out:
533         return rc;
534 }
535
536 static inline int compute_sid_handle_invalid_context(
537         struct context *scontext,
538         struct context *tcontext,
539         u16 tclass,
540         struct context *newcontext)
541 {
542         int rc = 0;
543
544         if (selinux_enforcing) {
545                 rc = -EACCES;
546         } else {
547                 char *s, *t, *n;
548                 u32 slen, tlen, nlen;
549
550                 context_struct_to_string(scontext, &s, &slen);
551                 context_struct_to_string(tcontext, &t, &tlen);
552                 context_struct_to_string(newcontext, &n, &nlen);
553                 printk(KERN_ERR "security_compute_sid:  invalid context %s", n);
554                 printk(" for scontext=%s", s);
555                 printk(" tcontext=%s", t);
556                 printk(" tclass=%s\n", policydb.p_class_val_to_name[tclass-1]);
557                 kfree(s);
558                 kfree(t);
559                 kfree(n);
560         }
561         return rc;
562 }
563
564 static int security_compute_sid(u32 ssid,
565                                 u32 tsid,
566                                 u16 tclass,
567                                 u32 specified,
568                                 u32 *out_sid)
569 {
570         struct context *scontext = 0, *tcontext = 0, newcontext;
571         struct role_trans *roletr = 0;
572         struct avtab_key avkey;
573         struct avtab_datum *avdatum;
574         unsigned int type_change = 0;
575         int rc = 0;
576
577         if (!ss_initialized) {
578                 switch (tclass) {
579                 case SECCLASS_PROCESS:
580                         *out_sid = ssid;
581                         break;
582                 default:
583                         *out_sid = tsid;
584                         break;
585                 }
586                 goto out;
587         }
588
589         POLICY_RDLOCK;
590
591         scontext = sidtab_search(&sidtab, ssid);
592         if (!scontext) {
593                 printk(KERN_ERR "security_compute_sid:  unrecognized SID %d\n",
594                        ssid);
595                 rc = -EINVAL;
596                 goto out_unlock;
597         }
598         tcontext = sidtab_search(&sidtab, tsid);
599         if (!tcontext) {
600                 printk(KERN_ERR "security_compute_sid:  unrecognized SID %d\n",
601                        tsid);
602                 rc = -EINVAL;
603                 goto out_unlock;
604         }
605
606         context_init(&newcontext);
607
608         /* Set the user identity. */
609         switch (specified) {
610         case AVTAB_TRANSITION:
611         case AVTAB_CHANGE:
612                 /* Use the process user identity. */
613                 newcontext.user = scontext->user;
614                 break;
615         case AVTAB_MEMBER:
616                 /* Use the related object owner. */
617                 newcontext.user = tcontext->user;
618                 break;
619         }
620
621         /* Set the role and type to default values. */
622         switch (tclass) {
623         case SECCLASS_PROCESS:
624                 /* Use the current role and type of process. */
625                 newcontext.role = scontext->role;
626                 newcontext.type = scontext->type;
627                 break;
628         default:
629                 /* Use the well-defined object role. */
630                 newcontext.role = OBJECT_R_VAL;
631                 /* Use the type of the related object. */
632                 newcontext.type = tcontext->type;
633         }
634
635         /* Look for a type transition/member/change rule. */
636         avkey.source_type = scontext->type;
637         avkey.target_type = tcontext->type;
638         avkey.target_class = tclass;
639         avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_TYPE);
640         type_change = (avdatum && (avdatum->specified & specified));
641         if (type_change) {
642                 /* Use the type from the type transition/member/change rule. */
643                 switch (specified) {
644                 case AVTAB_TRANSITION:
645                         newcontext.type = avtab_transition(avdatum);
646                         break;
647                 case AVTAB_MEMBER:
648                         newcontext.type = avtab_member(avdatum);
649                         break;
650                 case AVTAB_CHANGE:
651                         newcontext.type = avtab_change(avdatum);
652                         break;
653                 }
654         }
655
656         /* Check for class-specific changes. */
657         switch (tclass) {
658         case SECCLASS_PROCESS:
659                 if (specified & AVTAB_TRANSITION) {
660                         /* Look for a role transition rule. */
661                         for (roletr = policydb.role_tr; roletr;
662                              roletr = roletr->next) {
663                                 if (roletr->role == scontext->role &&
664                                     roletr->type == tcontext->type) {
665                                         /* Use the role transition rule. */
666                                         newcontext.role = roletr->new_role;
667                                         break;
668                                 }
669                         }
670                 }
671
672                 if (!type_change && !roletr) {
673                         /* No change in process role or type. */
674                         *out_sid = ssid;
675                         goto out_unlock;
676
677                 }
678                 break;
679         default:
680                 if (!type_change &&
681                     (newcontext.user == tcontext->user) &&
682                     mls_context_cmp(scontext, tcontext)) {
683                         /* No change in object type, owner,
684                            or MLS attributes. */
685                         *out_sid = tsid;
686                         goto out_unlock;
687                 }
688                 break;
689         }
690
691         /* Set the MLS attributes.
692            This is done last because it may allocate memory. */
693         rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext);
694         if (rc)
695                 goto out_unlock;
696
697         /* Check the validity of the context. */
698         if (!policydb_context_isvalid(&policydb, &newcontext)) {
699                 rc = compute_sid_handle_invalid_context(scontext,
700                                                         tcontext,
701                                                         tclass,
702                                                         &newcontext);
703                 if (rc)
704                         goto out_unlock;
705         }
706         /* Obtain the sid for the context. */
707         rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid);
708 out_unlock:
709         POLICY_RDUNLOCK;
710         context_destroy(&newcontext);
711 out:
712         return rc;
713 }
714
715 /**
716  * security_transition_sid - Compute the SID for a new subject/object.
717  * @ssid: source security identifier
718  * @tsid: target security identifier
719  * @tclass: target security class
720  * @out_sid: security identifier for new subject/object
721  *
722  * Compute a SID to use for labeling a new subject or object in the
723  * class @tclass based on a SID pair (@ssid, @tsid).
724  * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
725  * if insufficient memory is available, or %0 if the new SID was
726  * computed successfully.
727  */
728 int security_transition_sid(u32 ssid,
729                             u32 tsid,
730                             u16 tclass,
731                             u32 *out_sid)
732 {
733         return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid);
734 }
735
736 /**
737  * security_member_sid - Compute the SID for member selection.
738  * @ssid: source security identifier
739  * @tsid: target security identifier
740  * @tclass: target security class
741  * @out_sid: security identifier for selected member
742  *
743  * Compute a SID to use when selecting a member of a polyinstantiated
744  * object of class @tclass based on a SID pair (@ssid, @tsid).
745  * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
746  * if insufficient memory is available, or %0 if the SID was
747  * computed successfully.
748  */
749 int security_member_sid(u32 ssid,
750                         u32 tsid,
751                         u16 tclass,
752                         u32 *out_sid)
753 {
754         return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid);
755 }
756
757 /**
758  * security_change_sid - Compute the SID for object relabeling.
759  * @ssid: source security identifier
760  * @tsid: target security identifier
761  * @tclass: target security class
762  * @out_sid: security identifier for selected member
763  *
764  * Compute a SID to use for relabeling an object of class @tclass
765  * based on a SID pair (@ssid, @tsid).
766  * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM
767  * if insufficient memory is available, or %0 if the SID was
768  * computed successfully.
769  */
770 int security_change_sid(u32 ssid,
771                         u32 tsid,
772                         u16 tclass,
773                         u32 *out_sid)
774 {
775         return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid);
776 }
777
778 /*
779  * Verify that each permission that is defined under the
780  * existing policy is still defined with the same value
781  * in the new policy.
782  */
783 static int validate_perm(void *key, void *datum, void *p)
784 {
785         struct hashtab *h;
786         struct perm_datum *perdatum, *perdatum2;
787         int rc = 0;
788
789
790         h = p;
791         perdatum = datum;
792
793         perdatum2 = hashtab_search(h, key);
794         if (!perdatum2) {
795                 printk(KERN_ERR "security:  permission %s disappeared",
796                        (char *)key);
797                 rc = -ENOENT;
798                 goto out;
799         }
800         if (perdatum->value != perdatum2->value) {
801                 printk(KERN_ERR "security:  the value of permission %s changed",
802                        (char *)key);
803                 rc = -EINVAL;
804         }
805 out:
806         return rc;
807 }
808
809 /*
810  * Verify that each class that is defined under the
811  * existing policy is still defined with the same
812  * attributes in the new policy.
813  */
814 static int validate_class(void *key, void *datum, void *p)
815 {
816         struct policydb *newp;
817         struct class_datum *cladatum, *cladatum2;
818         int rc;
819
820         newp = p;
821         cladatum = datum;
822
823         cladatum2 = hashtab_search(newp->p_classes.table, key);
824         if (!cladatum2) {
825                 printk(KERN_ERR "security:  class %s disappeared\n",
826                        (char *)key);
827                 rc = -ENOENT;
828                 goto out;
829         }
830         if (cladatum->value != cladatum2->value) {
831                 printk(KERN_ERR "security:  the value of class %s changed\n",
832                        (char *)key);
833                 rc = -EINVAL;
834                 goto out;
835         }
836         if ((cladatum->comdatum && !cladatum2->comdatum) ||
837             (!cladatum->comdatum && cladatum2->comdatum)) {
838                 printk(KERN_ERR "security:  the inherits clause for the access "
839                        "vector definition for class %s changed\n", (char *)key);
840                 rc = -EINVAL;
841                 goto out;
842         }
843         if (cladatum->comdatum) {
844                 rc = hashtab_map(cladatum->comdatum->permissions.table, validate_perm,
845                                  cladatum2->comdatum->permissions.table);
846                 if (rc) {
847                         printk(" in the access vector definition for class "
848                                "%s\n", (char *)key);
849                         goto out;
850                 }
851         }
852         rc = hashtab_map(cladatum->permissions.table, validate_perm,
853                          cladatum2->permissions.table);
854         if (rc)
855                 printk(" in access vector definition for class %s\n",
856                        (char *)key);
857 out:
858         return rc;
859 }
860
861 /* Clone the SID into the new SID table. */
862 static int clone_sid(u32 sid,
863                      struct context *context,
864                      void *arg)
865 {
866         struct sidtab *s = arg;
867
868         return sidtab_insert(s, sid, context);
869 }
870
871 static inline int convert_context_handle_invalid_context(struct context *context)
872 {
873         int rc = 0;
874
875         if (selinux_enforcing) {
876                 rc = -EINVAL;
877         } else {
878                 char *s;
879                 u32 len;
880
881                 context_struct_to_string(context, &s, &len);
882                 printk(KERN_ERR "security:  context %s is invalid\n", s);
883                 kfree(s);
884         }
885         return rc;
886 }
887
888 struct convert_context_args {
889         struct policydb *oldp;
890         struct policydb *newp;
891 };
892
893 /*
894  * Convert the values in the security context
895  * structure `c' from the values specified
896  * in the policy `p->oldp' to the values specified
897  * in the policy `p->newp'.  Verify that the
898  * context is valid under the new policy.
899  */
900 static int convert_context(u32 key,
901                            struct context *c,
902                            void *p)
903 {
904         struct convert_context_args *args;
905         struct context oldc;
906         struct role_datum *role;
907         struct type_datum *typdatum;
908         struct user_datum *usrdatum;
909         char *s;
910         u32 len;
911         int rc;
912
913         args = p;
914
915         rc = context_cpy(&oldc, c);
916         if (rc)
917                 goto out;
918
919         rc = -EINVAL;
920
921         /* Convert the user. */
922         usrdatum = hashtab_search(args->newp->p_users.table,
923                                   args->oldp->p_user_val_to_name[c->user - 1]);
924         if (!usrdatum) {
925                 goto bad;
926         }
927         c->user = usrdatum->value;
928
929         /* Convert the role. */
930         role = hashtab_search(args->newp->p_roles.table,
931                               args->oldp->p_role_val_to_name[c->role - 1]);
932         if (!role) {
933                 goto bad;
934         }
935         c->role = role->value;
936
937         /* Convert the type. */
938         typdatum = hashtab_search(args->newp->p_types.table,
939                                   args->oldp->p_type_val_to_name[c->type - 1]);
940         if (!typdatum) {
941                 goto bad;
942         }
943         c->type = typdatum->value;
944
945         rc = mls_convert_context(args->oldp, args->newp, c);
946         if (rc)
947                 goto bad;
948
949         /* Check the validity of the new context. */
950         if (!policydb_context_isvalid(args->newp, c)) {
951                 rc = convert_context_handle_invalid_context(&oldc);
952                 if (rc)
953                         goto bad;
954         }
955
956         context_destroy(&oldc);
957 out:
958         return rc;
959 bad:
960         context_struct_to_string(&oldc, &s, &len);
961         context_destroy(&oldc);
962         printk(KERN_ERR "security:  invalidating context %s\n", s);
963         kfree(s);
964         goto out;
965 }
966
967 extern void selinux_complete_init(void);
968
969 /**
970  * security_load_policy - Load a security policy configuration.
971  * @data: binary policy data
972  * @len: length of data in bytes
973  *
974  * Load a new set of security policy configuration data,
975  * validate it and convert the SID table as necessary.
976  * This function will flush the access vector cache after
977  * loading the new policy.
978  */
979 int security_load_policy(void *data, size_t len)
980 {
981         struct policydb oldpolicydb, newpolicydb;
982         struct sidtab oldsidtab, newsidtab;
983         struct convert_context_args args;
984         u32 seqno;
985         int rc = 0;
986         struct policy_file file = { data, len }, *fp = &file;
987
988         LOAD_LOCK;
989
990         if (!ss_initialized) {
991                 if (policydb_read(&policydb, fp)) {
992                         LOAD_UNLOCK;
993                         return -EINVAL;
994                 }
995                 if (policydb_load_isids(&policydb, &sidtab)) {
996                         LOAD_UNLOCK;
997                         policydb_destroy(&policydb);
998                         return -EINVAL;
999                 }
1000                 ss_initialized = 1;
1001                 LOAD_UNLOCK;
1002                 selinux_complete_init();
1003                 return 0;
1004         }
1005
1006 #if 0
1007         sidtab_hash_eval(&sidtab, "sids");
1008 #endif
1009
1010         if (policydb_read(&newpolicydb, fp)) {
1011                 LOAD_UNLOCK;
1012                 return -EINVAL;
1013         }
1014
1015         sidtab_init(&newsidtab);
1016
1017         /* Verify that the existing classes did not change. */
1018         if (hashtab_map(policydb.p_classes.table, validate_class, &newpolicydb)) {
1019                 printk(KERN_ERR "security:  the definition of an existing "
1020                        "class changed\n");
1021                 rc = -EINVAL;
1022                 goto err;
1023         }
1024
1025         /* Clone the SID table. */
1026         sidtab_shutdown(&sidtab);
1027         if (sidtab_map(&sidtab, clone_sid, &newsidtab)) {
1028                 rc = -ENOMEM;
1029                 goto err;
1030         }
1031
1032         /* Convert the internal representations of contexts
1033            in the new SID table and remove invalid SIDs. */
1034         args.oldp = &policydb;
1035         args.newp = &newpolicydb;
1036         sidtab_map_remove_on_error(&newsidtab, convert_context, &args);
1037
1038         /* Save the old policydb and SID table to free later. */
1039         memcpy(&oldpolicydb, &policydb, sizeof policydb);
1040         sidtab_set(&oldsidtab, &sidtab);
1041
1042         /* Install the new policydb and SID table. */
1043         POLICY_WRLOCK;
1044         memcpy(&policydb, &newpolicydb, sizeof policydb);
1045         sidtab_set(&sidtab, &newsidtab);
1046         seqno = ++latest_granting;
1047         POLICY_WRUNLOCK;
1048         LOAD_UNLOCK;
1049
1050         /* Free the old policydb and SID table. */
1051         policydb_destroy(&oldpolicydb);
1052         sidtab_destroy(&oldsidtab);
1053
1054         avc_ss_reset(seqno);
1055
1056         return 0;
1057
1058 err:
1059         LOAD_UNLOCK;
1060         sidtab_destroy(&newsidtab);
1061         policydb_destroy(&newpolicydb);
1062         return rc;
1063
1064 }
1065
1066 /**
1067  * security_port_sid - Obtain the SID for a port.
1068  * @domain: communication domain aka address family
1069  * @type: socket type
1070  * @protocol: protocol number
1071  * @port: port number
1072  * @out_sid: security identifier
1073  */
1074 int security_port_sid(u16 domain,
1075                       u16 type,
1076                       u8 protocol,
1077                       u16 port,
1078                       u32 *out_sid)
1079 {
1080         struct ocontext *c;
1081         int rc = 0;
1082
1083         POLICY_RDLOCK;
1084
1085         c = policydb.ocontexts[OCON_PORT];
1086         while (c) {
1087                 if (c->u.port.protocol == protocol &&
1088                     c->u.port.low_port <= port &&
1089                     c->u.port.high_port >= port)
1090                         break;
1091                 c = c->next;
1092         }
1093
1094         if (c) {
1095                 if (!c->sid[0]) {
1096                         rc = sidtab_context_to_sid(&sidtab,
1097                                                    &c->context[0],
1098                                                    &c->sid[0]);
1099                         if (rc)
1100                                 goto out;
1101                 }
1102                 *out_sid = c->sid[0];
1103         } else {
1104                 *out_sid = SECINITSID_PORT;
1105         }
1106
1107 out:
1108         POLICY_RDUNLOCK;
1109         return rc;
1110 }
1111
1112 /**
1113  * security_netif_sid - Obtain the SID for a network interface.
1114  * @name: interface name
1115  * @if_sid: interface SID
1116  * @msg_sid: default SID for received packets
1117  */
1118 int security_netif_sid(char *name,
1119                        u32 *if_sid,
1120                        u32 *msg_sid)
1121 {
1122         int rc = 0;
1123         struct ocontext *c;
1124
1125         POLICY_RDLOCK;
1126
1127         c = policydb.ocontexts[OCON_NETIF];
1128         while (c) {
1129                 if (strcmp(name, c->u.name) == 0)
1130                         break;
1131                 c = c->next;
1132         }
1133
1134         if (c) {
1135                 if (!c->sid[0] || !c->sid[1]) {
1136                         rc = sidtab_context_to_sid(&sidtab,
1137                                                   &c->context[0],
1138                                                   &c->sid[0]);
1139                         if (rc)
1140                                 goto out;
1141                         rc = sidtab_context_to_sid(&sidtab,
1142                                                    &c->context[1],
1143                                                    &c->sid[1]);
1144                         if (rc)
1145                                 goto out;
1146                 }
1147                 *if_sid = c->sid[0];
1148                 *msg_sid = c->sid[1];
1149         } else {
1150                 *if_sid = SECINITSID_NETIF;
1151                 *msg_sid = SECINITSID_NETMSG;
1152         }
1153
1154 out:
1155         POLICY_RDUNLOCK;
1156         return rc;
1157 }
1158
1159
1160 /**
1161  * security_node_sid - Obtain the SID for a node (host).
1162  * @domain: communication domain aka address family
1163  * @addrp: address
1164  * @addrlen: address length in bytes
1165  * @out_sid: security identifier
1166  */
1167 int security_node_sid(u16 domain,
1168                       void *addrp,
1169                       u32 addrlen,
1170                       u32 *out_sid)
1171 {
1172         int rc = 0;
1173         u32 addr;
1174         struct ocontext *c;
1175
1176         POLICY_RDLOCK;
1177
1178         if (domain != AF_INET || addrlen != sizeof(u32)) {
1179                 *out_sid = SECINITSID_NODE;
1180                 goto out;
1181         }
1182         addr = *((u32 *)addrp);
1183
1184         c = policydb.ocontexts[OCON_NODE];
1185         while (c) {
1186                 if (c->u.node.addr == (addr & c->u.node.mask))
1187                         break;
1188                 c = c->next;
1189         }
1190
1191         if (c) {
1192                 if (!c->sid[0]) {
1193                         rc = sidtab_context_to_sid(&sidtab,
1194                                                    &c->context[0],
1195                                                    &c->sid[0]);
1196                         if (rc)
1197                                 goto out;
1198                 }
1199                 *out_sid = c->sid[0];
1200         } else {
1201                 *out_sid = SECINITSID_NODE;
1202         }
1203
1204 out:
1205         POLICY_RDUNLOCK;
1206         return rc;
1207 }
1208
1209 #define SIDS_NEL 25
1210
1211 /**
1212  * security_get_user_sids - Obtain reachable SIDs for a user.
1213  * @fromsid: starting SID
1214  * @username: username
1215  * @sids: array of reachable SIDs for user
1216  * @nel: number of elements in @sids
1217  *
1218  * Generate the set of SIDs for legal security contexts
1219  * for a given user that can be reached by @fromsid.
1220  * Set *@sids to point to a dynamically allocated
1221  * array containing the set of SIDs.  Set *@nel to the
1222  * number of elements in the array.
1223  */
1224
1225 int security_get_user_sids(u32 fromsid,
1226                            char *username,
1227                            u32 **sids,
1228                            u32 *nel)
1229 {
1230         struct context *fromcon, usercon;
1231         u32 *mysids, *mysids2, sid;
1232         u32 mynel = 0, maxnel = SIDS_NEL;
1233         struct user_datum *user;
1234         struct role_datum *role;
1235         struct av_decision avd;
1236         int rc = 0, i, j;
1237
1238         if (!ss_initialized) {
1239                 *sids = NULL;
1240                 *nel = 0;
1241                 goto out;
1242         }
1243
1244         POLICY_RDLOCK;
1245
1246         fromcon = sidtab_search(&sidtab, fromsid);
1247         if (!fromcon) {
1248                 rc = -EINVAL;
1249                 goto out_unlock;
1250         }
1251
1252         user = hashtab_search(policydb.p_users.table, username);
1253         if (!user) {
1254                 rc = -EINVAL;
1255                 goto out_unlock;
1256         }
1257         usercon.user = user->value;
1258
1259         mysids = kmalloc(maxnel*sizeof(*mysids), GFP_ATOMIC);
1260         if (!mysids) {
1261                 rc = -ENOMEM;
1262                 goto out_unlock;
1263         }
1264         memset(mysids, 0, maxnel*sizeof(*mysids));
1265
1266         for (i = ebitmap_startbit(&user->roles); i < ebitmap_length(&user->roles); i++) {
1267                 if (!ebitmap_get_bit(&user->roles, i))
1268                         continue;
1269                 role = policydb.role_val_to_struct[i];
1270                 usercon.role = i+1;
1271                 for (j = ebitmap_startbit(&role->types); j < ebitmap_length(&role->types); j++) {
1272                         if (!ebitmap_get_bit(&role->types, j))
1273                                 continue;
1274                         usercon.type = j+1;
1275                         if (usercon.type == fromcon->type)
1276                                 continue;
1277                         mls_for_user_ranges(user,usercon) {
1278                                 rc = context_struct_compute_av(fromcon, &usercon,
1279                                                                SECCLASS_PROCESS,
1280                                                                PROCESS__TRANSITION,
1281                                                                &avd);
1282                                 if (rc ||  !(avd.allowed & PROCESS__TRANSITION))
1283                                         continue;
1284                                 rc = sidtab_context_to_sid(&sidtab, &usercon, &sid);
1285                                 if (rc) {
1286                                         kfree(mysids);
1287                                         goto out_unlock;
1288                                 }
1289                                 if (mynel < maxnel) {
1290                                         mysids[mynel++] = sid;
1291                                 } else {
1292                                         maxnel += SIDS_NEL;
1293                                         mysids2 = kmalloc(maxnel*sizeof(*mysids2), GFP_ATOMIC);
1294                                         if (!mysids2) {
1295                                                 rc = -ENOMEM;
1296                                                 kfree(mysids);
1297                                                 goto out_unlock;
1298                                         }
1299                                         memset(mysids2, 0, maxnel*sizeof(*mysids2));
1300                                         memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
1301                                         kfree(mysids);
1302                                         mysids = mysids2;
1303                                         mysids[mynel++] = sid;
1304                                 }
1305                         }
1306                         mls_end_user_ranges;
1307                 }
1308         }
1309
1310         *sids = mysids;
1311         *nel = mynel;
1312
1313 out_unlock:
1314         POLICY_RDUNLOCK;
1315 out:
1316         return rc;
1317 }
1318
1319 /**
1320  * security_genfs_sid - Obtain a SID for a file in a filesystem
1321  * @fstype: filesystem type
1322  * @path: path from root of mount
1323  * @sclass: file security class
1324  * @sid: SID for path
1325  *
1326  * Obtain a SID to use for a file in a filesystem that
1327  * cannot support xattr or use a fixed labeling behavior like
1328  * transition SIDs or task SIDs.
1329  */
1330 int security_genfs_sid(const char *fstype,
1331                        char *path,
1332                        u16 sclass,
1333                        u32 *sid)
1334 {
1335         int len;
1336         struct genfs *genfs;
1337         struct ocontext *c;
1338         int rc = 0, cmp = 0;
1339
1340         POLICY_RDLOCK;
1341
1342         for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
1343                 cmp = strcmp(fstype, genfs->fstype);
1344                 if (cmp <= 0)
1345                         break;
1346         }
1347
1348         if (!genfs || cmp) {
1349                 *sid = SECINITSID_UNLABELED;
1350                 rc = -ENOENT;
1351                 goto out;
1352         }
1353
1354         for (c = genfs->head; c; c = c->next) {
1355                 len = strlen(c->u.name);
1356                 if ((!c->v.sclass || sclass == c->v.sclass) &&
1357                     (strncmp(c->u.name, path, len) == 0))
1358                         break;
1359         }
1360
1361         if (!c) {
1362                 *sid = SECINITSID_UNLABELED;
1363                 rc = -ENOENT;
1364                 goto out;
1365         }
1366
1367         if (!c->sid[0]) {
1368                 rc = sidtab_context_to_sid(&sidtab,
1369                                            &c->context[0],
1370                                            &c->sid[0]);
1371                 if (rc)
1372                         goto out;
1373         }
1374
1375         *sid = c->sid[0];
1376 out:
1377         POLICY_RDUNLOCK;
1378         return rc;
1379 }
1380
1381 /**
1382  * security_fs_use - Determine how to handle labeling for a filesystem.
1383  * @fstype: filesystem type
1384  * @behavior: labeling behavior
1385  * @sid: SID for filesystem (superblock)
1386  */
1387 int security_fs_use(
1388         const char *fstype,
1389         unsigned int *behavior,
1390         u32 *sid)
1391 {
1392         int rc = 0;
1393         struct ocontext *c;
1394
1395         POLICY_RDLOCK;
1396
1397         c = policydb.ocontexts[OCON_FSUSE];
1398         while (c) {
1399                 if (strcmp(fstype, c->u.name) == 0)
1400                         break;
1401                 c = c->next;
1402         }
1403
1404         if (c) {
1405                 *behavior = c->v.behavior;
1406                 if (!c->sid[0]) {
1407                         rc = sidtab_context_to_sid(&sidtab,
1408                                                    &c->context[0],
1409                                                    &c->sid[0]);
1410                         if (rc)
1411                                 goto out;
1412                 }
1413                 *sid = c->sid[0];
1414         } else {
1415                 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
1416                 if (rc) {
1417                         *behavior = SECURITY_FS_USE_NONE;
1418                         rc = 0;
1419                 } else {
1420                         *behavior = SECURITY_FS_USE_GENFS;
1421                 }
1422         }
1423
1424 out:
1425         POLICY_RDUNLOCK;
1426         return rc;
1427 }