xref: /linux/security/selinux/selinuxfs.c (revision 858259cf7d1c443c836a2022b78cb281f0a9b95e)
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/config.h>
13 #include <linux/kernel.h>
14 #include <linux/pagemap.h>
15 #include <linux/slab.h>
16 #include <linux/vmalloc.h>
17 #include <linux/fs.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 <asm/uaccess.h>
25 #include <asm/semaphore.h>
26 
27 /* selinuxfs pseudo filesystem for exporting the security policy API.
28    Based on the proc code and the fs/nfsd/nfsctl.c code. */
29 
30 #include "flask.h"
31 #include "avc.h"
32 #include "avc_ss.h"
33 #include "security.h"
34 #include "objsec.h"
35 #include "conditional.h"
36 
37 unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
38 
39 static int __init checkreqprot_setup(char *str)
40 {
41 	selinux_checkreqprot = simple_strtoul(str,NULL,0) ? 1 : 0;
42 	return 1;
43 }
44 __setup("checkreqprot=", checkreqprot_setup);
45 
46 
47 static DECLARE_MUTEX(sel_sem);
48 
49 /* global data for booleans */
50 static struct dentry *bool_dir = NULL;
51 static int bool_num = 0;
52 static int *bool_pending_values = NULL;
53 
54 extern void selnl_notify_setenforce(int val);
55 
56 /* Check whether a task is allowed to use a security operation. */
57 static int task_has_security(struct task_struct *tsk,
58 			     u32 perms)
59 {
60 	struct task_security_struct *tsec;
61 
62 	tsec = tsk->security;
63 	if (!tsec)
64 		return -EACCES;
65 
66 	return avc_has_perm(tsec->sid, SECINITSID_SECURITY,
67 			    SECCLASS_SECURITY, perms, NULL);
68 }
69 
70 enum sel_inos {
71 	SEL_ROOT_INO = 2,
72 	SEL_LOAD,	/* load policy */
73 	SEL_ENFORCE,	/* get or set enforcing status */
74 	SEL_CONTEXT,	/* validate context */
75 	SEL_ACCESS,	/* compute access decision */
76 	SEL_CREATE,	/* compute create labeling decision */
77 	SEL_RELABEL,	/* compute relabeling decision */
78 	SEL_USER,	/* compute reachable user contexts */
79 	SEL_POLICYVERS,	/* return policy version for this kernel */
80 	SEL_COMMIT_BOOLS, /* commit new boolean values */
81 	SEL_MLS,	/* return if MLS policy is enabled */
82 	SEL_DISABLE,	/* disable SELinux until next reboot */
83 	SEL_AVC,	/* AVC management directory */
84 	SEL_MEMBER,	/* compute polyinstantiation membership decision */
85 	SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */
86 };
87 
88 #define TMPBUFLEN	12
89 static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
90 				size_t count, loff_t *ppos)
91 {
92 	char tmpbuf[TMPBUFLEN];
93 	ssize_t length;
94 
95 	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_enforcing);
96 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
97 }
98 
99 #ifdef CONFIG_SECURITY_SELINUX_DEVELOP
100 static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
101 				 size_t count, loff_t *ppos)
102 
103 {
104 	char *page;
105 	ssize_t length;
106 	int new_value;
107 
108 	if (count >= PAGE_SIZE)
109 		return -ENOMEM;
110 	if (*ppos != 0) {
111 		/* No partial writes. */
112 		return -EINVAL;
113 	}
114 	page = (char*)get_zeroed_page(GFP_KERNEL);
115 	if (!page)
116 		return -ENOMEM;
117 	length = -EFAULT;
118 	if (copy_from_user(page, buf, count))
119 		goto out;
120 
121 	length = -EINVAL;
122 	if (sscanf(page, "%d", &new_value) != 1)
123 		goto out;
124 
125 	if (new_value != selinux_enforcing) {
126 		length = task_has_security(current, SECURITY__SETENFORCE);
127 		if (length)
128 			goto out;
129 		selinux_enforcing = new_value;
130 		if (selinux_enforcing)
131 			avc_ss_reset(0);
132 		selnl_notify_setenforce(selinux_enforcing);
133 	}
134 	length = count;
135 out:
136 	free_page((unsigned long) page);
137 	return length;
138 }
139 #else
140 #define sel_write_enforce NULL
141 #endif
142 
143 static struct file_operations sel_enforce_ops = {
144 	.read		= sel_read_enforce,
145 	.write		= sel_write_enforce,
146 };
147 
148 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
149 static ssize_t sel_write_disable(struct file * file, const char __user * buf,
150 				 size_t count, loff_t *ppos)
151 
152 {
153 	char *page;
154 	ssize_t length;
155 	int new_value;
156 	extern int selinux_disable(void);
157 
158 	if (count >= PAGE_SIZE)
159 		return -ENOMEM;
160 	if (*ppos != 0) {
161 		/* No partial writes. */
162 		return -EINVAL;
163 	}
164 	page = (char*)get_zeroed_page(GFP_KERNEL);
165 	if (!page)
166 		return -ENOMEM;
167 	length = -EFAULT;
168 	if (copy_from_user(page, buf, count))
169 		goto out;
170 
171 	length = -EINVAL;
172 	if (sscanf(page, "%d", &new_value) != 1)
173 		goto out;
174 
175 	if (new_value) {
176 		length = selinux_disable();
177 		if (length < 0)
178 			goto out;
179 	}
180 
181 	length = count;
182 out:
183 	free_page((unsigned long) page);
184 	return length;
185 }
186 #else
187 #define sel_write_disable NULL
188 #endif
189 
190 static struct file_operations sel_disable_ops = {
191 	.write		= sel_write_disable,
192 };
193 
194 static ssize_t sel_read_policyvers(struct file *filp, char __user *buf,
195                                    size_t count, loff_t *ppos)
196 {
197 	char tmpbuf[TMPBUFLEN];
198 	ssize_t length;
199 
200 	length = scnprintf(tmpbuf, TMPBUFLEN, "%u", POLICYDB_VERSION_MAX);
201 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
202 }
203 
204 static struct file_operations sel_policyvers_ops = {
205 	.read		= sel_read_policyvers,
206 };
207 
208 /* declaration for sel_write_load */
209 static int sel_make_bools(void);
210 
211 static ssize_t sel_read_mls(struct file *filp, char __user *buf,
212 				size_t count, loff_t *ppos)
213 {
214 	char tmpbuf[TMPBUFLEN];
215 	ssize_t length;
216 
217 	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
218 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
219 }
220 
221 static struct file_operations sel_mls_ops = {
222 	.read		= sel_read_mls,
223 };
224 
225 static ssize_t sel_write_load(struct file * file, const char __user * buf,
226 			      size_t count, loff_t *ppos)
227 
228 {
229 	int ret;
230 	ssize_t length;
231 	void *data = NULL;
232 
233 	down(&sel_sem);
234 
235 	length = task_has_security(current, SECURITY__LOAD_POLICY);
236 	if (length)
237 		goto out;
238 
239 	if (*ppos != 0) {
240 		/* No partial writes. */
241 		length = -EINVAL;
242 		goto out;
243 	}
244 
245 	if ((count > 64 * 1024 * 1024)
246 	    || (data = vmalloc(count)) == NULL) {
247 		length = -ENOMEM;
248 		goto out;
249 	}
250 
251 	length = -EFAULT;
252 	if (copy_from_user(data, buf, count) != 0)
253 		goto out;
254 
255 	length = security_load_policy(data, count);
256 	if (length)
257 		goto out;
258 
259 	ret = sel_make_bools();
260 	if (ret)
261 		length = ret;
262 	else
263 		length = count;
264 out:
265 	up(&sel_sem);
266 	vfree(data);
267 	return length;
268 }
269 
270 static struct file_operations sel_load_ops = {
271 	.write		= sel_write_load,
272 };
273 
274 
275 static ssize_t sel_write_context(struct file * file, const char __user * buf,
276 				 size_t count, loff_t *ppos)
277 
278 {
279 	char *page;
280 	u32 sid;
281 	ssize_t length;
282 
283 	length = task_has_security(current, SECURITY__CHECK_CONTEXT);
284 	if (length)
285 		return length;
286 
287 	if (count >= PAGE_SIZE)
288 		return -ENOMEM;
289 	if (*ppos != 0) {
290 		/* No partial writes. */
291 		return -EINVAL;
292 	}
293 	page = (char*)get_zeroed_page(GFP_KERNEL);
294 	if (!page)
295 		return -ENOMEM;
296 	length = -EFAULT;
297 	if (copy_from_user(page, buf, count))
298 		goto out;
299 
300 	length = security_context_to_sid(page, count, &sid);
301 	if (length < 0)
302 		goto out;
303 
304 	length = count;
305 out:
306 	free_page((unsigned long) page);
307 	return length;
308 }
309 
310 static struct file_operations sel_context_ops = {
311 	.write		= sel_write_context,
312 };
313 
314 static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
315 				     size_t count, loff_t *ppos)
316 {
317 	char tmpbuf[TMPBUFLEN];
318 	ssize_t length;
319 
320 	length = scnprintf(tmpbuf, TMPBUFLEN, "%u", selinux_checkreqprot);
321 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
322 }
323 
324 static ssize_t sel_write_checkreqprot(struct file * file, const char __user * buf,
325 				      size_t count, loff_t *ppos)
326 {
327 	char *page;
328 	ssize_t length;
329 	unsigned int new_value;
330 
331 	length = task_has_security(current, SECURITY__SETCHECKREQPROT);
332 	if (length)
333 		return length;
334 
335 	if (count >= PAGE_SIZE)
336 		return -ENOMEM;
337 	if (*ppos != 0) {
338 		/* No partial writes. */
339 		return -EINVAL;
340 	}
341 	page = (char*)get_zeroed_page(GFP_KERNEL);
342 	if (!page)
343 		return -ENOMEM;
344 	length = -EFAULT;
345 	if (copy_from_user(page, buf, count))
346 		goto out;
347 
348 	length = -EINVAL;
349 	if (sscanf(page, "%u", &new_value) != 1)
350 		goto out;
351 
352 	selinux_checkreqprot = new_value ? 1 : 0;
353 	length = count;
354 out:
355 	free_page((unsigned long) page);
356 	return length;
357 }
358 static struct file_operations sel_checkreqprot_ops = {
359 	.read		= sel_read_checkreqprot,
360 	.write		= sel_write_checkreqprot,
361 };
362 
363 /*
364  * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
365  */
366 static ssize_t sel_write_access(struct file * file, char *buf, size_t size);
367 static ssize_t sel_write_create(struct file * file, char *buf, size_t size);
368 static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size);
369 static ssize_t sel_write_user(struct file * file, char *buf, size_t size);
370 static ssize_t sel_write_member(struct file * file, char *buf, size_t size);
371 
372 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
373 	[SEL_ACCESS] = sel_write_access,
374 	[SEL_CREATE] = sel_write_create,
375 	[SEL_RELABEL] = sel_write_relabel,
376 	[SEL_USER] = sel_write_user,
377 	[SEL_MEMBER] = sel_write_member,
378 };
379 
380 static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
381 {
382 	ino_t ino =  file->f_dentry->d_inode->i_ino;
383 	char *data;
384 	ssize_t rv;
385 
386 	if (ino >= sizeof(write_op)/sizeof(write_op[0]) || !write_op[ino])
387 		return -EINVAL;
388 
389 	data = simple_transaction_get(file, buf, size);
390 	if (IS_ERR(data))
391 		return PTR_ERR(data);
392 
393 	rv =  write_op[ino](file, data, size);
394 	if (rv>0) {
395 		simple_transaction_set(file, rv);
396 		rv = size;
397 	}
398 	return rv;
399 }
400 
401 static struct file_operations transaction_ops = {
402 	.write		= selinux_transaction_write,
403 	.read		= simple_transaction_read,
404 	.release	= simple_transaction_release,
405 };
406 
407 /*
408  * payload - write methods
409  * If the method has a response, the response should be put in buf,
410  * and the length returned.  Otherwise return 0 or and -error.
411  */
412 
413 static ssize_t sel_write_access(struct file * file, char *buf, size_t size)
414 {
415 	char *scon, *tcon;
416 	u32 ssid, tsid;
417 	u16 tclass;
418 	u32 req;
419 	struct av_decision avd;
420 	ssize_t length;
421 
422 	length = task_has_security(current, SECURITY__COMPUTE_AV);
423 	if (length)
424 		return length;
425 
426 	length = -ENOMEM;
427 	scon = kzalloc(size+1, GFP_KERNEL);
428 	if (!scon)
429 		return length;
430 
431 	tcon = kzalloc(size+1, GFP_KERNEL);
432 	if (!tcon)
433 		goto out;
434 
435 	length = -EINVAL;
436 	if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4)
437 		goto out2;
438 
439 	length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
440 	if (length < 0)
441 		goto out2;
442 	length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
443 	if (length < 0)
444 		goto out2;
445 
446 	length = security_compute_av(ssid, tsid, tclass, req, &avd);
447 	if (length < 0)
448 		goto out2;
449 
450 	length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
451 			  "%x %x %x %x %u",
452 			  avd.allowed, avd.decided,
453 			  avd.auditallow, avd.auditdeny,
454 			  avd.seqno);
455 out2:
456 	kfree(tcon);
457 out:
458 	kfree(scon);
459 	return length;
460 }
461 
462 static ssize_t sel_write_create(struct file * file, char *buf, size_t size)
463 {
464 	char *scon, *tcon;
465 	u32 ssid, tsid, newsid;
466 	u16 tclass;
467 	ssize_t length;
468 	char *newcon;
469 	u32 len;
470 
471 	length = task_has_security(current, SECURITY__COMPUTE_CREATE);
472 	if (length)
473 		return length;
474 
475 	length = -ENOMEM;
476 	scon = kzalloc(size+1, GFP_KERNEL);
477 	if (!scon)
478 		return length;
479 
480 	tcon = kzalloc(size+1, GFP_KERNEL);
481 	if (!tcon)
482 		goto out;
483 
484 	length = -EINVAL;
485 	if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
486 		goto out2;
487 
488 	length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
489 	if (length < 0)
490 		goto out2;
491 	length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
492 	if (length < 0)
493 		goto out2;
494 
495 	length = security_transition_sid(ssid, tsid, tclass, &newsid);
496 	if (length < 0)
497 		goto out2;
498 
499 	length = security_sid_to_context(newsid, &newcon, &len);
500 	if (length < 0)
501 		goto out2;
502 
503 	if (len > SIMPLE_TRANSACTION_LIMIT) {
504 		printk(KERN_ERR "%s:  context size (%u) exceeds payload "
505 		       "max\n", __FUNCTION__, len);
506 		length = -ERANGE;
507 		goto out3;
508 	}
509 
510 	memcpy(buf, newcon, len);
511 	length = len;
512 out3:
513 	kfree(newcon);
514 out2:
515 	kfree(tcon);
516 out:
517 	kfree(scon);
518 	return length;
519 }
520 
521 static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size)
522 {
523 	char *scon, *tcon;
524 	u32 ssid, tsid, newsid;
525 	u16 tclass;
526 	ssize_t length;
527 	char *newcon;
528 	u32 len;
529 
530 	length = task_has_security(current, SECURITY__COMPUTE_RELABEL);
531 	if (length)
532 		return length;
533 
534 	length = -ENOMEM;
535 	scon = kzalloc(size+1, GFP_KERNEL);
536 	if (!scon)
537 		return length;
538 
539 	tcon = kzalloc(size+1, GFP_KERNEL);
540 	if (!tcon)
541 		goto out;
542 
543 	length = -EINVAL;
544 	if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
545 		goto out2;
546 
547 	length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
548 	if (length < 0)
549 		goto out2;
550 	length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
551 	if (length < 0)
552 		goto out2;
553 
554 	length = security_change_sid(ssid, tsid, tclass, &newsid);
555 	if (length < 0)
556 		goto out2;
557 
558 	length = security_sid_to_context(newsid, &newcon, &len);
559 	if (length < 0)
560 		goto out2;
561 
562 	if (len > SIMPLE_TRANSACTION_LIMIT) {
563 		length = -ERANGE;
564 		goto out3;
565 	}
566 
567 	memcpy(buf, newcon, len);
568 	length = len;
569 out3:
570 	kfree(newcon);
571 out2:
572 	kfree(tcon);
573 out:
574 	kfree(scon);
575 	return length;
576 }
577 
578 static ssize_t sel_write_user(struct file * file, char *buf, size_t size)
579 {
580 	char *con, *user, *ptr;
581 	u32 sid, *sids;
582 	ssize_t length;
583 	char *newcon;
584 	int i, rc;
585 	u32 len, nsids;
586 
587 	length = task_has_security(current, SECURITY__COMPUTE_USER);
588 	if (length)
589 		return length;
590 
591 	length = -ENOMEM;
592 	con = kzalloc(size+1, GFP_KERNEL);
593 	if (!con)
594 		return length;
595 
596 	user = kzalloc(size+1, GFP_KERNEL);
597 	if (!user)
598 		goto out;
599 
600 	length = -EINVAL;
601 	if (sscanf(buf, "%s %s", con, user) != 2)
602 		goto out2;
603 
604 	length = security_context_to_sid(con, strlen(con)+1, &sid);
605 	if (length < 0)
606 		goto out2;
607 
608 	length = security_get_user_sids(sid, user, &sids, &nsids);
609 	if (length < 0)
610 		goto out2;
611 
612 	length = sprintf(buf, "%u", nsids) + 1;
613 	ptr = buf + length;
614 	for (i = 0; i < nsids; i++) {
615 		rc = security_sid_to_context(sids[i], &newcon, &len);
616 		if (rc) {
617 			length = rc;
618 			goto out3;
619 		}
620 		if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) {
621 			kfree(newcon);
622 			length = -ERANGE;
623 			goto out3;
624 		}
625 		memcpy(ptr, newcon, len);
626 		kfree(newcon);
627 		ptr += len;
628 		length += len;
629 	}
630 out3:
631 	kfree(sids);
632 out2:
633 	kfree(user);
634 out:
635 	kfree(con);
636 	return length;
637 }
638 
639 static ssize_t sel_write_member(struct file * file, char *buf, size_t size)
640 {
641 	char *scon, *tcon;
642 	u32 ssid, tsid, newsid;
643 	u16 tclass;
644 	ssize_t length;
645 	char *newcon;
646 	u32 len;
647 
648 	length = task_has_security(current, SECURITY__COMPUTE_MEMBER);
649 	if (length)
650 		return length;
651 
652 	length = -ENOMEM;
653 	scon = kzalloc(size+1, GFP_KERNEL);
654 	if (!scon)
655 		return length;
656 
657 	tcon = kzalloc(size+1, GFP_KERNEL);
658 	if (!tcon)
659 		goto out;
660 
661 	length = -EINVAL;
662 	if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
663 		goto out2;
664 
665 	length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
666 	if (length < 0)
667 		goto out2;
668 	length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
669 	if (length < 0)
670 		goto out2;
671 
672 	length = security_member_sid(ssid, tsid, tclass, &newsid);
673 	if (length < 0)
674 		goto out2;
675 
676 	length = security_sid_to_context(newsid, &newcon, &len);
677 	if (length < 0)
678 		goto out2;
679 
680 	if (len > SIMPLE_TRANSACTION_LIMIT) {
681 		printk(KERN_ERR "%s:  context size (%u) exceeds payload "
682 		       "max\n", __FUNCTION__, len);
683 		length = -ERANGE;
684 		goto out3;
685 	}
686 
687 	memcpy(buf, newcon, len);
688 	length = len;
689 out3:
690 	kfree(newcon);
691 out2:
692 	kfree(tcon);
693 out:
694 	kfree(scon);
695 	return length;
696 }
697 
698 static struct inode *sel_make_inode(struct super_block *sb, int mode)
699 {
700 	struct inode *ret = new_inode(sb);
701 
702 	if (ret) {
703 		ret->i_mode = mode;
704 		ret->i_uid = ret->i_gid = 0;
705 		ret->i_blksize = PAGE_CACHE_SIZE;
706 		ret->i_blocks = 0;
707 		ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
708 	}
709 	return ret;
710 }
711 
712 #define BOOL_INO_OFFSET 30
713 
714 static ssize_t sel_read_bool(struct file *filep, char __user *buf,
715 			     size_t count, loff_t *ppos)
716 {
717 	char *page = NULL;
718 	ssize_t length;
719 	ssize_t end;
720 	ssize_t ret;
721 	int cur_enforcing;
722 	struct inode *inode;
723 
724 	down(&sel_sem);
725 
726 	ret = -EFAULT;
727 
728 	/* check to see if this file has been deleted */
729 	if (!filep->f_op)
730 		goto out;
731 
732 	if (count > PAGE_SIZE) {
733 		ret = -EINVAL;
734 		goto out;
735 	}
736 	if (!(page = (char*)get_zeroed_page(GFP_KERNEL))) {
737 		ret = -ENOMEM;
738 		goto out;
739 	}
740 
741 	inode = filep->f_dentry->d_inode;
742 	cur_enforcing = security_get_bool_value(inode->i_ino - BOOL_INO_OFFSET);
743 	if (cur_enforcing < 0) {
744 		ret = cur_enforcing;
745 		goto out;
746 	}
747 
748 	length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
749 			  bool_pending_values[inode->i_ino - BOOL_INO_OFFSET]);
750 	if (length < 0) {
751 		ret = length;
752 		goto out;
753 	}
754 
755 	if (*ppos >= length) {
756 		ret = 0;
757 		goto out;
758 	}
759 	if (count + *ppos > length)
760 		count = length - *ppos;
761 	end = count + *ppos;
762 	if (copy_to_user(buf, (char *) page + *ppos, count)) {
763 		ret = -EFAULT;
764 		goto out;
765 	}
766 	*ppos = end;
767 	ret = count;
768 out:
769 	up(&sel_sem);
770 	if (page)
771 		free_page((unsigned long)page);
772 	return ret;
773 }
774 
775 static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
776 			      size_t count, loff_t *ppos)
777 {
778 	char *page = NULL;
779 	ssize_t length = -EFAULT;
780 	int new_value;
781 	struct inode *inode;
782 
783 	down(&sel_sem);
784 
785 	length = task_has_security(current, SECURITY__SETBOOL);
786 	if (length)
787 		goto out;
788 
789 	/* check to see if this file has been deleted */
790 	if (!filep->f_op)
791 		goto out;
792 
793 	if (count >= PAGE_SIZE) {
794 		length = -ENOMEM;
795 		goto out;
796 	}
797 	if (*ppos != 0) {
798 		/* No partial writes. */
799 		goto out;
800 	}
801 	page = (char*)get_zeroed_page(GFP_KERNEL);
802 	if (!page) {
803 		length = -ENOMEM;
804 		goto out;
805 	}
806 
807 	if (copy_from_user(page, buf, count))
808 		goto out;
809 
810 	length = -EINVAL;
811 	if (sscanf(page, "%d", &new_value) != 1)
812 		goto out;
813 
814 	if (new_value)
815 		new_value = 1;
816 
817 	inode = filep->f_dentry->d_inode;
818 	bool_pending_values[inode->i_ino - BOOL_INO_OFFSET] = new_value;
819 	length = count;
820 
821 out:
822 	up(&sel_sem);
823 	if (page)
824 		free_page((unsigned long) page);
825 	return length;
826 }
827 
828 static struct file_operations sel_bool_ops = {
829 	.read           = sel_read_bool,
830 	.write          = sel_write_bool,
831 };
832 
833 static ssize_t sel_commit_bools_write(struct file *filep,
834 				      const char __user *buf,
835 				      size_t count, loff_t *ppos)
836 {
837 	char *page = NULL;
838 	ssize_t length = -EFAULT;
839 	int new_value;
840 
841 	down(&sel_sem);
842 
843 	length = task_has_security(current, SECURITY__SETBOOL);
844 	if (length)
845 		goto out;
846 
847 	/* check to see if this file has been deleted */
848 	if (!filep->f_op)
849 		goto out;
850 
851 	if (count >= PAGE_SIZE) {
852 		length = -ENOMEM;
853 		goto out;
854 	}
855 	if (*ppos != 0) {
856 		/* No partial writes. */
857 		goto out;
858 	}
859 	page = (char*)get_zeroed_page(GFP_KERNEL);
860 	if (!page) {
861 		length = -ENOMEM;
862 		goto out;
863 	}
864 
865 	if (copy_from_user(page, buf, count))
866 		goto out;
867 
868 	length = -EINVAL;
869 	if (sscanf(page, "%d", &new_value) != 1)
870 		goto out;
871 
872 	if (new_value && bool_pending_values) {
873 		security_set_bools(bool_num, bool_pending_values);
874 	}
875 
876 	length = count;
877 
878 out:
879 	up(&sel_sem);
880 	if (page)
881 		free_page((unsigned long) page);
882 	return length;
883 }
884 
885 static struct file_operations sel_commit_bools_ops = {
886 	.write          = sel_commit_bools_write,
887 };
888 
889 /* delete booleans - partial revoke() from
890  * fs/proc/generic.c proc_kill_inodes */
891 static void sel_remove_bools(struct dentry *de)
892 {
893 	struct list_head *p, *node;
894 	struct super_block *sb = de->d_sb;
895 
896 	spin_lock(&dcache_lock);
897 	node = de->d_subdirs.next;
898 	while (node != &de->d_subdirs) {
899 		struct dentry *d = list_entry(node, struct dentry, d_child);
900 		list_del_init(node);
901 
902 		if (d->d_inode) {
903 			d = dget_locked(d);
904 			spin_unlock(&dcache_lock);
905 			d_delete(d);
906 			simple_unlink(de->d_inode, d);
907 			dput(d);
908 			spin_lock(&dcache_lock);
909 		}
910 		node = de->d_subdirs.next;
911 	}
912 
913 	spin_unlock(&dcache_lock);
914 
915 	file_list_lock();
916 	list_for_each(p, &sb->s_files) {
917 		struct file * filp = list_entry(p, struct file, f_u.fu_list);
918 		struct dentry * dentry = filp->f_dentry;
919 
920 		if (dentry->d_parent != de) {
921 			continue;
922 		}
923 		filp->f_op = NULL;
924 	}
925 	file_list_unlock();
926 }
927 
928 #define BOOL_DIR_NAME "booleans"
929 
930 static int sel_make_bools(void)
931 {
932 	int i, ret = 0;
933 	ssize_t len;
934 	struct dentry *dentry = NULL;
935 	struct dentry *dir = bool_dir;
936 	struct inode *inode = NULL;
937 	struct inode_security_struct *isec;
938 	char **names = NULL, *page;
939 	int num;
940 	int *values = NULL;
941 	u32 sid;
942 
943 	/* remove any existing files */
944 	kfree(bool_pending_values);
945 	bool_pending_values = NULL;
946 
947 	sel_remove_bools(dir);
948 
949 	if (!(page = (char*)get_zeroed_page(GFP_KERNEL)))
950 		return -ENOMEM;
951 
952 	ret = security_get_bools(&num, &names, &values);
953 	if (ret != 0)
954 		goto out;
955 
956 	for (i = 0; i < num; i++) {
957 		dentry = d_alloc_name(dir, names[i]);
958 		if (!dentry) {
959 			ret = -ENOMEM;
960 			goto err;
961 		}
962 		inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
963 		if (!inode) {
964 			ret = -ENOMEM;
965 			goto err;
966 		}
967 
968 		len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
969 		if (len < 0) {
970 			ret = -EINVAL;
971 			goto err;
972 		} else if (len >= PAGE_SIZE) {
973 			ret = -ENAMETOOLONG;
974 			goto err;
975 		}
976 		isec = (struct inode_security_struct*)inode->i_security;
977 		if ((ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid)))
978 			goto err;
979 		isec->sid = sid;
980 		isec->initialized = 1;
981 		inode->i_fop = &sel_bool_ops;
982 		inode->i_ino = i + BOOL_INO_OFFSET;
983 		d_add(dentry, inode);
984 	}
985 	bool_num = num;
986 	bool_pending_values = values;
987 out:
988 	free_page((unsigned long)page);
989 	if (names) {
990 		for (i = 0; i < num; i++)
991 			kfree(names[i]);
992 		kfree(names);
993 	}
994 	return ret;
995 err:
996 	kfree(values);
997 	d_genocide(dir);
998 	ret = -ENOMEM;
999 	goto out;
1000 }
1001 
1002 #define NULL_FILE_NAME "null"
1003 
1004 struct dentry *selinux_null = NULL;
1005 
1006 static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf,
1007 					    size_t count, loff_t *ppos)
1008 {
1009 	char tmpbuf[TMPBUFLEN];
1010 	ssize_t length;
1011 
1012 	length = scnprintf(tmpbuf, TMPBUFLEN, "%u", avc_cache_threshold);
1013 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
1014 }
1015 
1016 static ssize_t sel_write_avc_cache_threshold(struct file * file,
1017 					     const char __user * buf,
1018 					     size_t count, loff_t *ppos)
1019 
1020 {
1021 	char *page;
1022 	ssize_t ret;
1023 	int new_value;
1024 
1025 	if (count >= PAGE_SIZE) {
1026 		ret = -ENOMEM;
1027 		goto out;
1028 	}
1029 
1030 	if (*ppos != 0) {
1031 		/* No partial writes. */
1032 		ret = -EINVAL;
1033 		goto out;
1034 	}
1035 
1036 	page = (char*)get_zeroed_page(GFP_KERNEL);
1037 	if (!page) {
1038 		ret = -ENOMEM;
1039 		goto out;
1040 	}
1041 
1042 	if (copy_from_user(page, buf, count)) {
1043 		ret = -EFAULT;
1044 		goto out_free;
1045 	}
1046 
1047 	if (sscanf(page, "%u", &new_value) != 1) {
1048 		ret = -EINVAL;
1049 		goto out;
1050 	}
1051 
1052 	if (new_value != avc_cache_threshold) {
1053 		ret = task_has_security(current, SECURITY__SETSECPARAM);
1054 		if (ret)
1055 			goto out_free;
1056 		avc_cache_threshold = new_value;
1057 	}
1058 	ret = count;
1059 out_free:
1060 	free_page((unsigned long)page);
1061 out:
1062 	return ret;
1063 }
1064 
1065 static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
1066 				       size_t count, loff_t *ppos)
1067 {
1068 	char *page;
1069 	ssize_t ret = 0;
1070 
1071 	page = (char *)__get_free_page(GFP_KERNEL);
1072 	if (!page) {
1073 		ret = -ENOMEM;
1074 		goto out;
1075 	}
1076 	ret = avc_get_hash_stats(page);
1077 	if (ret >= 0)
1078 		ret = simple_read_from_buffer(buf, count, ppos, page, ret);
1079 	free_page((unsigned long)page);
1080 out:
1081 	return ret;
1082 }
1083 
1084 static struct file_operations sel_avc_cache_threshold_ops = {
1085 	.read		= sel_read_avc_cache_threshold,
1086 	.write		= sel_write_avc_cache_threshold,
1087 };
1088 
1089 static struct file_operations sel_avc_hash_stats_ops = {
1090 	.read		= sel_read_avc_hash_stats,
1091 };
1092 
1093 #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
1094 static struct avc_cache_stats *sel_avc_get_stat_idx(loff_t *idx)
1095 {
1096 	int cpu;
1097 
1098 	for (cpu = *idx; cpu < NR_CPUS; ++cpu) {
1099 		if (!cpu_possible(cpu))
1100 			continue;
1101 		*idx = cpu + 1;
1102 		return &per_cpu(avc_cache_stats, cpu);
1103 	}
1104 	return NULL;
1105 }
1106 
1107 static void *sel_avc_stats_seq_start(struct seq_file *seq, loff_t *pos)
1108 {
1109 	loff_t n = *pos - 1;
1110 
1111 	if (*pos == 0)
1112 		return SEQ_START_TOKEN;
1113 
1114 	return sel_avc_get_stat_idx(&n);
1115 }
1116 
1117 static void *sel_avc_stats_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1118 {
1119 	return sel_avc_get_stat_idx(pos);
1120 }
1121 
1122 static int sel_avc_stats_seq_show(struct seq_file *seq, void *v)
1123 {
1124 	struct avc_cache_stats *st = v;
1125 
1126 	if (v == SEQ_START_TOKEN)
1127 		seq_printf(seq, "lookups hits misses allocations reclaims "
1128 			   "frees\n");
1129 	else
1130 		seq_printf(seq, "%u %u %u %u %u %u\n", st->lookups,
1131 			   st->hits, st->misses, st->allocations,
1132 			   st->reclaims, st->frees);
1133 	return 0;
1134 }
1135 
1136 static void sel_avc_stats_seq_stop(struct seq_file *seq, void *v)
1137 { }
1138 
1139 static struct seq_operations sel_avc_cache_stats_seq_ops = {
1140 	.start		= sel_avc_stats_seq_start,
1141 	.next		= sel_avc_stats_seq_next,
1142 	.show		= sel_avc_stats_seq_show,
1143 	.stop		= sel_avc_stats_seq_stop,
1144 };
1145 
1146 static int sel_open_avc_cache_stats(struct inode *inode, struct file *file)
1147 {
1148 	return seq_open(file, &sel_avc_cache_stats_seq_ops);
1149 }
1150 
1151 static struct file_operations sel_avc_cache_stats_ops = {
1152 	.open		= sel_open_avc_cache_stats,
1153 	.read		= seq_read,
1154 	.llseek		= seq_lseek,
1155 	.release	= seq_release,
1156 };
1157 #endif
1158 
1159 static int sel_make_avc_files(struct dentry *dir)
1160 {
1161 	int i, ret = 0;
1162 	static struct tree_descr files[] = {
1163 		{ "cache_threshold",
1164 		  &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR },
1165 		{ "hash_stats", &sel_avc_hash_stats_ops, S_IRUGO },
1166 #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
1167 		{ "cache_stats", &sel_avc_cache_stats_ops, S_IRUGO },
1168 #endif
1169 	};
1170 
1171 	for (i = 0; i < sizeof (files) / sizeof (files[0]); i++) {
1172 		struct inode *inode;
1173 		struct dentry *dentry;
1174 
1175 		dentry = d_alloc_name(dir, files[i].name);
1176 		if (!dentry) {
1177 			ret = -ENOMEM;
1178 			goto err;
1179 		}
1180 
1181 		inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
1182 		if (!inode) {
1183 			ret = -ENOMEM;
1184 			goto err;
1185 		}
1186 		inode->i_fop = files[i].ops;
1187 		d_add(dentry, inode);
1188 	}
1189 out:
1190 	return ret;
1191 err:
1192 	d_genocide(dir);
1193 	goto out;
1194 }
1195 
1196 static int sel_make_dir(struct super_block *sb, struct dentry *dentry)
1197 {
1198 	int ret = 0;
1199 	struct inode *inode;
1200 
1201 	inode = sel_make_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO);
1202 	if (!inode) {
1203 		ret = -ENOMEM;
1204 		goto out;
1205 	}
1206 	inode->i_op = &simple_dir_inode_operations;
1207 	inode->i_fop = &simple_dir_operations;
1208 	d_add(dentry, inode);
1209 out:
1210 	return ret;
1211 }
1212 
1213 static int sel_fill_super(struct super_block * sb, void * data, int silent)
1214 {
1215 	int ret;
1216 	struct dentry *dentry;
1217 	struct inode *inode;
1218 	struct inode_security_struct *isec;
1219 
1220 	static struct tree_descr selinux_files[] = {
1221 		[SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
1222 		[SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR},
1223 		[SEL_CONTEXT] = {"context", &sel_context_ops, S_IRUGO|S_IWUGO},
1224 		[SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO},
1225 		[SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO},
1226 		[SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO},
1227 		[SEL_USER] = {"user", &transaction_ops, S_IRUGO|S_IWUGO},
1228 		[SEL_POLICYVERS] = {"policyvers", &sel_policyvers_ops, S_IRUGO},
1229 		[SEL_COMMIT_BOOLS] = {"commit_pending_bools", &sel_commit_bools_ops, S_IWUSR},
1230 		[SEL_MLS] = {"mls", &sel_mls_ops, S_IRUGO},
1231 		[SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR},
1232 		[SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO},
1233 		[SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
1234 		/* last one */ {""}
1235 	};
1236 	ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
1237 	if (ret)
1238 		return ret;
1239 
1240 	dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME);
1241 	if (!dentry)
1242 		return -ENOMEM;
1243 
1244 	inode = sel_make_inode(sb, S_IFDIR | S_IRUGO | S_IXUGO);
1245 	if (!inode)
1246 		goto out;
1247 	inode->i_op = &simple_dir_inode_operations;
1248 	inode->i_fop = &simple_dir_operations;
1249 	d_add(dentry, inode);
1250 	bool_dir = dentry;
1251 	ret = sel_make_bools();
1252 	if (ret)
1253 		goto out;
1254 
1255 	dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME);
1256 	if (!dentry)
1257 		return -ENOMEM;
1258 
1259 	inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO);
1260 	if (!inode)
1261 		goto out;
1262 	isec = (struct inode_security_struct*)inode->i_security;
1263 	isec->sid = SECINITSID_DEVNULL;
1264 	isec->sclass = SECCLASS_CHR_FILE;
1265 	isec->initialized = 1;
1266 
1267 	init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3));
1268 	d_add(dentry, inode);
1269 	selinux_null = dentry;
1270 
1271 	dentry = d_alloc_name(sb->s_root, "avc");
1272 	if (!dentry)
1273 		return -ENOMEM;
1274 
1275 	ret = sel_make_dir(sb, dentry);
1276 	if (ret)
1277 		goto out;
1278 
1279 	ret = sel_make_avc_files(dentry);
1280 	if (ret)
1281 		goto out;
1282 
1283 	return 0;
1284 out:
1285 	dput(dentry);
1286 	printk(KERN_ERR "%s:  failed while creating inodes\n", __FUNCTION__);
1287 	return -ENOMEM;
1288 }
1289 
1290 static struct super_block *sel_get_sb(struct file_system_type *fs_type,
1291 				      int flags, const char *dev_name, void *data)
1292 {
1293 	return get_sb_single(fs_type, flags, data, sel_fill_super);
1294 }
1295 
1296 static struct file_system_type sel_fs_type = {
1297 	.name		= "selinuxfs",
1298 	.get_sb		= sel_get_sb,
1299 	.kill_sb	= kill_litter_super,
1300 };
1301 
1302 struct vfsmount *selinuxfs_mount;
1303 
1304 static int __init init_sel_fs(void)
1305 {
1306 	int err;
1307 
1308 	if (!selinux_enabled)
1309 		return 0;
1310 	err = register_filesystem(&sel_fs_type);
1311 	if (!err) {
1312 		selinuxfs_mount = kern_mount(&sel_fs_type);
1313 		if (IS_ERR(selinuxfs_mount)) {
1314 			printk(KERN_ERR "selinuxfs:  could not mount!\n");
1315 			err = PTR_ERR(selinuxfs_mount);
1316 			selinuxfs_mount = NULL;
1317 		}
1318 	}
1319 	return err;
1320 }
1321 
1322 __initcall(init_sel_fs);
1323 
1324 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
1325 void exit_sel_fs(void)
1326 {
1327 	unregister_filesystem(&sel_fs_type);
1328 }
1329 #endif
1330