Merge git://git.infradead.org/battery-2.6
[pandora-kernel.git] / security / selinux / selinuxfs.c
1 /* Updated: Karl MacMillan <kmacmillan@tresys.com>
2  *
3  *      Added conditional policy language extensions
4  *
5  * Copyright (C) 2003 - 2004 Tresys Technology, LLC
6  * Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
7  *      This program is free software; you can redistribute it and/or modify
8  *      it under the terms of the GNU General Public License as published by
9  *      the Free Software Foundation, version 2.
10  */
11
12 #include <linux/kernel.h>
13 #include <linux/pagemap.h>
14 #include <linux/slab.h>
15 #include <linux/vmalloc.h>
16 #include <linux/fs.h>
17 #include <linux/mutex.h>
18 #include <linux/init.h>
19 #include <linux/string.h>
20 #include <linux/security.h>
21 #include <linux/major.h>
22 #include <linux/seq_file.h>
23 #include <linux/percpu.h>
24 #include <linux/audit.h>
25 #include <asm/uaccess.h>
26 #include <asm/semaphore.h>
27
28 /* selinuxfs pseudo filesystem for exporting the security policy API.
29    Based on the proc code and the fs/nfsd/nfsctl.c code. */
30
31 #include "flask.h"
32 #include "avc.h"
33 #include "avc_ss.h"
34 #include "security.h"
35 #include "objsec.h"
36 #include "conditional.h"
37
38 unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
39
40 #ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
41 #define SELINUX_COMPAT_NET_VALUE 0
42 #else
43 #define SELINUX_COMPAT_NET_VALUE 1
44 #endif
45
46 int selinux_compat_net = SELINUX_COMPAT_NET_VALUE;
47
48 static int __init checkreqprot_setup(char *str)
49 {
50         selinux_checkreqprot = simple_strtoul(str,NULL,0) ? 1 : 0;
51         return 1;
52 }
53 __setup("checkreqprot=", checkreqprot_setup);
54
55 static int __init selinux_compat_net_setup(char *str)
56 {
57         selinux_compat_net = simple_strtoul(str,NULL,0) ? 1 : 0;
58         return 1;
59 }
60 __setup("selinux_compat_net=", selinux_compat_net_setup);
61
62
63 static DEFINE_MUTEX(sel_mutex);
64
65 /* global data for booleans */
66 static struct dentry *bool_dir = NULL;
67 static int bool_num = 0;
68 static int *bool_pending_values = NULL;
69
70 /* global data for classes */
71 static struct dentry *class_dir = NULL;
72 static unsigned long last_class_ino;
73
74 extern void selnl_notify_setenforce(int val);
75
76 /* Check whether a task is allowed to use a security operation. */
77 static int task_has_security(struct task_struct *tsk,
78                              u32 perms)
79 {
80         struct task_security_struct *tsec;
81
82         tsec = tsk->security;
83         if (!tsec)
84                 return -EACCES;
85
86         return avc_has_perm(tsec->sid, SECINITSID_SECURITY,
87                             SECCLASS_SECURITY, perms, NULL);
88 }
89
90 enum sel_inos {
91         SEL_ROOT_INO = 2,
92         SEL_LOAD,       /* load policy */
93         SEL_ENFORCE,    /* get or set enforcing status */
94         SEL_CONTEXT,    /* validate context */
95         SEL_ACCESS,     /* compute access decision */
96         SEL_CREATE,     /* compute create labeling decision */
97         SEL_RELABEL,    /* compute relabeling decision */
98         SEL_USER,       /* compute reachable user contexts */
99         SEL_POLICYVERS, /* return policy version for this kernel */
100         SEL_COMMIT_BOOLS, /* commit new boolean values */
101         SEL_MLS,        /* return if MLS policy is enabled */
102         SEL_DISABLE,    /* disable SELinux until next reboot */
103         SEL_MEMBER,     /* compute polyinstantiation membership decision */
104         SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */
105         SEL_COMPAT_NET, /* whether to use old compat network packet controls */
106         SEL_REJECT_UNKNOWN, /* export unknown reject handling to userspace */
107         SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */
108         SEL_INO_NEXT,   /* The next inode number to use */
109 };
110
111 static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
112
113 #define SEL_INITCON_INO_OFFSET  0x01000000
114 #define SEL_BOOL_INO_OFFSET     0x02000000
115 #define SEL_CLASS_INO_OFFSET    0x04000000
116 #define SEL_INO_MASK            0x00ffffff
117
118 #define TMPBUFLEN       12
119 static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
120                                 size_t count, loff_t *ppos)
121 {
122         char tmpbuf[TMPBUFLEN];
123         ssize_t length;
124
125         length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_enforcing);
126         return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
127 }
128
129 #ifdef CONFIG_SECURITY_SELINUX_DEVELOP
130 static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
131                                  size_t count, loff_t *ppos)
132
133 {
134         char *page;
135         ssize_t length;
136         int new_value;
137
138         if (count >= PAGE_SIZE)
139                 return -ENOMEM;
140         if (*ppos != 0) {
141                 /* No partial writes. */
142                 return -EINVAL;
143         }
144         page = (char*)get_zeroed_page(GFP_KERNEL);
145         if (!page)
146                 return -ENOMEM;
147         length = -EFAULT;
148         if (copy_from_user(page, buf, count))
149                 goto out;
150
151         length = -EINVAL;
152         if (sscanf(page, "%d", &new_value) != 1)
153                 goto out;
154
155         if (new_value != selinux_enforcing) {
156                 length = task_has_security(current, SECURITY__SETENFORCE);
157                 if (length)
158                         goto out;
159                 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
160                         "enforcing=%d old_enforcing=%d auid=%u", new_value, 
161                         selinux_enforcing,
162                         audit_get_loginuid(current->audit_context));
163                 selinux_enforcing = new_value;
164                 if (selinux_enforcing)
165                         avc_ss_reset(0);
166                 selnl_notify_setenforce(selinux_enforcing);
167         }
168         length = count;
169 out:
170         free_page((unsigned long) page);
171         return length;
172 }
173 #else
174 #define sel_write_enforce NULL
175 #endif
176
177 static const struct file_operations sel_enforce_ops = {
178         .read           = sel_read_enforce,
179         .write          = sel_write_enforce,
180 };
181
182 static ssize_t sel_read_handle_unknown(struct file *filp, char __user *buf,
183                                         size_t count, loff_t *ppos)
184 {
185         char tmpbuf[TMPBUFLEN];
186         ssize_t length;
187         ino_t ino = filp->f_path.dentry->d_inode->i_ino;
188         int handle_unknown = (ino == SEL_REJECT_UNKNOWN) ?
189                 security_get_reject_unknown() : !security_get_allow_unknown();
190
191         length = scnprintf(tmpbuf, TMPBUFLEN, "%d", handle_unknown);
192         return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
193 }
194
195 static const struct file_operations sel_handle_unknown_ops = {
196         .read           = sel_read_handle_unknown,
197 };
198
199 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
200 static ssize_t sel_write_disable(struct file * file, const char __user * buf,
201                                  size_t count, loff_t *ppos)
202
203 {
204         char *page;
205         ssize_t length;
206         int new_value;
207         extern int selinux_disable(void);
208
209         if (count >= PAGE_SIZE)
210                 return -ENOMEM;
211         if (*ppos != 0) {
212                 /* No partial writes. */
213                 return -EINVAL;
214         }
215         page = (char*)get_zeroed_page(GFP_KERNEL);
216         if (!page)
217                 return -ENOMEM;
218         length = -EFAULT;
219         if (copy_from_user(page, buf, count))
220                 goto out;
221
222         length = -EINVAL;
223         if (sscanf(page, "%d", &new_value) != 1)
224                 goto out;
225
226         if (new_value) {
227                 length = selinux_disable();
228                 if (length < 0)
229                         goto out;
230                 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
231                         "selinux=0 auid=%u",
232                         audit_get_loginuid(current->audit_context));
233         }
234
235         length = count;
236 out:
237         free_page((unsigned long) page);
238         return length;
239 }
240 #else
241 #define sel_write_disable NULL
242 #endif
243
244 static const struct file_operations sel_disable_ops = {
245         .write          = sel_write_disable,
246 };
247
248 static ssize_t sel_read_policyvers(struct file *filp, char __user *buf,
249                                    size_t count, loff_t *ppos)
250 {
251         char tmpbuf[TMPBUFLEN];
252         ssize_t length;
253
254         length = scnprintf(tmpbuf, TMPBUFLEN, "%u", POLICYDB_VERSION_MAX);
255         return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
256 }
257
258 static const struct file_operations sel_policyvers_ops = {
259         .read           = sel_read_policyvers,
260 };
261
262 /* declaration for sel_write_load */
263 static int sel_make_bools(void);
264 static int sel_make_classes(void);
265
266 /* declaration for sel_make_class_dirs */
267 static int sel_make_dir(struct inode *dir, struct dentry *dentry,
268                         unsigned long *ino);
269
270 static ssize_t sel_read_mls(struct file *filp, char __user *buf,
271                                 size_t count, loff_t *ppos)
272 {
273         char tmpbuf[TMPBUFLEN];
274         ssize_t length;
275
276         length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
277         return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
278 }
279
280 static const struct file_operations sel_mls_ops = {
281         .read           = sel_read_mls,
282 };
283
284 static ssize_t sel_write_load(struct file * file, const char __user * buf,
285                               size_t count, loff_t *ppos)
286
287 {
288         int ret;
289         ssize_t length;
290         void *data = NULL;
291
292         mutex_lock(&sel_mutex);
293
294         length = task_has_security(current, SECURITY__LOAD_POLICY);
295         if (length)
296                 goto out;
297
298         if (*ppos != 0) {
299                 /* No partial writes. */
300                 length = -EINVAL;
301                 goto out;
302         }
303
304         if ((count > 64 * 1024 * 1024)
305             || (data = vmalloc(count)) == NULL) {
306                 length = -ENOMEM;
307                 goto out;
308         }
309
310         length = -EFAULT;
311         if (copy_from_user(data, buf, count) != 0)
312                 goto out;
313
314         length = security_load_policy(data, count);
315         if (length)
316                 goto out;
317
318         ret = sel_make_bools();
319         if (ret) {
320                 length = ret;
321                 goto out1;
322         }
323
324         ret = sel_make_classes();
325         if (ret)
326                 length = ret;
327         else
328                 length = count;
329
330 out1:
331
332         printk(KERN_INFO "SELinux: policy loaded with handle_unknown=%s\n",
333                (security_get_reject_unknown() ? "reject" :
334                 (security_get_allow_unknown() ? "allow" : "deny")));
335
336         audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
337                 "policy loaded auid=%u",
338                 audit_get_loginuid(current->audit_context));
339 out:
340         mutex_unlock(&sel_mutex);
341         vfree(data);
342         return length;
343 }
344
345 static const struct file_operations sel_load_ops = {
346         .write          = sel_write_load,
347 };
348
349 static ssize_t sel_write_context(struct file * file, char *buf, size_t size)
350 {
351         char *canon;
352         u32 sid, len;
353         ssize_t length;
354
355         length = task_has_security(current, SECURITY__CHECK_CONTEXT);
356         if (length)
357                 return length;
358
359         length = security_context_to_sid(buf, size, &sid);
360         if (length < 0)
361                 return length;
362
363         length = security_sid_to_context(sid, &canon, &len);
364         if (length < 0)
365                 return length;
366
367         if (len > SIMPLE_TRANSACTION_LIMIT) {
368                 printk(KERN_ERR "%s:  context size (%u) exceeds payload "
369                        "max\n", __FUNCTION__, len);
370                 length = -ERANGE;
371                 goto out;
372         }
373
374         memcpy(buf, canon, len);
375         length = len;
376 out:
377         kfree(canon);
378         return length;
379 }
380
381 static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
382                                      size_t count, loff_t *ppos)
383 {
384         char tmpbuf[TMPBUFLEN];
385         ssize_t length;
386
387         length = scnprintf(tmpbuf, TMPBUFLEN, "%u", selinux_checkreqprot);
388         return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
389 }
390
391 static ssize_t sel_write_checkreqprot(struct file * file, const char __user * buf,
392                                       size_t count, loff_t *ppos)
393 {
394         char *page;
395         ssize_t length;
396         unsigned int new_value;
397
398         length = task_has_security(current, SECURITY__SETCHECKREQPROT);
399         if (length)
400                 return length;
401
402         if (count >= PAGE_SIZE)
403                 return -ENOMEM;
404         if (*ppos != 0) {
405                 /* No partial writes. */
406                 return -EINVAL;
407         }
408         page = (char*)get_zeroed_page(GFP_KERNEL);
409         if (!page)
410                 return -ENOMEM;
411         length = -EFAULT;
412         if (copy_from_user(page, buf, count))
413                 goto out;
414
415         length = -EINVAL;
416         if (sscanf(page, "%u", &new_value) != 1)
417                 goto out;
418
419         selinux_checkreqprot = new_value ? 1 : 0;
420         length = count;
421 out:
422         free_page((unsigned long) page);
423         return length;
424 }
425 static const struct file_operations sel_checkreqprot_ops = {
426         .read           = sel_read_checkreqprot,
427         .write          = sel_write_checkreqprot,
428 };
429
430 static ssize_t sel_read_compat_net(struct file *filp, char __user *buf,
431                                    size_t count, loff_t *ppos)
432 {
433         char tmpbuf[TMPBUFLEN];
434         ssize_t length;
435
436         length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_compat_net);
437         return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
438 }
439
440 static ssize_t sel_write_compat_net(struct file * file, const char __user * buf,
441                                     size_t count, loff_t *ppos)
442 {
443         char *page;
444         ssize_t length;
445         int new_value;
446
447         length = task_has_security(current, SECURITY__LOAD_POLICY);
448         if (length)
449                 return length;
450
451         if (count >= PAGE_SIZE)
452                 return -ENOMEM;
453         if (*ppos != 0) {
454                 /* No partial writes. */
455                 return -EINVAL;
456         }
457         page = (char*)get_zeroed_page(GFP_KERNEL);
458         if (!page)
459                 return -ENOMEM;
460         length = -EFAULT;
461         if (copy_from_user(page, buf, count))
462                 goto out;
463
464         length = -EINVAL;
465         if (sscanf(page, "%d", &new_value) != 1)
466                 goto out;
467
468         selinux_compat_net = new_value ? 1 : 0;
469         length = count;
470 out:
471         free_page((unsigned long) page);
472         return length;
473 }
474 static const struct file_operations sel_compat_net_ops = {
475         .read           = sel_read_compat_net,
476         .write          = sel_write_compat_net,
477 };
478
479 /*
480  * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
481  */
482 static ssize_t sel_write_access(struct file * file, char *buf, size_t size);
483 static ssize_t sel_write_create(struct file * file, char *buf, size_t size);
484 static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size);
485 static ssize_t sel_write_user(struct file * file, char *buf, size_t size);
486 static ssize_t sel_write_member(struct file * file, char *buf, size_t size);
487
488 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
489         [SEL_ACCESS] = sel_write_access,
490         [SEL_CREATE] = sel_write_create,
491         [SEL_RELABEL] = sel_write_relabel,
492         [SEL_USER] = sel_write_user,
493         [SEL_MEMBER] = sel_write_member,
494         [SEL_CONTEXT] = sel_write_context,
495 };
496
497 static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
498 {
499         ino_t ino =  file->f_path.dentry->d_inode->i_ino;
500         char *data;
501         ssize_t rv;
502
503         if (ino >= ARRAY_SIZE(write_op) || !write_op[ino])
504                 return -EINVAL;
505
506         data = simple_transaction_get(file, buf, size);
507         if (IS_ERR(data))
508                 return PTR_ERR(data);
509
510         rv =  write_op[ino](file, data, size);
511         if (rv>0) {
512                 simple_transaction_set(file, rv);
513                 rv = size;
514         }
515         return rv;
516 }
517
518 static const struct file_operations transaction_ops = {
519         .write          = selinux_transaction_write,
520         .read           = simple_transaction_read,
521         .release        = simple_transaction_release,
522 };
523
524 /*
525  * payload - write methods
526  * If the method has a response, the response should be put in buf,
527  * and the length returned.  Otherwise return 0 or and -error.
528  */
529
530 static ssize_t sel_write_access(struct file * file, char *buf, size_t size)
531 {
532         char *scon, *tcon;
533         u32 ssid, tsid;
534         u16 tclass;
535         u32 req;
536         struct av_decision avd;
537         ssize_t length;
538
539         length = task_has_security(current, SECURITY__COMPUTE_AV);
540         if (length)
541                 return length;
542
543         length = -ENOMEM;
544         scon = kzalloc(size+1, GFP_KERNEL);
545         if (!scon)
546                 return length;
547
548         tcon = kzalloc(size+1, GFP_KERNEL);
549         if (!tcon)
550                 goto out;
551
552         length = -EINVAL;
553         if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4)
554                 goto out2;
555
556         length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
557         if (length < 0)
558                 goto out2;
559         length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
560         if (length < 0)
561                 goto out2;
562
563         length = security_compute_av(ssid, tsid, tclass, req, &avd);
564         if (length < 0)
565                 goto out2;
566
567         length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
568                           "%x %x %x %x %u",
569                           avd.allowed, avd.decided,
570                           avd.auditallow, avd.auditdeny,
571                           avd.seqno);
572 out2:
573         kfree(tcon);
574 out:
575         kfree(scon);
576         return length;
577 }
578
579 static ssize_t sel_write_create(struct file * file, char *buf, size_t size)
580 {
581         char *scon, *tcon;
582         u32 ssid, tsid, newsid;
583         u16 tclass;
584         ssize_t length;
585         char *newcon;
586         u32 len;
587
588         length = task_has_security(current, SECURITY__COMPUTE_CREATE);
589         if (length)
590                 return length;
591
592         length = -ENOMEM;
593         scon = kzalloc(size+1, GFP_KERNEL);
594         if (!scon)
595                 return length;
596
597         tcon = kzalloc(size+1, GFP_KERNEL);
598         if (!tcon)
599                 goto out;
600
601         length = -EINVAL;
602         if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
603                 goto out2;
604
605         length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
606         if (length < 0)
607                 goto out2;
608         length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
609         if (length < 0)
610                 goto out2;
611
612         length = security_transition_sid(ssid, tsid, tclass, &newsid);
613         if (length < 0)
614                 goto out2;
615
616         length = security_sid_to_context(newsid, &newcon, &len);
617         if (length < 0)
618                 goto out2;
619
620         if (len > SIMPLE_TRANSACTION_LIMIT) {
621                 printk(KERN_ERR "%s:  context size (%u) exceeds payload "
622                        "max\n", __FUNCTION__, len);
623                 length = -ERANGE;
624                 goto out3;
625         }
626
627         memcpy(buf, newcon, len);
628         length = len;
629 out3:
630         kfree(newcon);
631 out2:
632         kfree(tcon);
633 out:
634         kfree(scon);
635         return length;
636 }
637
638 static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size)
639 {
640         char *scon, *tcon;
641         u32 ssid, tsid, newsid;
642         u16 tclass;
643         ssize_t length;
644         char *newcon;
645         u32 len;
646
647         length = task_has_security(current, SECURITY__COMPUTE_RELABEL);
648         if (length)
649                 return length;
650
651         length = -ENOMEM;
652         scon = kzalloc(size+1, GFP_KERNEL);
653         if (!scon)
654                 return length;
655
656         tcon = kzalloc(size+1, GFP_KERNEL);
657         if (!tcon)
658                 goto out;
659
660         length = -EINVAL;
661         if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
662                 goto out2;
663
664         length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
665         if (length < 0)
666                 goto out2;
667         length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
668         if (length < 0)
669                 goto out2;
670
671         length = security_change_sid(ssid, tsid, tclass, &newsid);
672         if (length < 0)
673                 goto out2;
674
675         length = security_sid_to_context(newsid, &newcon, &len);
676         if (length < 0)
677                 goto out2;
678
679         if (len > SIMPLE_TRANSACTION_LIMIT) {
680                 length = -ERANGE;
681                 goto out3;
682         }
683
684         memcpy(buf, newcon, len);
685         length = len;
686 out3:
687         kfree(newcon);
688 out2:
689         kfree(tcon);
690 out:
691         kfree(scon);
692         return length;
693 }
694
695 static ssize_t sel_write_user(struct file * file, char *buf, size_t size)
696 {
697         char *con, *user, *ptr;
698         u32 sid, *sids;
699         ssize_t length;
700         char *newcon;
701         int i, rc;
702         u32 len, nsids;
703
704         length = task_has_security(current, SECURITY__COMPUTE_USER);
705         if (length)
706                 return length;
707
708         length = -ENOMEM;
709         con = kzalloc(size+1, GFP_KERNEL);
710         if (!con)
711                 return length;
712
713         user = kzalloc(size+1, GFP_KERNEL);
714         if (!user)
715                 goto out;
716
717         length = -EINVAL;
718         if (sscanf(buf, "%s %s", con, user) != 2)
719                 goto out2;
720
721         length = security_context_to_sid(con, strlen(con)+1, &sid);
722         if (length < 0)
723                 goto out2;
724
725         length = security_get_user_sids(sid, user, &sids, &nsids);
726         if (length < 0)
727                 goto out2;
728
729         length = sprintf(buf, "%u", nsids) + 1;
730         ptr = buf + length;
731         for (i = 0; i < nsids; i++) {
732                 rc = security_sid_to_context(sids[i], &newcon, &len);
733                 if (rc) {
734                         length = rc;
735                         goto out3;
736                 }
737                 if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) {
738                         kfree(newcon);
739                         length = -ERANGE;
740                         goto out3;
741                 }
742                 memcpy(ptr, newcon, len);
743                 kfree(newcon);
744                 ptr += len;
745                 length += len;
746         }
747 out3:
748         kfree(sids);
749 out2:
750         kfree(user);
751 out:
752         kfree(con);
753         return length;
754 }
755
756 static ssize_t sel_write_member(struct file * file, char *buf, size_t size)
757 {
758         char *scon, *tcon;
759         u32 ssid, tsid, newsid;
760         u16 tclass;
761         ssize_t length;
762         char *newcon;
763         u32 len;
764
765         length = task_has_security(current, SECURITY__COMPUTE_MEMBER);
766         if (length)
767                 return length;
768
769         length = -ENOMEM;
770         scon = kzalloc(size+1, GFP_KERNEL);
771         if (!scon)
772                 return length;
773
774         tcon = kzalloc(size+1, GFP_KERNEL);
775         if (!tcon)
776                 goto out;
777
778         length = -EINVAL;
779         if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
780                 goto out2;
781
782         length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
783         if (length < 0)
784                 goto out2;
785         length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
786         if (length < 0)
787                 goto out2;
788
789         length = security_member_sid(ssid, tsid, tclass, &newsid);
790         if (length < 0)
791                 goto out2;
792
793         length = security_sid_to_context(newsid, &newcon, &len);
794         if (length < 0)
795                 goto out2;
796
797         if (len > SIMPLE_TRANSACTION_LIMIT) {
798                 printk(KERN_ERR "%s:  context size (%u) exceeds payload "
799                        "max\n", __FUNCTION__, len);
800                 length = -ERANGE;
801                 goto out3;
802         }
803
804         memcpy(buf, newcon, len);
805         length = len;
806 out3:
807         kfree(newcon);
808 out2:
809         kfree(tcon);
810 out:
811         kfree(scon);
812         return length;
813 }
814
815 static struct inode *sel_make_inode(struct super_block *sb, int mode)
816 {
817         struct inode *ret = new_inode(sb);
818
819         if (ret) {
820                 ret->i_mode = mode;
821                 ret->i_uid = ret->i_gid = 0;
822                 ret->i_blocks = 0;
823                 ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
824         }
825         return ret;
826 }
827
828 static ssize_t sel_read_bool(struct file *filep, char __user *buf,
829                              size_t count, loff_t *ppos)
830 {
831         char *page = NULL;
832         ssize_t length;
833         ssize_t ret;
834         int cur_enforcing;
835         struct inode *inode;
836
837         mutex_lock(&sel_mutex);
838
839         ret = -EFAULT;
840
841         /* check to see if this file has been deleted */
842         if (!filep->f_op)
843                 goto out;
844
845         if (count > PAGE_SIZE) {
846                 ret = -EINVAL;
847                 goto out;
848         }
849         if (!(page = (char*)get_zeroed_page(GFP_KERNEL))) {
850                 ret = -ENOMEM;
851                 goto out;
852         }
853
854         inode = filep->f_path.dentry->d_inode;
855         cur_enforcing = security_get_bool_value(inode->i_ino&SEL_INO_MASK);
856         if (cur_enforcing < 0) {
857                 ret = cur_enforcing;
858                 goto out;
859         }
860
861         length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
862                           bool_pending_values[inode->i_ino&SEL_INO_MASK]);
863         ret = simple_read_from_buffer(buf, count, ppos, page, length);
864 out:
865         mutex_unlock(&sel_mutex);
866         if (page)
867                 free_page((unsigned long)page);
868         return ret;
869 }
870
871 static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
872                               size_t count, loff_t *ppos)
873 {
874         char *page = NULL;
875         ssize_t length = -EFAULT;
876         int new_value;
877         struct inode *inode;
878
879         mutex_lock(&sel_mutex);
880
881         length = task_has_security(current, SECURITY__SETBOOL);
882         if (length)
883                 goto out;
884
885         /* check to see if this file has been deleted */
886         if (!filep->f_op)
887                 goto out;
888
889         if (count >= PAGE_SIZE) {
890                 length = -ENOMEM;
891                 goto out;
892         }
893         if (*ppos != 0) {
894                 /* No partial writes. */
895                 goto out;
896         }
897         page = (char*)get_zeroed_page(GFP_KERNEL);
898         if (!page) {
899                 length = -ENOMEM;
900                 goto out;
901         }
902
903         if (copy_from_user(page, buf, count))
904                 goto out;
905
906         length = -EINVAL;
907         if (sscanf(page, "%d", &new_value) != 1)
908                 goto out;
909
910         if (new_value)
911                 new_value = 1;
912
913         inode = filep->f_path.dentry->d_inode;
914         bool_pending_values[inode->i_ino&SEL_INO_MASK] = new_value;
915         length = count;
916
917 out:
918         mutex_unlock(&sel_mutex);
919         if (page)
920                 free_page((unsigned long) page);
921         return length;
922 }
923
924 static const struct file_operations sel_bool_ops = {
925         .read           = sel_read_bool,
926         .write          = sel_write_bool,
927 };
928
929 static ssize_t sel_commit_bools_write(struct file *filep,
930                                       const char __user *buf,
931                                       size_t count, loff_t *ppos)
932 {
933         char *page = NULL;
934         ssize_t length = -EFAULT;
935         int new_value;
936
937         mutex_lock(&sel_mutex);
938
939         length = task_has_security(current, SECURITY__SETBOOL);
940         if (length)
941                 goto out;
942
943         /* check to see if this file has been deleted */
944         if (!filep->f_op)
945                 goto out;
946
947         if (count >= PAGE_SIZE) {
948                 length = -ENOMEM;
949                 goto out;
950         }
951         if (*ppos != 0) {
952                 /* No partial writes. */
953                 goto out;
954         }
955         page = (char*)get_zeroed_page(GFP_KERNEL);
956         if (!page) {
957                 length = -ENOMEM;
958                 goto out;
959         }
960
961         if (copy_from_user(page, buf, count))
962                 goto out;
963
964         length = -EINVAL;
965         if (sscanf(page, "%d", &new_value) != 1)
966                 goto out;
967
968         if (new_value && bool_pending_values) {
969                 security_set_bools(bool_num, bool_pending_values);
970         }
971
972         length = count;
973
974 out:
975         mutex_unlock(&sel_mutex);
976         if (page)
977                 free_page((unsigned long) page);
978         return length;
979 }
980
981 static const struct file_operations sel_commit_bools_ops = {
982         .write          = sel_commit_bools_write,
983 };
984
985 /* partial revoke() from fs/proc/generic.c proc_kill_inodes */
986 static void sel_remove_entries(struct dentry *de)
987 {
988         struct list_head *p, *node;
989         struct super_block *sb = de->d_sb;
990
991         spin_lock(&dcache_lock);
992         node = de->d_subdirs.next;
993         while (node != &de->d_subdirs) {
994                 struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
995                 list_del_init(node);
996
997                 if (d->d_inode) {
998                         d = dget_locked(d);
999                         spin_unlock(&dcache_lock);
1000                         d_delete(d);
1001                         simple_unlink(de->d_inode, d);
1002                         dput(d);
1003                         spin_lock(&dcache_lock);
1004                 }
1005                 node = de->d_subdirs.next;
1006         }
1007
1008         spin_unlock(&dcache_lock);
1009
1010         file_list_lock();
1011         list_for_each(p, &sb->s_files) {
1012                 struct file * filp = list_entry(p, struct file, f_u.fu_list);
1013                 struct dentry * dentry = filp->f_path.dentry;
1014
1015                 if (dentry->d_parent != de) {
1016                         continue;
1017                 }
1018                 filp->f_op = NULL;
1019         }
1020         file_list_unlock();
1021 }
1022
1023 #define BOOL_DIR_NAME "booleans"
1024
1025 static int sel_make_bools(void)
1026 {
1027         int i, ret = 0;
1028         ssize_t len;
1029         struct dentry *dentry = NULL;
1030         struct dentry *dir = bool_dir;
1031         struct inode *inode = NULL;
1032         struct inode_security_struct *isec;
1033         char **names = NULL, *page;
1034         int num;
1035         int *values = NULL;
1036         u32 sid;
1037
1038         /* remove any existing files */
1039         kfree(bool_pending_values);
1040         bool_pending_values = NULL;
1041
1042         sel_remove_entries(dir);
1043
1044         if (!(page = (char*)get_zeroed_page(GFP_KERNEL)))
1045                 return -ENOMEM;
1046
1047         ret = security_get_bools(&num, &names, &values);
1048         if (ret != 0)
1049                 goto out;
1050
1051         for (i = 0; i < num; i++) {
1052                 dentry = d_alloc_name(dir, names[i]);
1053                 if (!dentry) {
1054                         ret = -ENOMEM;
1055                         goto err;
1056                 }
1057                 inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
1058                 if (!inode) {
1059                         ret = -ENOMEM;
1060                         goto err;
1061                 }
1062
1063                 len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
1064                 if (len < 0) {
1065                         ret = -EINVAL;
1066                         goto err;
1067                 } else if (len >= PAGE_SIZE) {
1068                         ret = -ENAMETOOLONG;
1069                         goto err;
1070                 }
1071                 isec = (struct inode_security_struct*)inode->i_security;
1072                 if ((ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid)))
1073                         goto err;
1074                 isec->sid = sid;
1075                 isec->initialized = 1;
1076                 inode->i_fop = &sel_bool_ops;
1077                 inode->i_ino = i|SEL_BOOL_INO_OFFSET;
1078                 d_add(dentry, inode);
1079         }
1080         bool_num = num;
1081         bool_pending_values = values;
1082 out:
1083         free_page((unsigned long)page);
1084         if (names) {
1085                 for (i = 0; i < num; i++)
1086                         kfree(names[i]);
1087                 kfree(names);
1088         }
1089         return ret;
1090 err:
1091         kfree(values);
1092         sel_remove_entries(dir);
1093         ret = -ENOMEM;
1094         goto out;
1095 }
1096
1097 #define NULL_FILE_NAME "null"
1098
1099 struct dentry *selinux_null = NULL;
1100
1101 static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf,
1102                                             size_t count, loff_t *ppos)
1103 {
1104         char tmpbuf[TMPBUFLEN];
1105         ssize_t length;
1106
1107         length = scnprintf(tmpbuf, TMPBUFLEN, "%u", avc_cache_threshold);
1108         return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
1109 }
1110
1111 static ssize_t sel_write_avc_cache_threshold(struct file * file,
1112                                              const char __user * buf,
1113                                              size_t count, loff_t *ppos)
1114
1115 {
1116         char *page;
1117         ssize_t ret;
1118         int new_value;
1119
1120         if (count >= PAGE_SIZE) {
1121                 ret = -ENOMEM;
1122                 goto out;
1123         }
1124
1125         if (*ppos != 0) {
1126                 /* No partial writes. */
1127                 ret = -EINVAL;
1128                 goto out;
1129         }
1130
1131         page = (char*)get_zeroed_page(GFP_KERNEL);
1132         if (!page) {
1133                 ret = -ENOMEM;
1134                 goto out;
1135         }
1136
1137         if (copy_from_user(page, buf, count)) {
1138                 ret = -EFAULT;
1139                 goto out_free;
1140         }
1141
1142         if (sscanf(page, "%u", &new_value) != 1) {
1143                 ret = -EINVAL;
1144                 goto out;
1145         }
1146
1147         if (new_value != avc_cache_threshold) {
1148                 ret = task_has_security(current, SECURITY__SETSECPARAM);
1149                 if (ret)
1150                         goto out_free;
1151                 avc_cache_threshold = new_value;
1152         }
1153         ret = count;
1154 out_free:
1155         free_page((unsigned long)page);
1156 out:
1157         return ret;
1158 }
1159
1160 static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
1161                                        size_t count, loff_t *ppos)
1162 {
1163         char *page;
1164         ssize_t ret = 0;
1165
1166         page = (char *)__get_free_page(GFP_KERNEL);
1167         if (!page) {
1168                 ret = -ENOMEM;
1169                 goto out;
1170         }
1171         ret = avc_get_hash_stats(page);
1172         if (ret >= 0)
1173                 ret = simple_read_from_buffer(buf, count, ppos, page, ret);
1174         free_page((unsigned long)page);
1175 out:
1176         return ret;
1177 }
1178
1179 static const struct file_operations sel_avc_cache_threshold_ops = {
1180         .read           = sel_read_avc_cache_threshold,
1181         .write          = sel_write_avc_cache_threshold,
1182 };
1183
1184 static const struct file_operations sel_avc_hash_stats_ops = {
1185         .read           = sel_read_avc_hash_stats,
1186 };
1187
1188 #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
1189 static struct avc_cache_stats *sel_avc_get_stat_idx(loff_t *idx)
1190 {
1191         int cpu;
1192
1193         for (cpu = *idx; cpu < NR_CPUS; ++cpu) {
1194                 if (!cpu_possible(cpu))
1195                         continue;
1196                 *idx = cpu + 1;
1197                 return &per_cpu(avc_cache_stats, cpu);
1198         }
1199         return NULL;
1200 }
1201
1202 static void *sel_avc_stats_seq_start(struct seq_file *seq, loff_t *pos)
1203 {
1204         loff_t n = *pos - 1;
1205
1206         if (*pos == 0)
1207                 return SEQ_START_TOKEN;
1208
1209         return sel_avc_get_stat_idx(&n);
1210 }
1211
1212 static void *sel_avc_stats_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1213 {
1214         return sel_avc_get_stat_idx(pos);
1215 }
1216
1217 static int sel_avc_stats_seq_show(struct seq_file *seq, void *v)
1218 {
1219         struct avc_cache_stats *st = v;
1220
1221         if (v == SEQ_START_TOKEN)
1222                 seq_printf(seq, "lookups hits misses allocations reclaims "
1223                            "frees\n");
1224         else
1225                 seq_printf(seq, "%u %u %u %u %u %u\n", st->lookups,
1226                            st->hits, st->misses, st->allocations,
1227                            st->reclaims, st->frees);
1228         return 0;
1229 }
1230
1231 static void sel_avc_stats_seq_stop(struct seq_file *seq, void *v)
1232 { }
1233
1234 static struct seq_operations sel_avc_cache_stats_seq_ops = {
1235         .start          = sel_avc_stats_seq_start,
1236         .next           = sel_avc_stats_seq_next,
1237         .show           = sel_avc_stats_seq_show,
1238         .stop           = sel_avc_stats_seq_stop,
1239 };
1240
1241 static int sel_open_avc_cache_stats(struct inode *inode, struct file *file)
1242 {
1243         return seq_open(file, &sel_avc_cache_stats_seq_ops);
1244 }
1245
1246 static const struct file_operations sel_avc_cache_stats_ops = {
1247         .open           = sel_open_avc_cache_stats,
1248         .read           = seq_read,
1249         .llseek         = seq_lseek,
1250         .release        = seq_release,
1251 };
1252 #endif
1253
1254 static int sel_make_avc_files(struct dentry *dir)
1255 {
1256         int i, ret = 0;
1257         static struct tree_descr files[] = {
1258                 { "cache_threshold",
1259                   &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR },
1260                 { "hash_stats", &sel_avc_hash_stats_ops, S_IRUGO },
1261 #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
1262                 { "cache_stats", &sel_avc_cache_stats_ops, S_IRUGO },
1263 #endif
1264         };
1265
1266         for (i = 0; i < ARRAY_SIZE(files); i++) {
1267                 struct inode *inode;
1268                 struct dentry *dentry;
1269
1270                 dentry = d_alloc_name(dir, files[i].name);
1271                 if (!dentry) {
1272                         ret = -ENOMEM;
1273                         goto out;
1274                 }
1275
1276                 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
1277                 if (!inode) {
1278                         ret = -ENOMEM;
1279                         goto out;
1280                 }
1281                 inode->i_fop = files[i].ops;
1282                 inode->i_ino = ++sel_last_ino;
1283                 d_add(dentry, inode);
1284         }
1285 out:
1286         return ret;
1287 }
1288
1289 static ssize_t sel_read_initcon(struct file * file, char __user *buf,
1290                                 size_t count, loff_t *ppos)
1291 {
1292         struct inode *inode;
1293         char *con;
1294         u32 sid, len;
1295         ssize_t ret;
1296
1297         inode = file->f_path.dentry->d_inode;
1298         sid = inode->i_ino&SEL_INO_MASK;
1299         ret = security_sid_to_context(sid, &con, &len);
1300         if (ret < 0)
1301                 return ret;
1302
1303         ret = simple_read_from_buffer(buf, count, ppos, con, len);
1304         kfree(con);
1305         return ret;
1306 }
1307
1308 static const struct file_operations sel_initcon_ops = {
1309         .read           = sel_read_initcon,
1310 };
1311
1312 static int sel_make_initcon_files(struct dentry *dir)
1313 {
1314         int i, ret = 0;
1315
1316         for (i = 1; i <= SECINITSID_NUM; i++) {
1317                 struct inode *inode;
1318                 struct dentry *dentry;
1319                 dentry = d_alloc_name(dir, security_get_initial_sid_context(i));
1320                 if (!dentry) {
1321                         ret = -ENOMEM;
1322                         goto out;
1323                 }
1324
1325                 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1326                 if (!inode) {
1327                         ret = -ENOMEM;
1328                         goto out;
1329                 }
1330                 inode->i_fop = &sel_initcon_ops;
1331                 inode->i_ino = i|SEL_INITCON_INO_OFFSET;
1332                 d_add(dentry, inode);
1333         }
1334 out:
1335         return ret;
1336 }
1337
1338 static inline unsigned int sel_div(unsigned long a, unsigned long b)
1339 {
1340         return a / b - (a % b < 0);
1341 }
1342
1343 static inline unsigned long sel_class_to_ino(u16 class)
1344 {
1345         return (class * (SEL_VEC_MAX + 1)) | SEL_CLASS_INO_OFFSET;
1346 }
1347
1348 static inline u16 sel_ino_to_class(unsigned long ino)
1349 {
1350         return sel_div(ino & SEL_INO_MASK, SEL_VEC_MAX + 1);
1351 }
1352
1353 static inline unsigned long sel_perm_to_ino(u16 class, u32 perm)
1354 {
1355         return (class * (SEL_VEC_MAX + 1) + perm) | SEL_CLASS_INO_OFFSET;
1356 }
1357
1358 static inline u32 sel_ino_to_perm(unsigned long ino)
1359 {
1360         return (ino & SEL_INO_MASK) % (SEL_VEC_MAX + 1);
1361 }
1362
1363 static ssize_t sel_read_class(struct file * file, char __user *buf,
1364                                 size_t count, loff_t *ppos)
1365 {
1366         ssize_t rc, len;
1367         char *page;
1368         unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1369
1370         page = (char *)__get_free_page(GFP_KERNEL);
1371         if (!page) {
1372                 rc = -ENOMEM;
1373                 goto out;
1374         }
1375
1376         len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino));
1377         rc = simple_read_from_buffer(buf, count, ppos, page, len);
1378         free_page((unsigned long)page);
1379 out:
1380         return rc;
1381 }
1382
1383 static const struct file_operations sel_class_ops = {
1384         .read           = sel_read_class,
1385 };
1386
1387 static ssize_t sel_read_perm(struct file * file, char __user *buf,
1388                                 size_t count, loff_t *ppos)
1389 {
1390         ssize_t rc, len;
1391         char *page;
1392         unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1393
1394         page = (char *)__get_free_page(GFP_KERNEL);
1395         if (!page) {
1396                 rc = -ENOMEM;
1397                 goto out;
1398         }
1399
1400         len = snprintf(page, PAGE_SIZE,"%d", sel_ino_to_perm(ino));
1401         rc = simple_read_from_buffer(buf, count, ppos, page, len);
1402         free_page((unsigned long)page);
1403 out:
1404         return rc;
1405 }
1406
1407 static const struct file_operations sel_perm_ops = {
1408         .read           = sel_read_perm,
1409 };
1410
1411 static int sel_make_perm_files(char *objclass, int classvalue,
1412                                 struct dentry *dir)
1413 {
1414         int i, rc = 0, nperms;
1415         char **perms;
1416
1417         rc = security_get_permissions(objclass, &perms, &nperms);
1418         if (rc)
1419                 goto out;
1420
1421         for (i = 0; i < nperms; i++) {
1422                 struct inode *inode;
1423                 struct dentry *dentry;
1424
1425                 dentry = d_alloc_name(dir, perms[i]);
1426                 if (!dentry) {
1427                         rc = -ENOMEM;
1428                         goto out1;
1429                 }
1430
1431                 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1432                 if (!inode) {
1433                         rc = -ENOMEM;
1434                         goto out1;
1435                 }
1436                 inode->i_fop = &sel_perm_ops;
1437                 /* i+1 since perm values are 1-indexed */
1438                 inode->i_ino = sel_perm_to_ino(classvalue, i+1);
1439                 d_add(dentry, inode);
1440         }
1441
1442 out1:
1443         for (i = 0; i < nperms; i++)
1444                 kfree(perms[i]);
1445         kfree(perms);
1446 out:
1447         return rc;
1448 }
1449
1450 static int sel_make_class_dir_entries(char *classname, int index,
1451                                         struct dentry *dir)
1452 {
1453         struct dentry *dentry = NULL;
1454         struct inode *inode = NULL;
1455         int rc;
1456
1457         dentry = d_alloc_name(dir, "index");
1458         if (!dentry) {
1459                 rc = -ENOMEM;
1460                 goto out;
1461         }
1462
1463         inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1464         if (!inode) {
1465                 rc = -ENOMEM;
1466                 goto out;
1467         }
1468
1469         inode->i_fop = &sel_class_ops;
1470         inode->i_ino = sel_class_to_ino(index);
1471         d_add(dentry, inode);
1472
1473         dentry = d_alloc_name(dir, "perms");
1474         if (!dentry) {
1475                 rc = -ENOMEM;
1476                 goto out;
1477         }
1478
1479         rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino);
1480         if (rc)
1481                 goto out;
1482
1483         rc = sel_make_perm_files(classname, index, dentry);
1484
1485 out:
1486         return rc;
1487 }
1488
1489 static void sel_remove_classes(void)
1490 {
1491         struct list_head *class_node;
1492
1493         list_for_each(class_node, &class_dir->d_subdirs) {
1494                 struct dentry *class_subdir = list_entry(class_node,
1495                                         struct dentry, d_u.d_child);
1496                 struct list_head *class_subdir_node;
1497
1498                 list_for_each(class_subdir_node, &class_subdir->d_subdirs) {
1499                         struct dentry *d = list_entry(class_subdir_node,
1500                                                 struct dentry, d_u.d_child);
1501
1502                         if (d->d_inode)
1503                                 if (d->d_inode->i_mode & S_IFDIR)
1504                                         sel_remove_entries(d);
1505                 }
1506
1507                 sel_remove_entries(class_subdir);
1508         }
1509
1510         sel_remove_entries(class_dir);
1511 }
1512
1513 static int sel_make_classes(void)
1514 {
1515         int rc = 0, nclasses, i;
1516         char **classes;
1517
1518         /* delete any existing entries */
1519         sel_remove_classes();
1520
1521         rc = security_get_classes(&classes, &nclasses);
1522         if (rc < 0)
1523                 goto out;
1524
1525         /* +2 since classes are 1-indexed */
1526         last_class_ino = sel_class_to_ino(nclasses+2);
1527
1528         for (i = 0; i < nclasses; i++) {
1529                 struct dentry *class_name_dir;
1530
1531                 class_name_dir = d_alloc_name(class_dir, classes[i]);
1532                 if (!class_name_dir) {
1533                         rc = -ENOMEM;
1534                         goto out1;
1535                 }
1536
1537                 rc = sel_make_dir(class_dir->d_inode, class_name_dir,
1538                                 &last_class_ino);
1539                 if (rc)
1540                         goto out1;
1541
1542                 /* i+1 since class values are 1-indexed */
1543                 rc = sel_make_class_dir_entries(classes[i], i+1,
1544                                 class_name_dir);
1545                 if (rc)
1546                         goto out1;
1547         }
1548
1549 out1:
1550         for (i = 0; i < nclasses; i++)
1551                 kfree(classes[i]);
1552         kfree(classes);
1553 out:
1554         return rc;
1555 }
1556
1557 static int sel_make_dir(struct inode *dir, struct dentry *dentry,
1558                         unsigned long *ino)
1559 {
1560         int ret = 0;
1561         struct inode *inode;
1562
1563         inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO);
1564         if (!inode) {
1565                 ret = -ENOMEM;
1566                 goto out;
1567         }
1568         inode->i_op = &simple_dir_inode_operations;
1569         inode->i_fop = &simple_dir_operations;
1570         inode->i_ino = ++(*ino);
1571         /* directory inodes start off with i_nlink == 2 (for "." entry) */
1572         inc_nlink(inode);
1573         d_add(dentry, inode);
1574         /* bump link count on parent directory, too */
1575         inc_nlink(dir);
1576 out:
1577         return ret;
1578 }
1579
1580 static int sel_fill_super(struct super_block * sb, void * data, int silent)
1581 {
1582         int ret;
1583         struct dentry *dentry;
1584         struct inode *inode, *root_inode;
1585         struct inode_security_struct *isec;
1586
1587         static struct tree_descr selinux_files[] = {
1588                 [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
1589                 [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR},
1590                 [SEL_CONTEXT] = {"context", &transaction_ops, S_IRUGO|S_IWUGO},
1591                 [SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO},
1592                 [SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO},
1593                 [SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO},
1594                 [SEL_USER] = {"user", &transaction_ops, S_IRUGO|S_IWUGO},
1595                 [SEL_POLICYVERS] = {"policyvers", &sel_policyvers_ops, S_IRUGO},
1596                 [SEL_COMMIT_BOOLS] = {"commit_pending_bools", &sel_commit_bools_ops, S_IWUSR},
1597                 [SEL_MLS] = {"mls", &sel_mls_ops, S_IRUGO},
1598                 [SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR},
1599                 [SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO},
1600                 [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
1601                 [SEL_COMPAT_NET] = {"compat_net", &sel_compat_net_ops, S_IRUGO|S_IWUSR},
1602                 [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
1603                 [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
1604                 /* last one */ {""}
1605         };
1606         ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
1607         if (ret)
1608                 goto err;
1609
1610         root_inode = sb->s_root->d_inode;
1611
1612         dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME);
1613         if (!dentry) {
1614                 ret = -ENOMEM;
1615                 goto err;
1616         }
1617
1618         ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1619         if (ret)
1620                 goto err;
1621
1622         bool_dir = dentry;
1623
1624         dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME);
1625         if (!dentry) {
1626                 ret = -ENOMEM;
1627                 goto err;
1628         }
1629
1630         inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO);
1631         if (!inode) {
1632                 ret = -ENOMEM;
1633                 goto err;
1634         }
1635         inode->i_ino = ++sel_last_ino;
1636         isec = (struct inode_security_struct*)inode->i_security;
1637         isec->sid = SECINITSID_DEVNULL;
1638         isec->sclass = SECCLASS_CHR_FILE;
1639         isec->initialized = 1;
1640
1641         init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3));
1642         d_add(dentry, inode);
1643         selinux_null = dentry;
1644
1645         dentry = d_alloc_name(sb->s_root, "avc");
1646         if (!dentry) {
1647                 ret = -ENOMEM;
1648                 goto err;
1649         }
1650
1651         ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1652         if (ret)
1653                 goto err;
1654
1655         ret = sel_make_avc_files(dentry);
1656         if (ret)
1657                 goto err;
1658
1659         dentry = d_alloc_name(sb->s_root, "initial_contexts");
1660         if (!dentry) {
1661                 ret = -ENOMEM;
1662                 goto err;
1663         }
1664
1665         ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1666         if (ret)
1667                 goto err;
1668
1669         ret = sel_make_initcon_files(dentry);
1670         if (ret)
1671                 goto err;
1672
1673         dentry = d_alloc_name(sb->s_root, "class");
1674         if (!dentry) {
1675                 ret = -ENOMEM;
1676                 goto err;
1677         }
1678
1679         ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1680         if (ret)
1681                 goto err;
1682
1683         class_dir = dentry;
1684
1685 out:
1686         return ret;
1687 err:
1688         printk(KERN_ERR "%s:  failed while creating inodes\n", __FUNCTION__);
1689         goto out;
1690 }
1691
1692 static int sel_get_sb(struct file_system_type *fs_type,
1693                       int flags, const char *dev_name, void *data,
1694                       struct vfsmount *mnt)
1695 {
1696         return get_sb_single(fs_type, flags, data, sel_fill_super, mnt);
1697 }
1698
1699 static struct file_system_type sel_fs_type = {
1700         .name           = "selinuxfs",
1701         .get_sb         = sel_get_sb,
1702         .kill_sb        = kill_litter_super,
1703 };
1704
1705 struct vfsmount *selinuxfs_mount;
1706
1707 static int __init init_sel_fs(void)
1708 {
1709         int err;
1710
1711         if (!selinux_enabled)
1712                 return 0;
1713         err = register_filesystem(&sel_fs_type);
1714         if (!err) {
1715                 selinuxfs_mount = kern_mount(&sel_fs_type);
1716                 if (IS_ERR(selinuxfs_mount)) {
1717                         printk(KERN_ERR "selinuxfs:  could not mount!\n");
1718                         err = PTR_ERR(selinuxfs_mount);
1719                         selinuxfs_mount = NULL;
1720                 }
1721         }
1722         return err;
1723 }
1724
1725 __initcall(init_sel_fs);
1726
1727 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
1728 void exit_sel_fs(void)
1729 {
1730         unregister_filesystem(&sel_fs_type);
1731 }
1732 #endif