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