aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/selinuxfs.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /security/selinux/selinuxfs.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'security/selinux/selinuxfs.c')
-rw-r--r--security/selinux/selinuxfs.c939
1 files changed, 586 insertions, 353 deletions
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 79a1bb635662..35459340019e 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -28,6 +28,8 @@
28#include <linux/percpu.h> 28#include <linux/percpu.h>
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <linux/uaccess.h> 30#include <linux/uaccess.h>
31#include <linux/kobject.h>
32#include <linux/ctype.h>
31 33
32/* selinuxfs pseudo filesystem for exporting the security policy API. 34/* selinuxfs pseudo filesystem for exporting the security policy API.
33 Based on the proc code and the fs/nfsd/nfsctl.c code. */ 35 Based on the proc code and the fs/nfsd/nfsctl.c code. */
@@ -68,6 +70,8 @@ static int *bool_pending_values;
68static struct dentry *class_dir; 70static struct dentry *class_dir;
69static unsigned long last_class_ino; 71static unsigned long last_class_ino;
70 72
73static char policy_opened;
74
71/* global data for policy capabilities */ 75/* global data for policy capabilities */
72static struct dentry *policycap_dir; 76static struct dentry *policycap_dir;
73 77
@@ -110,6 +114,8 @@ enum sel_inos {
110 SEL_COMPAT_NET, /* whether to use old compat network packet controls */ 114 SEL_COMPAT_NET, /* whether to use old compat network packet controls */
111 SEL_REJECT_UNKNOWN, /* export unknown reject handling to userspace */ 115 SEL_REJECT_UNKNOWN, /* export unknown reject handling to userspace */
112 SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */ 116 SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */
117 SEL_STATUS, /* export current status using mmap() */
118 SEL_POLICY, /* allow userspace to read the in kernel policy */
113 SEL_INO_NEXT, /* The next inode number to use */ 119 SEL_INO_NEXT, /* The next inode number to use */
114}; 120};
115 121
@@ -137,19 +143,24 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
137 size_t count, loff_t *ppos) 143 size_t count, loff_t *ppos)
138 144
139{ 145{
140 char *page; 146 char *page = NULL;
141 ssize_t length; 147 ssize_t length;
142 int new_value; 148 int new_value;
143 149
150 length = -ENOMEM;
144 if (count >= PAGE_SIZE) 151 if (count >= PAGE_SIZE)
145 return -ENOMEM; 152 goto out;
146 if (*ppos != 0) { 153
147 /* No partial writes. */ 154 /* No partial writes. */
148 return -EINVAL; 155 length = EINVAL;
149 } 156 if (*ppos != 0)
157 goto out;
158
159 length = -ENOMEM;
150 page = (char *)get_zeroed_page(GFP_KERNEL); 160 page = (char *)get_zeroed_page(GFP_KERNEL);
151 if (!page) 161 if (!page)
152 return -ENOMEM; 162 goto out;
163
153 length = -EFAULT; 164 length = -EFAULT;
154 if (copy_from_user(page, buf, count)) 165 if (copy_from_user(page, buf, count))
155 goto out; 166 goto out;
@@ -171,6 +182,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
171 if (selinux_enforcing) 182 if (selinux_enforcing)
172 avc_ss_reset(0); 183 avc_ss_reset(0);
173 selnl_notify_setenforce(selinux_enforcing); 184 selnl_notify_setenforce(selinux_enforcing);
185 selinux_status_update_setenforce(selinux_enforcing);
174 } 186 }
175 length = count; 187 length = count;
176out: 188out:
@@ -205,25 +217,83 @@ static const struct file_operations sel_handle_unknown_ops = {
205 .llseek = generic_file_llseek, 217 .llseek = generic_file_llseek,
206}; 218};
207 219
220static int sel_open_handle_status(struct inode *inode, struct file *filp)
221{
222 struct page *status = selinux_kernel_status_page();
223
224 if (!status)
225 return -ENOMEM;
226
227 filp->private_data = status;
228
229 return 0;
230}
231
232static ssize_t sel_read_handle_status(struct file *filp, char __user *buf,
233 size_t count, loff_t *ppos)
234{
235 struct page *status = filp->private_data;
236
237 BUG_ON(!status);
238
239 return simple_read_from_buffer(buf, count, ppos,
240 page_address(status),
241 sizeof(struct selinux_kernel_status));
242}
243
244static int sel_mmap_handle_status(struct file *filp,
245 struct vm_area_struct *vma)
246{
247 struct page *status = filp->private_data;
248 unsigned long size = vma->vm_end - vma->vm_start;
249
250 BUG_ON(!status);
251
252 /* only allows one page from the head */
253 if (vma->vm_pgoff > 0 || size != PAGE_SIZE)
254 return -EIO;
255 /* disallow writable mapping */
256 if (vma->vm_flags & VM_WRITE)
257 return -EPERM;
258 /* disallow mprotect() turns it into writable */
259 vma->vm_flags &= ~VM_MAYWRITE;
260
261 return remap_pfn_range(vma, vma->vm_start,
262 page_to_pfn(status),
263 size, vma->vm_page_prot);
264}
265
266static const struct file_operations sel_handle_status_ops = {
267 .open = sel_open_handle_status,
268 .read = sel_read_handle_status,
269 .mmap = sel_mmap_handle_status,
270 .llseek = generic_file_llseek,
271};
272
208#ifdef CONFIG_SECURITY_SELINUX_DISABLE 273#ifdef CONFIG_SECURITY_SELINUX_DISABLE
209static ssize_t sel_write_disable(struct file *file, const char __user *buf, 274static ssize_t sel_write_disable(struct file *file, const char __user *buf,
210 size_t count, loff_t *ppos) 275 size_t count, loff_t *ppos)
211 276
212{ 277{
213 char *page; 278 char *page = NULL;
214 ssize_t length; 279 ssize_t length;
215 int new_value; 280 int new_value;
216 extern int selinux_disable(void); 281 extern int selinux_disable(void);
217 282
283 length = -ENOMEM;
218 if (count >= PAGE_SIZE) 284 if (count >= PAGE_SIZE)
219 return -ENOMEM; 285 goto out;
220 if (*ppos != 0) { 286
221 /* No partial writes. */ 287 /* No partial writes. */
222 return -EINVAL; 288 length = -EINVAL;
223 } 289 if (*ppos != 0)
290 goto out;
291
292 length = -ENOMEM;
224 page = (char *)get_zeroed_page(GFP_KERNEL); 293 page = (char *)get_zeroed_page(GFP_KERNEL);
225 if (!page) 294 if (!page)
226 return -ENOMEM; 295 goto out;
296
227 length = -EFAULT; 297 length = -EFAULT;
228 if (copy_from_user(page, buf, count)) 298 if (copy_from_user(page, buf, count))
229 goto out; 299 goto out;
@@ -234,7 +304,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
234 304
235 if (new_value) { 305 if (new_value) {
236 length = selinux_disable(); 306 length = selinux_disable();
237 if (length < 0) 307 if (length)
238 goto out; 308 goto out;
239 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, 309 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
240 "selinux=0 auid=%u ses=%u", 310 "selinux=0 auid=%u ses=%u",
@@ -296,11 +366,145 @@ static const struct file_operations sel_mls_ops = {
296 .llseek = generic_file_llseek, 366 .llseek = generic_file_llseek,
297}; 367};
298 368
369struct policy_load_memory {
370 size_t len;
371 void *data;
372};
373
374static int sel_open_policy(struct inode *inode, struct file *filp)
375{
376 struct policy_load_memory *plm = NULL;
377 int rc;
378
379 BUG_ON(filp->private_data);
380
381 mutex_lock(&sel_mutex);
382
383 rc = task_has_security(current, SECURITY__READ_POLICY);
384 if (rc)
385 goto err;
386
387 rc = -EBUSY;
388 if (policy_opened)
389 goto err;
390
391 rc = -ENOMEM;
392 plm = kzalloc(sizeof(*plm), GFP_KERNEL);
393 if (!plm)
394 goto err;
395
396 if (i_size_read(inode) != security_policydb_len()) {
397 mutex_lock(&inode->i_mutex);
398 i_size_write(inode, security_policydb_len());
399 mutex_unlock(&inode->i_mutex);
400 }
401
402 rc = security_read_policy(&plm->data, &plm->len);
403 if (rc)
404 goto err;
405
406 policy_opened = 1;
407
408 filp->private_data = plm;
409
410 mutex_unlock(&sel_mutex);
411
412 return 0;
413err:
414 mutex_unlock(&sel_mutex);
415
416 if (plm)
417 vfree(plm->data);
418 kfree(plm);
419 return rc;
420}
421
422static int sel_release_policy(struct inode *inode, struct file *filp)
423{
424 struct policy_load_memory *plm = filp->private_data;
425
426 BUG_ON(!plm);
427
428 policy_opened = 0;
429
430 vfree(plm->data);
431 kfree(plm);
432
433 return 0;
434}
435
436static ssize_t sel_read_policy(struct file *filp, char __user *buf,
437 size_t count, loff_t *ppos)
438{
439 struct policy_load_memory *plm = filp->private_data;
440 int ret;
441
442 mutex_lock(&sel_mutex);
443
444 ret = task_has_security(current, SECURITY__READ_POLICY);
445 if (ret)
446 goto out;
447
448 ret = simple_read_from_buffer(buf, count, ppos, plm->data, plm->len);
449out:
450 mutex_unlock(&sel_mutex);
451 return ret;
452}
453
454static int sel_mmap_policy_fault(struct vm_area_struct *vma,
455 struct vm_fault *vmf)
456{
457 struct policy_load_memory *plm = vma->vm_file->private_data;
458 unsigned long offset;
459 struct page *page;
460
461 if (vmf->flags & (FAULT_FLAG_MKWRITE | FAULT_FLAG_WRITE))
462 return VM_FAULT_SIGBUS;
463
464 offset = vmf->pgoff << PAGE_SHIFT;
465 if (offset >= roundup(plm->len, PAGE_SIZE))
466 return VM_FAULT_SIGBUS;
467
468 page = vmalloc_to_page(plm->data + offset);
469 get_page(page);
470
471 vmf->page = page;
472
473 return 0;
474}
475
476static struct vm_operations_struct sel_mmap_policy_ops = {
477 .fault = sel_mmap_policy_fault,
478 .page_mkwrite = sel_mmap_policy_fault,
479};
480
481int sel_mmap_policy(struct file *filp, struct vm_area_struct *vma)
482{
483 if (vma->vm_flags & VM_SHARED) {
484 /* do not allow mprotect to make mapping writable */
485 vma->vm_flags &= ~VM_MAYWRITE;
486
487 if (vma->vm_flags & VM_WRITE)
488 return -EACCES;
489 }
490
491 vma->vm_flags |= VM_RESERVED;
492 vma->vm_ops = &sel_mmap_policy_ops;
493
494 return 0;
495}
496
497static const struct file_operations sel_policy_ops = {
498 .open = sel_open_policy,
499 .read = sel_read_policy,
500 .mmap = sel_mmap_policy,
501 .release = sel_release_policy,
502};
503
299static ssize_t sel_write_load(struct file *file, const char __user *buf, 504static ssize_t sel_write_load(struct file *file, const char __user *buf,
300 size_t count, loff_t *ppos) 505 size_t count, loff_t *ppos)
301 506
302{ 507{
303 int ret;
304 ssize_t length; 508 ssize_t length;
305 void *data = NULL; 509 void *data = NULL;
306 510
@@ -310,17 +514,19 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
310 if (length) 514 if (length)
311 goto out; 515 goto out;
312 516
313 if (*ppos != 0) { 517 /* No partial writes. */
314 /* No partial writes. */ 518 length = -EINVAL;
315 length = -EINVAL; 519 if (*ppos != 0)
316 goto out; 520 goto out;
317 }
318 521
319 if ((count > 64 * 1024 * 1024) 522 length = -EFBIG;
320 || (data = vmalloc(count)) == NULL) { 523 if (count > 64 * 1024 * 1024)
321 length = -ENOMEM; 524 goto out;
525
526 length = -ENOMEM;
527 data = vmalloc(count);
528 if (!data)
322 goto out; 529 goto out;
323 }
324 530
325 length = -EFAULT; 531 length = -EFAULT;
326 if (copy_from_user(data, buf, count) != 0) 532 if (copy_from_user(data, buf, count) != 0)
@@ -330,23 +536,19 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
330 if (length) 536 if (length)
331 goto out; 537 goto out;
332 538
333 ret = sel_make_bools(); 539 length = sel_make_bools();
334 if (ret) { 540 if (length)
335 length = ret;
336 goto out1; 541 goto out1;
337 }
338 542
339 ret = sel_make_classes(); 543 length = sel_make_classes();
340 if (ret) { 544 if (length)
341 length = ret;
342 goto out1; 545 goto out1;
343 }
344 546
345 ret = sel_make_policycap(); 547 length = sel_make_policycap();
346 if (ret) 548 if (length)
347 length = ret; 549 goto out1;
348 else 550
349 length = count; 551 length = count;
350 552
351out1: 553out1:
352 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, 554 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
@@ -366,26 +568,26 @@ static const struct file_operations sel_load_ops = {
366 568
367static ssize_t sel_write_context(struct file *file, char *buf, size_t size) 569static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
368{ 570{
369 char *canon; 571 char *canon = NULL;
370 u32 sid, len; 572 u32 sid, len;
371 ssize_t length; 573 ssize_t length;
372 574
373 length = task_has_security(current, SECURITY__CHECK_CONTEXT); 575 length = task_has_security(current, SECURITY__CHECK_CONTEXT);
374 if (length) 576 if (length)
375 return length; 577 goto out;
376 578
377 length = security_context_to_sid(buf, size, &sid); 579 length = security_context_to_sid(buf, size, &sid);
378 if (length < 0) 580 if (length)
379 return length; 581 goto out;
380 582
381 length = security_sid_to_context(sid, &canon, &len); 583 length = security_sid_to_context(sid, &canon, &len);
382 if (length < 0) 584 if (length)
383 return length; 585 goto out;
384 586
587 length = -ERANGE;
385 if (len > SIMPLE_TRANSACTION_LIMIT) { 588 if (len > SIMPLE_TRANSACTION_LIMIT) {
386 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " 589 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds "
387 "payload max\n", __func__, len); 590 "payload max\n", __func__, len);
388 length = -ERANGE;
389 goto out; 591 goto out;
390 } 592 }
391 593
@@ -409,23 +611,28 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
409static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf, 611static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
410 size_t count, loff_t *ppos) 612 size_t count, loff_t *ppos)
411{ 613{
412 char *page; 614 char *page = NULL;
413 ssize_t length; 615 ssize_t length;
414 unsigned int new_value; 616 unsigned int new_value;
415 617
416 length = task_has_security(current, SECURITY__SETCHECKREQPROT); 618 length = task_has_security(current, SECURITY__SETCHECKREQPROT);
417 if (length) 619 if (length)
418 return length; 620 goto out;
419 621
622 length = -ENOMEM;
420 if (count >= PAGE_SIZE) 623 if (count >= PAGE_SIZE)
421 return -ENOMEM; 624 goto out;
422 if (*ppos != 0) { 625
423 /* No partial writes. */ 626 /* No partial writes. */
424 return -EINVAL; 627 length = -EINVAL;
425 } 628 if (*ppos != 0)
629 goto out;
630
631 length = -ENOMEM;
426 page = (char *)get_zeroed_page(GFP_KERNEL); 632 page = (char *)get_zeroed_page(GFP_KERNEL);
427 if (!page) 633 if (!page)
428 return -ENOMEM; 634 goto out;
635
429 length = -EFAULT; 636 length = -EFAULT;
430 if (copy_from_user(page, buf, count)) 637 if (copy_from_user(page, buf, count))
431 goto out; 638 goto out;
@@ -500,7 +707,7 @@ static const struct file_operations transaction_ops = {
500 707
501static ssize_t sel_write_access(struct file *file, char *buf, size_t size) 708static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
502{ 709{
503 char *scon, *tcon; 710 char *scon = NULL, *tcon = NULL;
504 u32 ssid, tsid; 711 u32 ssid, tsid;
505 u16 tclass; 712 u16 tclass;
506 struct av_decision avd; 713 struct av_decision avd;
@@ -508,27 +715,29 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
508 715
509 length = task_has_security(current, SECURITY__COMPUTE_AV); 716 length = task_has_security(current, SECURITY__COMPUTE_AV);
510 if (length) 717 if (length)
511 return length; 718 goto out;
512 719
513 length = -ENOMEM; 720 length = -ENOMEM;
514 scon = kzalloc(size + 1, GFP_KERNEL); 721 scon = kzalloc(size + 1, GFP_KERNEL);
515 if (!scon) 722 if (!scon)
516 return length; 723 goto out;
517 724
725 length = -ENOMEM;
518 tcon = kzalloc(size + 1, GFP_KERNEL); 726 tcon = kzalloc(size + 1, GFP_KERNEL);
519 if (!tcon) 727 if (!tcon)
520 goto out; 728 goto out;
521 729
522 length = -EINVAL; 730 length = -EINVAL;
523 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 731 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
524 goto out2; 732 goto out;
525 733
526 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 734 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
527 if (length < 0) 735 if (length)
528 goto out2; 736 goto out;
737
529 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 738 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
530 if (length < 0) 739 if (length)
531 goto out2; 740 goto out;
532 741
533 security_compute_av_user(ssid, tsid, tclass, &avd); 742 security_compute_av_user(ssid, tsid, tclass, &avd);
534 743
@@ -537,133 +746,177 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
537 avd.allowed, 0xffffffff, 746 avd.allowed, 0xffffffff,
538 avd.auditallow, avd.auditdeny, 747 avd.auditallow, avd.auditdeny,
539 avd.seqno, avd.flags); 748 avd.seqno, avd.flags);
540out2:
541 kfree(tcon);
542out: 749out:
750 kfree(tcon);
543 kfree(scon); 751 kfree(scon);
544 return length; 752 return length;
545} 753}
546 754
755static inline int hexcode_to_int(int code) {
756 if (code == '\0' || !isxdigit(code))
757 return -1;
758 if (isdigit(code))
759 return code - '0';
760 return tolower(code) - 'a' + 10;
761}
762
547static ssize_t sel_write_create(struct file *file, char *buf, size_t size) 763static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
548{ 764{
549 char *scon, *tcon; 765 char *scon = NULL, *tcon = NULL;
766 char *namebuf = NULL, *objname = NULL;
550 u32 ssid, tsid, newsid; 767 u32 ssid, tsid, newsid;
551 u16 tclass; 768 u16 tclass;
552 ssize_t length; 769 ssize_t length;
553 char *newcon; 770 char *newcon = NULL;
554 u32 len; 771 u32 len;
772 int nargs;
555 773
556 length = task_has_security(current, SECURITY__COMPUTE_CREATE); 774 length = task_has_security(current, SECURITY__COMPUTE_CREATE);
557 if (length) 775 if (length)
558 return length; 776 goto out;
559 777
560 length = -ENOMEM; 778 length = -ENOMEM;
561 scon = kzalloc(size + 1, GFP_KERNEL); 779 scon = kzalloc(size + 1, GFP_KERNEL);
562 if (!scon) 780 if (!scon)
563 return length; 781 goto out;
564 782
783 length = -ENOMEM;
565 tcon = kzalloc(size + 1, GFP_KERNEL); 784 tcon = kzalloc(size + 1, GFP_KERNEL);
566 if (!tcon) 785 if (!tcon)
567 goto out; 786 goto out;
568 787
788 length = -ENOMEM;
789 namebuf = kzalloc(size + 1, GFP_KERNEL);
790 if (!namebuf)
791 goto out;
792
569 length = -EINVAL; 793 length = -EINVAL;
570 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 794 nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
571 goto out2; 795 if (nargs < 3 || nargs > 4)
796 goto out;
797 if (nargs == 4) {
798 /*
799 * If and when the name of new object to be queried contains
800 * either whitespace or multibyte characters, they shall be
801 * encoded based on the percentage-encoding rule.
802 * If not encoded, the sscanf logic picks up only left-half
803 * of the supplied name; splitted by a whitespace unexpectedly.
804 */
805 char *r, *w;
806 int c1, c2;
807
808 r = w = namebuf;
809 do {
810 c1 = *r++;
811 if (c1 == '+')
812 c1 = ' ';
813 else if (c1 == '%') {
814 if ((c1 = hexcode_to_int(*r++)) < 0)
815 goto out;
816 if ((c2 = hexcode_to_int(*r++)) < 0)
817 goto out;
818 c1 = (c1 << 4) | c2;
819 }
820 *w++ = c1;
821 } while (c1 != '\0');
822
823 objname = namebuf;
824 }
572 825
573 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 826 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
574 if (length < 0) 827 if (length)
575 goto out2; 828 goto out;
829
576 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 830 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
577 if (length < 0) 831 if (length)
578 goto out2; 832 goto out;
579 833
580 length = security_transition_sid_user(ssid, tsid, tclass, &newsid); 834 length = security_transition_sid_user(ssid, tsid, tclass,
581 if (length < 0) 835 objname, &newsid);
582 goto out2; 836 if (length)
837 goto out;
583 838
584 length = security_sid_to_context(newsid, &newcon, &len); 839 length = security_sid_to_context(newsid, &newcon, &len);
585 if (length < 0) 840 if (length)
586 goto out2; 841 goto out;
587 842
843 length = -ERANGE;
588 if (len > SIMPLE_TRANSACTION_LIMIT) { 844 if (len > SIMPLE_TRANSACTION_LIMIT) {
589 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " 845 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds "
590 "payload max\n", __func__, len); 846 "payload max\n", __func__, len);
591 length = -ERANGE; 847 goto out;
592 goto out3;
593 } 848 }
594 849
595 memcpy(buf, newcon, len); 850 memcpy(buf, newcon, len);
596 length = len; 851 length = len;
597out3: 852out:
598 kfree(newcon); 853 kfree(newcon);
599out2: 854 kfree(namebuf);
600 kfree(tcon); 855 kfree(tcon);
601out:
602 kfree(scon); 856 kfree(scon);
603 return length; 857 return length;
604} 858}
605 859
606static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size) 860static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
607{ 861{
608 char *scon, *tcon; 862 char *scon = NULL, *tcon = NULL;
609 u32 ssid, tsid, newsid; 863 u32 ssid, tsid, newsid;
610 u16 tclass; 864 u16 tclass;
611 ssize_t length; 865 ssize_t length;
612 char *newcon; 866 char *newcon = NULL;
613 u32 len; 867 u32 len;
614 868
615 length = task_has_security(current, SECURITY__COMPUTE_RELABEL); 869 length = task_has_security(current, SECURITY__COMPUTE_RELABEL);
616 if (length) 870 if (length)
617 return length; 871 goto out;
618 872
619 length = -ENOMEM; 873 length = -ENOMEM;
620 scon = kzalloc(size + 1, GFP_KERNEL); 874 scon = kzalloc(size + 1, GFP_KERNEL);
621 if (!scon) 875 if (!scon)
622 return length; 876 goto out;
623 877
878 length = -ENOMEM;
624 tcon = kzalloc(size + 1, GFP_KERNEL); 879 tcon = kzalloc(size + 1, GFP_KERNEL);
625 if (!tcon) 880 if (!tcon)
626 goto out; 881 goto out;
627 882
628 length = -EINVAL; 883 length = -EINVAL;
629 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 884 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
630 goto out2; 885 goto out;
631 886
632 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 887 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
633 if (length < 0) 888 if (length)
634 goto out2; 889 goto out;
890
635 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 891 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
636 if (length < 0) 892 if (length)
637 goto out2; 893 goto out;
638 894
639 length = security_change_sid(ssid, tsid, tclass, &newsid); 895 length = security_change_sid(ssid, tsid, tclass, &newsid);
640 if (length < 0) 896 if (length)
641 goto out2; 897 goto out;
642 898
643 length = security_sid_to_context(newsid, &newcon, &len); 899 length = security_sid_to_context(newsid, &newcon, &len);
644 if (length < 0) 900 if (length)
645 goto out2; 901 goto out;
646 902
647 if (len > SIMPLE_TRANSACTION_LIMIT) { 903 length = -ERANGE;
648 length = -ERANGE; 904 if (len > SIMPLE_TRANSACTION_LIMIT)
649 goto out3; 905 goto out;
650 }
651 906
652 memcpy(buf, newcon, len); 907 memcpy(buf, newcon, len);
653 length = len; 908 length = len;
654out3: 909out:
655 kfree(newcon); 910 kfree(newcon);
656out2:
657 kfree(tcon); 911 kfree(tcon);
658out:
659 kfree(scon); 912 kfree(scon);
660 return length; 913 return length;
661} 914}
662 915
663static ssize_t sel_write_user(struct file *file, char *buf, size_t size) 916static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
664{ 917{
665 char *con, *user, *ptr; 918 char *con = NULL, *user = NULL, *ptr;
666 u32 sid, *sids; 919 u32 sid, *sids = NULL;
667 ssize_t length; 920 ssize_t length;
668 char *newcon; 921 char *newcon;
669 int i, rc; 922 int i, rc;
@@ -671,28 +924,29 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
671 924
672 length = task_has_security(current, SECURITY__COMPUTE_USER); 925 length = task_has_security(current, SECURITY__COMPUTE_USER);
673 if (length) 926 if (length)
674 return length; 927 goto out;
675 928
676 length = -ENOMEM; 929 length = -ENOMEM;
677 con = kzalloc(size + 1, GFP_KERNEL); 930 con = kzalloc(size + 1, GFP_KERNEL);
678 if (!con) 931 if (!con)
679 return length; 932 goto out;
680 933
934 length = -ENOMEM;
681 user = kzalloc(size + 1, GFP_KERNEL); 935 user = kzalloc(size + 1, GFP_KERNEL);
682 if (!user) 936 if (!user)
683 goto out; 937 goto out;
684 938
685 length = -EINVAL; 939 length = -EINVAL;
686 if (sscanf(buf, "%s %s", con, user) != 2) 940 if (sscanf(buf, "%s %s", con, user) != 2)
687 goto out2; 941 goto out;
688 942
689 length = security_context_to_sid(con, strlen(con) + 1, &sid); 943 length = security_context_to_sid(con, strlen(con) + 1, &sid);
690 if (length < 0) 944 if (length)
691 goto out2; 945 goto out;
692 946
693 length = security_get_user_sids(sid, user, &sids, &nsids); 947 length = security_get_user_sids(sid, user, &sids, &nsids);
694 if (length < 0) 948 if (length)
695 goto out2; 949 goto out;
696 950
697 length = sprintf(buf, "%u", nsids) + 1; 951 length = sprintf(buf, "%u", nsids) + 1;
698 ptr = buf + length; 952 ptr = buf + length;
@@ -700,82 +954,80 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
700 rc = security_sid_to_context(sids[i], &newcon, &len); 954 rc = security_sid_to_context(sids[i], &newcon, &len);
701 if (rc) { 955 if (rc) {
702 length = rc; 956 length = rc;
703 goto out3; 957 goto out;
704 } 958 }
705 if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) { 959 if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) {
706 kfree(newcon); 960 kfree(newcon);
707 length = -ERANGE; 961 length = -ERANGE;
708 goto out3; 962 goto out;
709 } 963 }
710 memcpy(ptr, newcon, len); 964 memcpy(ptr, newcon, len);
711 kfree(newcon); 965 kfree(newcon);
712 ptr += len; 966 ptr += len;
713 length += len; 967 length += len;
714 } 968 }
715out3: 969out:
716 kfree(sids); 970 kfree(sids);
717out2:
718 kfree(user); 971 kfree(user);
719out:
720 kfree(con); 972 kfree(con);
721 return length; 973 return length;
722} 974}
723 975
724static ssize_t sel_write_member(struct file *file, char *buf, size_t size) 976static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
725{ 977{
726 char *scon, *tcon; 978 char *scon = NULL, *tcon = NULL;
727 u32 ssid, tsid, newsid; 979 u32 ssid, tsid, newsid;
728 u16 tclass; 980 u16 tclass;
729 ssize_t length; 981 ssize_t length;
730 char *newcon; 982 char *newcon = NULL;
731 u32 len; 983 u32 len;
732 984
733 length = task_has_security(current, SECURITY__COMPUTE_MEMBER); 985 length = task_has_security(current, SECURITY__COMPUTE_MEMBER);
734 if (length) 986 if (length)
735 return length; 987 goto out;
736 988
737 length = -ENOMEM; 989 length = -ENOMEM;
738 scon = kzalloc(size + 1, GFP_KERNEL); 990 scon = kzalloc(size + 1, GFP_KERNEL);
739 if (!scon) 991 if (!scon)
740 return length; 992 goto out;
741 993
994 length = -ENOMEM;
742 tcon = kzalloc(size + 1, GFP_KERNEL); 995 tcon = kzalloc(size + 1, GFP_KERNEL);
743 if (!tcon) 996 if (!tcon)
744 goto out; 997 goto out;
745 998
746 length = -EINVAL; 999 length = -EINVAL;
747 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 1000 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
748 goto out2; 1001 goto out;
749 1002
750 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 1003 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
751 if (length < 0) 1004 if (length)
752 goto out2; 1005 goto out;
1006
753 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 1007 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
754 if (length < 0) 1008 if (length)
755 goto out2; 1009 goto out;
756 1010
757 length = security_member_sid(ssid, tsid, tclass, &newsid); 1011 length = security_member_sid(ssid, tsid, tclass, &newsid);
758 if (length < 0) 1012 if (length)
759 goto out2; 1013 goto out;
760 1014
761 length = security_sid_to_context(newsid, &newcon, &len); 1015 length = security_sid_to_context(newsid, &newcon, &len);
762 if (length < 0) 1016 if (length)
763 goto out2; 1017 goto out;
764 1018
1019 length = -ERANGE;
765 if (len > SIMPLE_TRANSACTION_LIMIT) { 1020 if (len > SIMPLE_TRANSACTION_LIMIT) {
766 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " 1021 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds "
767 "payload max\n", __func__, len); 1022 "payload max\n", __func__, len);
768 length = -ERANGE; 1023 goto out;
769 goto out3;
770 } 1024 }
771 1025
772 memcpy(buf, newcon, len); 1026 memcpy(buf, newcon, len);
773 length = len; 1027 length = len;
774out3: 1028out:
775 kfree(newcon); 1029 kfree(newcon);
776out2:
777 kfree(tcon); 1030 kfree(tcon);
778out:
779 kfree(scon); 1031 kfree(scon);
780 return length; 1032 return length;
781} 1033}
@@ -804,16 +1056,14 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
804 1056
805 mutex_lock(&sel_mutex); 1057 mutex_lock(&sel_mutex);
806 1058
807 if (index >= bool_num || strcmp(name, bool_pending_names[index])) { 1059 ret = -EINVAL;
808 ret = -EINVAL; 1060 if (index >= bool_num || strcmp(name, bool_pending_names[index]))
809 goto out; 1061 goto out;
810 }
811 1062
1063 ret = -ENOMEM;
812 page = (char *)get_zeroed_page(GFP_KERNEL); 1064 page = (char *)get_zeroed_page(GFP_KERNEL);
813 if (!page) { 1065 if (!page)
814 ret = -ENOMEM;
815 goto out; 1066 goto out;
816 }
817 1067
818 cur_enforcing = security_get_bool_value(index); 1068 cur_enforcing = security_get_bool_value(index);
819 if (cur_enforcing < 0) { 1069 if (cur_enforcing < 0) {
@@ -825,8 +1075,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
825 ret = simple_read_from_buffer(buf, count, ppos, page, length); 1075 ret = simple_read_from_buffer(buf, count, ppos, page, length);
826out: 1076out:
827 mutex_unlock(&sel_mutex); 1077 mutex_unlock(&sel_mutex);
828 if (page) 1078 free_page((unsigned long)page);
829 free_page((unsigned long)page);
830 return ret; 1079 return ret;
831} 1080}
832 1081
@@ -846,26 +1095,23 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
846 if (length) 1095 if (length)
847 goto out; 1096 goto out;
848 1097
849 if (index >= bool_num || strcmp(name, bool_pending_names[index])) { 1098 length = -EINVAL;
850 length = -EINVAL; 1099 if (index >= bool_num || strcmp(name, bool_pending_names[index]))
851 goto out; 1100 goto out;
852 }
853 1101
854 if (count >= PAGE_SIZE) { 1102 length = -ENOMEM;
855 length = -ENOMEM; 1103 if (count >= PAGE_SIZE)
856 goto out; 1104 goto out;
857 }
858 1105
859 if (*ppos != 0) { 1106 /* No partial writes. */
860 /* No partial writes. */ 1107 length = -EINVAL;
861 length = -EINVAL; 1108 if (*ppos != 0)
862 goto out; 1109 goto out;
863 } 1110
1111 length = -ENOMEM;
864 page = (char *)get_zeroed_page(GFP_KERNEL); 1112 page = (char *)get_zeroed_page(GFP_KERNEL);
865 if (!page) { 1113 if (!page)
866 length = -ENOMEM;
867 goto out; 1114 goto out;
868 }
869 1115
870 length = -EFAULT; 1116 length = -EFAULT;
871 if (copy_from_user(page, buf, count)) 1117 if (copy_from_user(page, buf, count))
@@ -883,8 +1129,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
883 1129
884out: 1130out:
885 mutex_unlock(&sel_mutex); 1131 mutex_unlock(&sel_mutex);
886 if (page) 1132 free_page((unsigned long) page);
887 free_page((unsigned long) page);
888 return length; 1133 return length;
889} 1134}
890 1135
@@ -908,19 +1153,19 @@ static ssize_t sel_commit_bools_write(struct file *filep,
908 if (length) 1153 if (length)
909 goto out; 1154 goto out;
910 1155
911 if (count >= PAGE_SIZE) { 1156 length = -ENOMEM;
912 length = -ENOMEM; 1157 if (count >= PAGE_SIZE)
913 goto out; 1158 goto out;
914 } 1159
915 if (*ppos != 0) { 1160 /* No partial writes. */
916 /* No partial writes. */ 1161 length = -EINVAL;
1162 if (*ppos != 0)
917 goto out; 1163 goto out;
918 } 1164
1165 length = -ENOMEM;
919 page = (char *)get_zeroed_page(GFP_KERNEL); 1166 page = (char *)get_zeroed_page(GFP_KERNEL);
920 if (!page) { 1167 if (!page)
921 length = -ENOMEM;
922 goto out; 1168 goto out;
923 }
924 1169
925 length = -EFAULT; 1170 length = -EFAULT;
926 if (copy_from_user(page, buf, count)) 1171 if (copy_from_user(page, buf, count))
@@ -930,15 +1175,16 @@ static ssize_t sel_commit_bools_write(struct file *filep,
930 if (sscanf(page, "%d", &new_value) != 1) 1175 if (sscanf(page, "%d", &new_value) != 1)
931 goto out; 1176 goto out;
932 1177
1178 length = 0;
933 if (new_value && bool_pending_values) 1179 if (new_value && bool_pending_values)
934 security_set_bools(bool_num, bool_pending_values); 1180 length = security_set_bools(bool_num, bool_pending_values);
935 1181
936 length = count; 1182 if (!length)
1183 length = count;
937 1184
938out: 1185out:
939 mutex_unlock(&sel_mutex); 1186 mutex_unlock(&sel_mutex);
940 if (page) 1187 free_page((unsigned long) page);
941 free_page((unsigned long) page);
942 return length; 1188 return length;
943} 1189}
944 1190
@@ -951,31 +1197,35 @@ static void sel_remove_entries(struct dentry *de)
951{ 1197{
952 struct list_head *node; 1198 struct list_head *node;
953 1199
954 spin_lock(&dcache_lock); 1200 spin_lock(&de->d_lock);
955 node = de->d_subdirs.next; 1201 node = de->d_subdirs.next;
956 while (node != &de->d_subdirs) { 1202 while (node != &de->d_subdirs) {
957 struct dentry *d = list_entry(node, struct dentry, d_u.d_child); 1203 struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
1204
1205 spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
958 list_del_init(node); 1206 list_del_init(node);
959 1207
960 if (d->d_inode) { 1208 if (d->d_inode) {
961 d = dget_locked(d); 1209 dget_dlock(d);
962 spin_unlock(&dcache_lock); 1210 spin_unlock(&de->d_lock);
1211 spin_unlock(&d->d_lock);
963 d_delete(d); 1212 d_delete(d);
964 simple_unlink(de->d_inode, d); 1213 simple_unlink(de->d_inode, d);
965 dput(d); 1214 dput(d);
966 spin_lock(&dcache_lock); 1215 spin_lock(&de->d_lock);
967 } 1216 } else
1217 spin_unlock(&d->d_lock);
968 node = de->d_subdirs.next; 1218 node = de->d_subdirs.next;
969 } 1219 }
970 1220
971 spin_unlock(&dcache_lock); 1221 spin_unlock(&de->d_lock);
972} 1222}
973 1223
974#define BOOL_DIR_NAME "booleans" 1224#define BOOL_DIR_NAME "booleans"
975 1225
976static int sel_make_bools(void) 1226static int sel_make_bools(void)
977{ 1227{
978 int i, ret = 0; 1228 int i, ret;
979 ssize_t len; 1229 ssize_t len;
980 struct dentry *dentry = NULL; 1230 struct dentry *dentry = NULL;
981 struct dentry *dir = bool_dir; 1231 struct dentry *dir = bool_dir;
@@ -996,38 +1246,40 @@ static int sel_make_bools(void)
996 1246
997 sel_remove_entries(dir); 1247 sel_remove_entries(dir);
998 1248
1249 ret = -ENOMEM;
999 page = (char *)get_zeroed_page(GFP_KERNEL); 1250 page = (char *)get_zeroed_page(GFP_KERNEL);
1000 if (!page) 1251 if (!page)
1001 return -ENOMEM; 1252 goto out;
1002 1253
1003 ret = security_get_bools(&num, &names, &values); 1254 ret = security_get_bools(&num, &names, &values);
1004 if (ret != 0) 1255 if (ret)
1005 goto out; 1256 goto out;
1006 1257
1007 for (i = 0; i < num; i++) { 1258 for (i = 0; i < num; i++) {
1259 ret = -ENOMEM;
1008 dentry = d_alloc_name(dir, names[i]); 1260 dentry = d_alloc_name(dir, names[i]);
1009 if (!dentry) { 1261 if (!dentry)
1010 ret = -ENOMEM; 1262 goto out;
1011 goto err; 1263
1012 } 1264 ret = -ENOMEM;
1013 inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR); 1265 inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
1014 if (!inode) { 1266 if (!inode)
1015 ret = -ENOMEM; 1267 goto out;
1016 goto err;
1017 }
1018 1268
1269 ret = -EINVAL;
1019 len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]); 1270 len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
1020 if (len < 0) { 1271 if (len < 0)
1021 ret = -EINVAL; 1272 goto out;
1022 goto err; 1273
1023 } else if (len >= PAGE_SIZE) { 1274 ret = -ENAMETOOLONG;
1024 ret = -ENAMETOOLONG; 1275 if (len >= PAGE_SIZE)
1025 goto err; 1276 goto out;
1026 } 1277
1027 isec = (struct inode_security_struct *)inode->i_security; 1278 isec = (struct inode_security_struct *)inode->i_security;
1028 ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid); 1279 ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid);
1029 if (ret) 1280 if (ret)
1030 goto err; 1281 goto out;
1282
1031 isec->sid = sid; 1283 isec->sid = sid;
1032 isec->initialized = 1; 1284 isec->initialized = 1;
1033 inode->i_fop = &sel_bool_ops; 1285 inode->i_fop = &sel_bool_ops;
@@ -1037,10 +1289,12 @@ static int sel_make_bools(void)
1037 bool_num = num; 1289 bool_num = num;
1038 bool_pending_names = names; 1290 bool_pending_names = names;
1039 bool_pending_values = values; 1291 bool_pending_values = values;
1292
1293 free_page((unsigned long)page);
1294 return 0;
1040out: 1295out:
1041 free_page((unsigned long)page); 1296 free_page((unsigned long)page);
1042 return ret; 1297
1043err:
1044 if (names) { 1298 if (names) {
1045 for (i = 0; i < num; i++) 1299 for (i = 0; i < num; i++)
1046 kfree(names[i]); 1300 kfree(names[i]);
@@ -1048,8 +1302,8 @@ err:
1048 } 1302 }
1049 kfree(values); 1303 kfree(values);
1050 sel_remove_entries(dir); 1304 sel_remove_entries(dir);
1051 ret = -ENOMEM; 1305
1052 goto out; 1306 return ret;
1053} 1307}
1054 1308
1055#define NULL_FILE_NAME "null" 1309#define NULL_FILE_NAME "null"
@@ -1071,47 +1325,41 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file,
1071 size_t count, loff_t *ppos) 1325 size_t count, loff_t *ppos)
1072 1326
1073{ 1327{
1074 char *page; 1328 char *page = NULL;
1075 ssize_t ret; 1329 ssize_t ret;
1076 int new_value; 1330 int new_value;
1077 1331
1078 if (count >= PAGE_SIZE) { 1332 ret = task_has_security(current, SECURITY__SETSECPARAM);
1079 ret = -ENOMEM; 1333 if (ret)
1080 goto out; 1334 goto out;
1081 }
1082 1335
1083 if (*ppos != 0) { 1336 ret = -ENOMEM;
1084 /* No partial writes. */ 1337 if (count >= PAGE_SIZE)
1085 ret = -EINVAL; 1338 goto out;
1339
1340 /* No partial writes. */
1341 ret = -EINVAL;
1342 if (*ppos != 0)
1086 goto out; 1343 goto out;
1087 }
1088 1344
1345 ret = -ENOMEM;
1089 page = (char *)get_zeroed_page(GFP_KERNEL); 1346 page = (char *)get_zeroed_page(GFP_KERNEL);
1090 if (!page) { 1347 if (!page)
1091 ret = -ENOMEM;
1092 goto out; 1348 goto out;
1093 }
1094 1349
1095 if (copy_from_user(page, buf, count)) { 1350 ret = -EFAULT;
1096 ret = -EFAULT; 1351 if (copy_from_user(page, buf, count))
1097 goto out_free; 1352 goto out;
1098 }
1099 1353
1100 if (sscanf(page, "%u", &new_value) != 1) { 1354 ret = -EINVAL;
1101 ret = -EINVAL; 1355 if (sscanf(page, "%u", &new_value) != 1)
1102 goto out; 1356 goto out;
1103 }
1104 1357
1105 if (new_value != avc_cache_threshold) { 1358 avc_cache_threshold = new_value;
1106 ret = task_has_security(current, SECURITY__SETSECPARAM); 1359
1107 if (ret)
1108 goto out_free;
1109 avc_cache_threshold = new_value;
1110 }
1111 ret = count; 1360 ret = count;
1112out_free:
1113 free_page((unsigned long)page);
1114out: 1361out:
1362 free_page((unsigned long)page);
1115 return ret; 1363 return ret;
1116} 1364}
1117 1365
@@ -1119,19 +1367,18 @@ static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
1119 size_t count, loff_t *ppos) 1367 size_t count, loff_t *ppos)
1120{ 1368{
1121 char *page; 1369 char *page;
1122 ssize_t ret = 0; 1370 ssize_t length;
1123 1371
1124 page = (char *)__get_free_page(GFP_KERNEL); 1372 page = (char *)__get_free_page(GFP_KERNEL);
1125 if (!page) { 1373 if (!page)
1126 ret = -ENOMEM; 1374 return -ENOMEM;
1127 goto out; 1375
1128 } 1376 length = avc_get_hash_stats(page);
1129 ret = avc_get_hash_stats(page); 1377 if (length >= 0)
1130 if (ret >= 0) 1378 length = simple_read_from_buffer(buf, count, ppos, page, length);
1131 ret = simple_read_from_buffer(buf, count, ppos, page, ret);
1132 free_page((unsigned long)page); 1379 free_page((unsigned long)page);
1133out: 1380
1134 return ret; 1381 return length;
1135} 1382}
1136 1383
1137static const struct file_operations sel_avc_cache_threshold_ops = { 1384static const struct file_operations sel_avc_cache_threshold_ops = {
@@ -1181,10 +1428,14 @@ static int sel_avc_stats_seq_show(struct seq_file *seq, void *v)
1181 if (v == SEQ_START_TOKEN) 1428 if (v == SEQ_START_TOKEN)
1182 seq_printf(seq, "lookups hits misses allocations reclaims " 1429 seq_printf(seq, "lookups hits misses allocations reclaims "
1183 "frees\n"); 1430 "frees\n");
1184 else 1431 else {
1185 seq_printf(seq, "%u %u %u %u %u %u\n", st->lookups, 1432 unsigned int lookups = st->lookups;
1186 st->hits, st->misses, st->allocations, 1433 unsigned int misses = st->misses;
1434 unsigned int hits = lookups - misses;
1435 seq_printf(seq, "%u %u %u %u %u %u\n", lookups,
1436 hits, misses, st->allocations,
1187 st->reclaims, st->frees); 1437 st->reclaims, st->frees);
1438 }
1188 return 0; 1439 return 0;
1189} 1440}
1190 1441
@@ -1213,7 +1464,7 @@ static const struct file_operations sel_avc_cache_stats_ops = {
1213 1464
1214static int sel_make_avc_files(struct dentry *dir) 1465static int sel_make_avc_files(struct dentry *dir)
1215{ 1466{
1216 int i, ret = 0; 1467 int i;
1217 static struct tree_descr files[] = { 1468 static struct tree_descr files[] = {
1218 { "cache_threshold", 1469 { "cache_threshold",
1219 &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR }, 1470 &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR },
@@ -1228,22 +1479,19 @@ static int sel_make_avc_files(struct dentry *dir)
1228 struct dentry *dentry; 1479 struct dentry *dentry;
1229 1480
1230 dentry = d_alloc_name(dir, files[i].name); 1481 dentry = d_alloc_name(dir, files[i].name);
1231 if (!dentry) { 1482 if (!dentry)
1232 ret = -ENOMEM; 1483 return -ENOMEM;
1233 goto out;
1234 }
1235 1484
1236 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode); 1485 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
1237 if (!inode) { 1486 if (!inode)
1238 ret = -ENOMEM; 1487 return -ENOMEM;
1239 goto out; 1488
1240 }
1241 inode->i_fop = files[i].ops; 1489 inode->i_fop = files[i].ops;
1242 inode->i_ino = ++sel_last_ino; 1490 inode->i_ino = ++sel_last_ino;
1243 d_add(dentry, inode); 1491 d_add(dentry, inode);
1244 } 1492 }
1245out: 1493
1246 return ret; 1494 return 0;
1247} 1495}
1248 1496
1249static ssize_t sel_read_initcon(struct file *file, char __user *buf, 1497static ssize_t sel_read_initcon(struct file *file, char __user *buf,
@@ -1257,7 +1505,7 @@ static ssize_t sel_read_initcon(struct file *file, char __user *buf,
1257 inode = file->f_path.dentry->d_inode; 1505 inode = file->f_path.dentry->d_inode;
1258 sid = inode->i_ino&SEL_INO_MASK; 1506 sid = inode->i_ino&SEL_INO_MASK;
1259 ret = security_sid_to_context(sid, &con, &len); 1507 ret = security_sid_to_context(sid, &con, &len);
1260 if (ret < 0) 1508 if (ret)
1261 return ret; 1509 return ret;
1262 1510
1263 ret = simple_read_from_buffer(buf, count, ppos, con, len); 1511 ret = simple_read_from_buffer(buf, count, ppos, con, len);
@@ -1272,28 +1520,25 @@ static const struct file_operations sel_initcon_ops = {
1272 1520
1273static int sel_make_initcon_files(struct dentry *dir) 1521static int sel_make_initcon_files(struct dentry *dir)
1274{ 1522{
1275 int i, ret = 0; 1523 int i;
1276 1524
1277 for (i = 1; i <= SECINITSID_NUM; i++) { 1525 for (i = 1; i <= SECINITSID_NUM; i++) {
1278 struct inode *inode; 1526 struct inode *inode;
1279 struct dentry *dentry; 1527 struct dentry *dentry;
1280 dentry = d_alloc_name(dir, security_get_initial_sid_context(i)); 1528 dentry = d_alloc_name(dir, security_get_initial_sid_context(i));
1281 if (!dentry) { 1529 if (!dentry)
1282 ret = -ENOMEM; 1530 return -ENOMEM;
1283 goto out;
1284 }
1285 1531
1286 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); 1532 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1287 if (!inode) { 1533 if (!inode)
1288 ret = -ENOMEM; 1534 return -ENOMEM;
1289 goto out; 1535
1290 }
1291 inode->i_fop = &sel_initcon_ops; 1536 inode->i_fop = &sel_initcon_ops;
1292 inode->i_ino = i|SEL_INITCON_INO_OFFSET; 1537 inode->i_ino = i|SEL_INITCON_INO_OFFSET;
1293 d_add(dentry, inode); 1538 d_add(dentry, inode);
1294 } 1539 }
1295out: 1540
1296 return ret; 1541 return 0;
1297} 1542}
1298 1543
1299static inline unsigned int sel_div(unsigned long a, unsigned long b) 1544static inline unsigned int sel_div(unsigned long a, unsigned long b)
@@ -1329,15 +1574,13 @@ static ssize_t sel_read_class(struct file *file, char __user *buf,
1329 unsigned long ino = file->f_path.dentry->d_inode->i_ino; 1574 unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1330 1575
1331 page = (char *)__get_free_page(GFP_KERNEL); 1576 page = (char *)__get_free_page(GFP_KERNEL);
1332 if (!page) { 1577 if (!page)
1333 rc = -ENOMEM; 1578 return -ENOMEM;
1334 goto out;
1335 }
1336 1579
1337 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino)); 1580 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino));
1338 rc = simple_read_from_buffer(buf, count, ppos, page, len); 1581 rc = simple_read_from_buffer(buf, count, ppos, page, len);
1339 free_page((unsigned long)page); 1582 free_page((unsigned long)page);
1340out: 1583
1341 return rc; 1584 return rc;
1342} 1585}
1343 1586
@@ -1354,15 +1597,13 @@ static ssize_t sel_read_perm(struct file *file, char __user *buf,
1354 unsigned long ino = file->f_path.dentry->d_inode->i_ino; 1597 unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1355 1598
1356 page = (char *)__get_free_page(GFP_KERNEL); 1599 page = (char *)__get_free_page(GFP_KERNEL);
1357 if (!page) { 1600 if (!page)
1358 rc = -ENOMEM; 1601 return -ENOMEM;
1359 goto out;
1360 }
1361 1602
1362 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_perm(ino)); 1603 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_perm(ino));
1363 rc = simple_read_from_buffer(buf, count, ppos, page, len); 1604 rc = simple_read_from_buffer(buf, count, ppos, page, len);
1364 free_page((unsigned long)page); 1605 free_page((unsigned long)page);
1365out: 1606
1366 return rc; 1607 return rc;
1367} 1608}
1368 1609
@@ -1393,39 +1634,37 @@ static const struct file_operations sel_policycap_ops = {
1393static int sel_make_perm_files(char *objclass, int classvalue, 1634static int sel_make_perm_files(char *objclass, int classvalue,
1394 struct dentry *dir) 1635 struct dentry *dir)
1395{ 1636{
1396 int i, rc = 0, nperms; 1637 int i, rc, nperms;
1397 char **perms; 1638 char **perms;
1398 1639
1399 rc = security_get_permissions(objclass, &perms, &nperms); 1640 rc = security_get_permissions(objclass, &perms, &nperms);
1400 if (rc) 1641 if (rc)
1401 goto out; 1642 return rc;
1402 1643
1403 for (i = 0; i < nperms; i++) { 1644 for (i = 0; i < nperms; i++) {
1404 struct inode *inode; 1645 struct inode *inode;
1405 struct dentry *dentry; 1646 struct dentry *dentry;
1406 1647
1648 rc = -ENOMEM;
1407 dentry = d_alloc_name(dir, perms[i]); 1649 dentry = d_alloc_name(dir, perms[i]);
1408 if (!dentry) { 1650 if (!dentry)
1409 rc = -ENOMEM; 1651 goto out;
1410 goto out1;
1411 }
1412 1652
1653 rc = -ENOMEM;
1413 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); 1654 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1414 if (!inode) { 1655 if (!inode)
1415 rc = -ENOMEM; 1656 goto out;
1416 goto out1; 1657
1417 }
1418 inode->i_fop = &sel_perm_ops; 1658 inode->i_fop = &sel_perm_ops;
1419 /* i+1 since perm values are 1-indexed */ 1659 /* i+1 since perm values are 1-indexed */
1420 inode->i_ino = sel_perm_to_ino(classvalue, i + 1); 1660 inode->i_ino = sel_perm_to_ino(classvalue, i + 1);
1421 d_add(dentry, inode); 1661 d_add(dentry, inode);
1422 } 1662 }
1423 1663 rc = 0;
1424out1: 1664out:
1425 for (i = 0; i < nperms; i++) 1665 for (i = 0; i < nperms; i++)
1426 kfree(perms[i]); 1666 kfree(perms[i]);
1427 kfree(perms); 1667 kfree(perms);
1428out:
1429 return rc; 1668 return rc;
1430} 1669}
1431 1670
@@ -1437,34 +1676,27 @@ static int sel_make_class_dir_entries(char *classname, int index,
1437 int rc; 1676 int rc;
1438 1677
1439 dentry = d_alloc_name(dir, "index"); 1678 dentry = d_alloc_name(dir, "index");
1440 if (!dentry) { 1679 if (!dentry)
1441 rc = -ENOMEM; 1680 return -ENOMEM;
1442 goto out;
1443 }
1444 1681
1445 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); 1682 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1446 if (!inode) { 1683 if (!inode)
1447 rc = -ENOMEM; 1684 return -ENOMEM;
1448 goto out;
1449 }
1450 1685
1451 inode->i_fop = &sel_class_ops; 1686 inode->i_fop = &sel_class_ops;
1452 inode->i_ino = sel_class_to_ino(index); 1687 inode->i_ino = sel_class_to_ino(index);
1453 d_add(dentry, inode); 1688 d_add(dentry, inode);
1454 1689
1455 dentry = d_alloc_name(dir, "perms"); 1690 dentry = d_alloc_name(dir, "perms");
1456 if (!dentry) { 1691 if (!dentry)
1457 rc = -ENOMEM; 1692 return -ENOMEM;
1458 goto out;
1459 }
1460 1693
1461 rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino); 1694 rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino);
1462 if (rc) 1695 if (rc)
1463 goto out; 1696 return rc;
1464 1697
1465 rc = sel_make_perm_files(classname, index, dentry); 1698 rc = sel_make_perm_files(classname, index, dentry);
1466 1699
1467out:
1468 return rc; 1700 return rc;
1469} 1701}
1470 1702
@@ -1494,15 +1726,15 @@ static void sel_remove_classes(void)
1494 1726
1495static int sel_make_classes(void) 1727static int sel_make_classes(void)
1496{ 1728{
1497 int rc = 0, nclasses, i; 1729 int rc, nclasses, i;
1498 char **classes; 1730 char **classes;
1499 1731
1500 /* delete any existing entries */ 1732 /* delete any existing entries */
1501 sel_remove_classes(); 1733 sel_remove_classes();
1502 1734
1503 rc = security_get_classes(&classes, &nclasses); 1735 rc = security_get_classes(&classes, &nclasses);
1504 if (rc < 0) 1736 if (rc)
1505 goto out; 1737 return rc;
1506 1738
1507 /* +2 since classes are 1-indexed */ 1739 /* +2 since classes are 1-indexed */
1508 last_class_ino = sel_class_to_ino(nclasses + 2); 1740 last_class_ino = sel_class_to_ino(nclasses + 2);
@@ -1510,29 +1742,27 @@ static int sel_make_classes(void)
1510 for (i = 0; i < nclasses; i++) { 1742 for (i = 0; i < nclasses; i++) {
1511 struct dentry *class_name_dir; 1743 struct dentry *class_name_dir;
1512 1744
1745 rc = -ENOMEM;
1513 class_name_dir = d_alloc_name(class_dir, classes[i]); 1746 class_name_dir = d_alloc_name(class_dir, classes[i]);
1514 if (!class_name_dir) { 1747 if (!class_name_dir)
1515 rc = -ENOMEM; 1748 goto out;
1516 goto out1;
1517 }
1518 1749
1519 rc = sel_make_dir(class_dir->d_inode, class_name_dir, 1750 rc = sel_make_dir(class_dir->d_inode, class_name_dir,
1520 &last_class_ino); 1751 &last_class_ino);
1521 if (rc) 1752 if (rc)
1522 goto out1; 1753 goto out;
1523 1754
1524 /* i+1 since class values are 1-indexed */ 1755 /* i+1 since class values are 1-indexed */
1525 rc = sel_make_class_dir_entries(classes[i], i + 1, 1756 rc = sel_make_class_dir_entries(classes[i], i + 1,
1526 class_name_dir); 1757 class_name_dir);
1527 if (rc) 1758 if (rc)
1528 goto out1; 1759 goto out;
1529 } 1760 }
1530 1761 rc = 0;
1531out1: 1762out:
1532 for (i = 0; i < nclasses; i++) 1763 for (i = 0; i < nclasses; i++)
1533 kfree(classes[i]); 1764 kfree(classes[i]);
1534 kfree(classes); 1765 kfree(classes);
1535out:
1536 return rc; 1766 return rc;
1537} 1767}
1538 1768
@@ -1569,14 +1799,12 @@ static int sel_make_policycap(void)
1569static int sel_make_dir(struct inode *dir, struct dentry *dentry, 1799static int sel_make_dir(struct inode *dir, struct dentry *dentry,
1570 unsigned long *ino) 1800 unsigned long *ino)
1571{ 1801{
1572 int ret = 0;
1573 struct inode *inode; 1802 struct inode *inode;
1574 1803
1575 inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO); 1804 inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO);
1576 if (!inode) { 1805 if (!inode)
1577 ret = -ENOMEM; 1806 return -ENOMEM;
1578 goto out; 1807
1579 }
1580 inode->i_op = &simple_dir_inode_operations; 1808 inode->i_op = &simple_dir_inode_operations;
1581 inode->i_fop = &simple_dir_operations; 1809 inode->i_fop = &simple_dir_operations;
1582 inode->i_ino = ++(*ino); 1810 inode->i_ino = ++(*ino);
@@ -1585,8 +1813,8 @@ static int sel_make_dir(struct inode *dir, struct dentry *dentry,
1585 d_add(dentry, inode); 1813 d_add(dentry, inode);
1586 /* bump link count on parent directory, too */ 1814 /* bump link count on parent directory, too */
1587 inc_nlink(dir); 1815 inc_nlink(dir);
1588out: 1816
1589 return ret; 1817 return 0;
1590} 1818}
1591 1819
1592static int sel_fill_super(struct super_block *sb, void *data, int silent) 1820static int sel_fill_super(struct super_block *sb, void *data, int silent)
@@ -1612,6 +1840,8 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1612 [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR}, 1840 [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
1613 [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO}, 1841 [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
1614 [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO}, 1842 [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
1843 [SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO},
1844 [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUSR},
1615 /* last one */ {""} 1845 /* last one */ {""}
1616 }; 1846 };
1617 ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); 1847 ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
@@ -1620,11 +1850,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1620 1850
1621 root_inode = sb->s_root->d_inode; 1851 root_inode = sb->s_root->d_inode;
1622 1852
1853 ret = -ENOMEM;
1623 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME); 1854 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME);
1624 if (!dentry) { 1855 if (!dentry)
1625 ret = -ENOMEM;
1626 goto err; 1856 goto err;
1627 }
1628 1857
1629 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1858 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1630 if (ret) 1859 if (ret)
@@ -1632,17 +1861,16 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1632 1861
1633 bool_dir = dentry; 1862 bool_dir = dentry;
1634 1863
1864 ret = -ENOMEM;
1635 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME); 1865 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME);
1636 if (!dentry) { 1866 if (!dentry)
1637 ret = -ENOMEM;
1638 goto err; 1867 goto err;
1639 }
1640 1868
1869 ret = -ENOMEM;
1641 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO); 1870 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO);
1642 if (!inode) { 1871 if (!inode)
1643 ret = -ENOMEM;
1644 goto err; 1872 goto err;
1645 } 1873
1646 inode->i_ino = ++sel_last_ino; 1874 inode->i_ino = ++sel_last_ino;
1647 isec = (struct inode_security_struct *)inode->i_security; 1875 isec = (struct inode_security_struct *)inode->i_security;
1648 isec->sid = SECINITSID_DEVNULL; 1876 isec->sid = SECINITSID_DEVNULL;
@@ -1653,11 +1881,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1653 d_add(dentry, inode); 1881 d_add(dentry, inode);
1654 selinux_null = dentry; 1882 selinux_null = dentry;
1655 1883
1884 ret = -ENOMEM;
1656 dentry = d_alloc_name(sb->s_root, "avc"); 1885 dentry = d_alloc_name(sb->s_root, "avc");
1657 if (!dentry) { 1886 if (!dentry)
1658 ret = -ENOMEM;
1659 goto err; 1887 goto err;
1660 }
1661 1888
1662 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1889 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1663 if (ret) 1890 if (ret)
@@ -1667,11 +1894,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1667 if (ret) 1894 if (ret)
1668 goto err; 1895 goto err;
1669 1896
1897 ret = -ENOMEM;
1670 dentry = d_alloc_name(sb->s_root, "initial_contexts"); 1898 dentry = d_alloc_name(sb->s_root, "initial_contexts");
1671 if (!dentry) { 1899 if (!dentry)
1672 ret = -ENOMEM;
1673 goto err; 1900 goto err;
1674 }
1675 1901
1676 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1902 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1677 if (ret) 1903 if (ret)
@@ -1681,11 +1907,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1681 if (ret) 1907 if (ret)
1682 goto err; 1908 goto err;
1683 1909
1910 ret = -ENOMEM;
1684 dentry = d_alloc_name(sb->s_root, "class"); 1911 dentry = d_alloc_name(sb->s_root, "class");
1685 if (!dentry) { 1912 if (!dentry)
1686 ret = -ENOMEM;
1687 goto err; 1913 goto err;
1688 }
1689 1914
1690 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1915 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1691 if (ret) 1916 if (ret)
@@ -1693,11 +1918,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1693 1918
1694 class_dir = dentry; 1919 class_dir = dentry;
1695 1920
1921 ret = -ENOMEM;
1696 dentry = d_alloc_name(sb->s_root, "policy_capabilities"); 1922 dentry = d_alloc_name(sb->s_root, "policy_capabilities");
1697 if (!dentry) { 1923 if (!dentry)
1698 ret = -ENOMEM;
1699 goto err; 1924 goto err;
1700 }
1701 1925
1702 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1926 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1703 if (ret) 1927 if (ret)
@@ -1705,28 +1929,27 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1705 1929
1706 policycap_dir = dentry; 1930 policycap_dir = dentry;
1707 1931
1708out: 1932 return 0;
1709 return ret;
1710err: 1933err:
1711 printk(KERN_ERR "SELinux: %s: failed while creating inodes\n", 1934 printk(KERN_ERR "SELinux: %s: failed while creating inodes\n",
1712 __func__); 1935 __func__);
1713 goto out; 1936 return ret;
1714} 1937}
1715 1938
1716static int sel_get_sb(struct file_system_type *fs_type, 1939static struct dentry *sel_mount(struct file_system_type *fs_type,
1717 int flags, const char *dev_name, void *data, 1940 int flags, const char *dev_name, void *data)
1718 struct vfsmount *mnt)
1719{ 1941{
1720 return get_sb_single(fs_type, flags, data, sel_fill_super, mnt); 1942 return mount_single(fs_type, flags, data, sel_fill_super);
1721} 1943}
1722 1944
1723static struct file_system_type sel_fs_type = { 1945static struct file_system_type sel_fs_type = {
1724 .name = "selinuxfs", 1946 .name = "selinuxfs",
1725 .get_sb = sel_get_sb, 1947 .mount = sel_mount,
1726 .kill_sb = kill_litter_super, 1948 .kill_sb = kill_litter_super,
1727}; 1949};
1728 1950
1729struct vfsmount *selinuxfs_mount; 1951struct vfsmount *selinuxfs_mount;
1952static struct kobject *selinuxfs_kobj;
1730 1953
1731static int __init init_sel_fs(void) 1954static int __init init_sel_fs(void)
1732{ 1955{
@@ -1734,15 +1957,24 @@ static int __init init_sel_fs(void)
1734 1957
1735 if (!selinux_enabled) 1958 if (!selinux_enabled)
1736 return 0; 1959 return 0;
1960
1961 selinuxfs_kobj = kobject_create_and_add("selinux", fs_kobj);
1962 if (!selinuxfs_kobj)
1963 return -ENOMEM;
1964
1737 err = register_filesystem(&sel_fs_type); 1965 err = register_filesystem(&sel_fs_type);
1738 if (!err) { 1966 if (err) {
1739 selinuxfs_mount = kern_mount(&sel_fs_type); 1967 kobject_put(selinuxfs_kobj);
1740 if (IS_ERR(selinuxfs_mount)) { 1968 return err;
1741 printk(KERN_ERR "selinuxfs: could not mount!\n");
1742 err = PTR_ERR(selinuxfs_mount);
1743 selinuxfs_mount = NULL;
1744 }
1745 } 1969 }
1970
1971 selinuxfs_mount = kern_mount(&sel_fs_type);
1972 if (IS_ERR(selinuxfs_mount)) {
1973 printk(KERN_ERR "selinuxfs: could not mount!\n");
1974 err = PTR_ERR(selinuxfs_mount);
1975 selinuxfs_mount = NULL;
1976 }
1977
1746 return err; 1978 return err;
1747} 1979}
1748 1980
@@ -1751,6 +1983,7 @@ __initcall(init_sel_fs);
1751#ifdef CONFIG_SECURITY_SELINUX_DISABLE 1983#ifdef CONFIG_SECURITY_SELINUX_DISABLE
1752void exit_sel_fs(void) 1984void exit_sel_fs(void)
1753{ 1985{
1986 kobject_put(selinuxfs_kobj);
1754 unregister_filesystem(&sel_fs_type); 1987 unregister_filesystem(&sel_fs_type);
1755} 1988}
1756#endif 1989#endif