aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-10 14:18:59 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-10 14:18:59 -0500
commite0e736fc0d33861335e2a132e4f688f7fd380c61 (patch)
treed9febe9ca1ef1e24efc5e6e1e34e412316d246bd /security/selinux
parenta08948812b30653eb2c536ae613b635a989feb6f (diff)
parentaeda4ac3efc29e4d55989abd0a73530453aa69ba (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6: (30 commits) MAINTAINERS: Add tomoyo-dev-en ML. SELinux: define permissions for DCB netlink messages encrypted-keys: style and other cleanup encrypted-keys: verify datablob size before converting to binary trusted-keys: kzalloc and other cleanup trusted-keys: additional TSS return code and other error handling syslog: check cap_syslog when dmesg_restrict Smack: Transmute labels on specified directories selinux: cache sidtab_context_to_sid results SELinux: do not compute transition labels on mountpoint labeled filesystems This patch adds a new security attribute to Smack called SMACK64EXEC. It defines label that is used while task is running. SELinux: merge policydb_index_classes and policydb_index_others selinux: convert part of the sym_val_to_name array to use flex_array selinux: convert type_val_to_struct to flex_array flex_array: fix flex_array_put_ptr macro to be valid C SELinux: do not set automatic i_ino in selinuxfs selinux: rework security_netlbl_secattr_to_sid SELinux: standardize return code handling in selinuxfs.c SELinux: standardize return code handling in selinuxfs.c SELinux: standardize return code handling in policydb.c ...
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c5
-rw-r--r--security/selinux/include/classmap.h2
-rw-r--r--security/selinux/nlmsgtab.c2
-rw-r--r--security/selinux/selinuxfs.c649
-rw-r--r--security/selinux/ss/conditional.c6
-rw-r--r--security/selinux/ss/mls.c25
-rw-r--r--security/selinux/ss/policydb.c701
-rw-r--r--security/selinux/ss/policydb.h19
-rw-r--r--security/selinux/ss/services.c425
-rw-r--r--security/selinux/ss/sidtab.c39
-rw-r--r--security/selinux/ss/sidtab.h2
11 files changed, 944 insertions, 931 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6f637d2678ac..e276eb468536 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2525,7 +2525,10 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2525 sid = tsec->sid; 2525 sid = tsec->sid;
2526 newsid = tsec->create_sid; 2526 newsid = tsec->create_sid;
2527 2527
2528 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 2528 if ((sbsec->flags & SE_SBINITIALIZED) &&
2529 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT))
2530 newsid = sbsec->mntpoint_sid;
2531 else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
2529 rc = security_transition_sid(sid, dsec->sid, 2532 rc = security_transition_sid(sid, dsec->sid,
2530 inode_mode_to_security_class(inode->i_mode), 2533 inode_mode_to_security_class(inode->i_mode),
2531 &newsid); 2534 &newsid);
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 8858d2b2d4b6..7ed3663332ec 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -142,7 +142,7 @@ struct security_class_mapping secclass_map[] = {
142 "node_bind", "name_connect", NULL } }, 142 "node_bind", "name_connect", NULL } },
143 { "memprotect", { "mmap_zero", NULL } }, 143 { "memprotect", { "mmap_zero", NULL } },
144 { "peer", { "recv", NULL } }, 144 { "peer", { "recv", NULL } },
145 { "capability2", { "mac_override", "mac_admin", NULL } }, 145 { "capability2", { "mac_override", "mac_admin", "syslog", NULL } },
146 { "kernel_service", { "use_as_override", "create_files_as", NULL } }, 146 { "kernel_service", { "use_as_override", "create_files_as", NULL } },
147 { "tun_socket", 147 { "tun_socket",
148 { COMMON_SOCK_PERMS, NULL } }, 148 { COMMON_SOCK_PERMS, NULL } },
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 75ec0c6ebacd..8b02b2137da2 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -65,6 +65,8 @@ static struct nlmsg_perm nlmsg_route_perms[] =
65 { RTM_NEWADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, 65 { RTM_NEWADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
66 { RTM_DELADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, 66 { RTM_DELADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
67 { RTM_GETADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_READ }, 67 { RTM_GETADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_READ },
68 { RTM_GETDCB, NETLINK_ROUTE_SOCKET__NLMSG_READ },
69 { RTM_SETDCB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
68}; 70};
69 71
70static struct nlmsg_perm nlmsg_firewall_perms[] = 72static struct nlmsg_perm nlmsg_firewall_perms[] =
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 43deac219491..ea39cb742ae5 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -141,19 +141,24 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
141 size_t count, loff_t *ppos) 141 size_t count, loff_t *ppos)
142 142
143{ 143{
144 char *page; 144 char *page = NULL;
145 ssize_t length; 145 ssize_t length;
146 int new_value; 146 int new_value;
147 147
148 length = -ENOMEM;
148 if (count >= PAGE_SIZE) 149 if (count >= PAGE_SIZE)
149 return -ENOMEM; 150 goto out;
150 if (*ppos != 0) { 151
151 /* No partial writes. */ 152 /* No partial writes. */
152 return -EINVAL; 153 length = EINVAL;
153 } 154 if (*ppos != 0)
155 goto out;
156
157 length = -ENOMEM;
154 page = (char *)get_zeroed_page(GFP_KERNEL); 158 page = (char *)get_zeroed_page(GFP_KERNEL);
155 if (!page) 159 if (!page)
156 return -ENOMEM; 160 goto out;
161
157 length = -EFAULT; 162 length = -EFAULT;
158 if (copy_from_user(page, buf, count)) 163 if (copy_from_user(page, buf, count))
159 goto out; 164 goto out;
@@ -268,20 +273,25 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
268 size_t count, loff_t *ppos) 273 size_t count, loff_t *ppos)
269 274
270{ 275{
271 char *page; 276 char *page = NULL;
272 ssize_t length; 277 ssize_t length;
273 int new_value; 278 int new_value;
274 extern int selinux_disable(void); 279 extern int selinux_disable(void);
275 280
281 length = -ENOMEM;
276 if (count >= PAGE_SIZE) 282 if (count >= PAGE_SIZE)
277 return -ENOMEM; 283 goto out;;
278 if (*ppos != 0) { 284
279 /* No partial writes. */ 285 /* No partial writes. */
280 return -EINVAL; 286 length = -EINVAL;
281 } 287 if (*ppos != 0)
288 goto out;
289
290 length = -ENOMEM;
282 page = (char *)get_zeroed_page(GFP_KERNEL); 291 page = (char *)get_zeroed_page(GFP_KERNEL);
283 if (!page) 292 if (!page)
284 return -ENOMEM; 293 goto out;
294
285 length = -EFAULT; 295 length = -EFAULT;
286 if (copy_from_user(page, buf, count)) 296 if (copy_from_user(page, buf, count))
287 goto out; 297 goto out;
@@ -292,7 +302,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
292 302
293 if (new_value) { 303 if (new_value) {
294 length = selinux_disable(); 304 length = selinux_disable();
295 if (length < 0) 305 if (length)
296 goto out; 306 goto out;
297 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, 307 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
298 "selinux=0 auid=%u ses=%u", 308 "selinux=0 auid=%u ses=%u",
@@ -493,7 +503,6 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
493 size_t count, loff_t *ppos) 503 size_t count, loff_t *ppos)
494 504
495{ 505{
496 int ret;
497 ssize_t length; 506 ssize_t length;
498 void *data = NULL; 507 void *data = NULL;
499 508
@@ -503,17 +512,19 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
503 if (length) 512 if (length)
504 goto out; 513 goto out;
505 514
506 if (*ppos != 0) { 515 /* No partial writes. */
507 /* No partial writes. */ 516 length = -EINVAL;
508 length = -EINVAL; 517 if (*ppos != 0)
509 goto out; 518 goto out;
510 }
511 519
512 if ((count > 64 * 1024 * 1024) 520 length = -EFBIG;
513 || (data = vmalloc(count)) == NULL) { 521 if (count > 64 * 1024 * 1024)
514 length = -ENOMEM; 522 goto out;
523
524 length = -ENOMEM;
525 data = vmalloc(count);
526 if (!data)
515 goto out; 527 goto out;
516 }
517 528
518 length = -EFAULT; 529 length = -EFAULT;
519 if (copy_from_user(data, buf, count) != 0) 530 if (copy_from_user(data, buf, count) != 0)
@@ -523,23 +534,19 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
523 if (length) 534 if (length)
524 goto out; 535 goto out;
525 536
526 ret = sel_make_bools(); 537 length = sel_make_bools();
527 if (ret) { 538 if (length)
528 length = ret;
529 goto out1; 539 goto out1;
530 }
531 540
532 ret = sel_make_classes(); 541 length = sel_make_classes();
533 if (ret) { 542 if (length)
534 length = ret;
535 goto out1; 543 goto out1;
536 }
537 544
538 ret = sel_make_policycap(); 545 length = sel_make_policycap();
539 if (ret) 546 if (length)
540 length = ret; 547 goto out1;
541 else 548
542 length = count; 549 length = count;
543 550
544out1: 551out1:
545 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, 552 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
@@ -559,26 +566,26 @@ static const struct file_operations sel_load_ops = {
559 566
560static ssize_t sel_write_context(struct file *file, char *buf, size_t size) 567static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
561{ 568{
562 char *canon; 569 char *canon = NULL;
563 u32 sid, len; 570 u32 sid, len;
564 ssize_t length; 571 ssize_t length;
565 572
566 length = task_has_security(current, SECURITY__CHECK_CONTEXT); 573 length = task_has_security(current, SECURITY__CHECK_CONTEXT);
567 if (length) 574 if (length)
568 return length; 575 goto out;
569 576
570 length = security_context_to_sid(buf, size, &sid); 577 length = security_context_to_sid(buf, size, &sid);
571 if (length < 0) 578 if (length)
572 return length; 579 goto out;
573 580
574 length = security_sid_to_context(sid, &canon, &len); 581 length = security_sid_to_context(sid, &canon, &len);
575 if (length < 0) 582 if (length)
576 return length; 583 goto out;
577 584
585 length = -ERANGE;
578 if (len > SIMPLE_TRANSACTION_LIMIT) { 586 if (len > SIMPLE_TRANSACTION_LIMIT) {
579 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " 587 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds "
580 "payload max\n", __func__, len); 588 "payload max\n", __func__, len);
581 length = -ERANGE;
582 goto out; 589 goto out;
583 } 590 }
584 591
@@ -602,23 +609,28 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
602static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf, 609static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
603 size_t count, loff_t *ppos) 610 size_t count, loff_t *ppos)
604{ 611{
605 char *page; 612 char *page = NULL;
606 ssize_t length; 613 ssize_t length;
607 unsigned int new_value; 614 unsigned int new_value;
608 615
609 length = task_has_security(current, SECURITY__SETCHECKREQPROT); 616 length = task_has_security(current, SECURITY__SETCHECKREQPROT);
610 if (length) 617 if (length)
611 return length; 618 goto out;
612 619
620 length = -ENOMEM;
613 if (count >= PAGE_SIZE) 621 if (count >= PAGE_SIZE)
614 return -ENOMEM; 622 goto out;
615 if (*ppos != 0) { 623
616 /* No partial writes. */ 624 /* No partial writes. */
617 return -EINVAL; 625 length = -EINVAL;
618 } 626 if (*ppos != 0)
627 goto out;
628
629 length = -ENOMEM;
619 page = (char *)get_zeroed_page(GFP_KERNEL); 630 page = (char *)get_zeroed_page(GFP_KERNEL);
620 if (!page) 631 if (!page)
621 return -ENOMEM; 632 goto out;
633
622 length = -EFAULT; 634 length = -EFAULT;
623 if (copy_from_user(page, buf, count)) 635 if (copy_from_user(page, buf, count))
624 goto out; 636 goto out;
@@ -693,7 +705,7 @@ static const struct file_operations transaction_ops = {
693 705
694static ssize_t sel_write_access(struct file *file, char *buf, size_t size) 706static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
695{ 707{
696 char *scon, *tcon; 708 char *scon = NULL, *tcon = NULL;
697 u32 ssid, tsid; 709 u32 ssid, tsid;
698 u16 tclass; 710 u16 tclass;
699 struct av_decision avd; 711 struct av_decision avd;
@@ -701,27 +713,29 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
701 713
702 length = task_has_security(current, SECURITY__COMPUTE_AV); 714 length = task_has_security(current, SECURITY__COMPUTE_AV);
703 if (length) 715 if (length)
704 return length; 716 goto out;
705 717
706 length = -ENOMEM; 718 length = -ENOMEM;
707 scon = kzalloc(size + 1, GFP_KERNEL); 719 scon = kzalloc(size + 1, GFP_KERNEL);
708 if (!scon) 720 if (!scon)
709 return length; 721 goto out;
710 722
723 length = -ENOMEM;
711 tcon = kzalloc(size + 1, GFP_KERNEL); 724 tcon = kzalloc(size + 1, GFP_KERNEL);
712 if (!tcon) 725 if (!tcon)
713 goto out; 726 goto out;
714 727
715 length = -EINVAL; 728 length = -EINVAL;
716 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 729 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
717 goto out2; 730 goto out;
718 731
719 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 732 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
720 if (length < 0) 733 if (length)
721 goto out2; 734 goto out;
735
722 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 736 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
723 if (length < 0) 737 if (length)
724 goto out2; 738 goto out;
725 739
726 security_compute_av_user(ssid, tsid, tclass, &avd); 740 security_compute_av_user(ssid, tsid, tclass, &avd);
727 741
@@ -730,133 +744,131 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
730 avd.allowed, 0xffffffff, 744 avd.allowed, 0xffffffff,
731 avd.auditallow, avd.auditdeny, 745 avd.auditallow, avd.auditdeny,
732 avd.seqno, avd.flags); 746 avd.seqno, avd.flags);
733out2:
734 kfree(tcon);
735out: 747out:
748 kfree(tcon);
736 kfree(scon); 749 kfree(scon);
737 return length; 750 return length;
738} 751}
739 752
740static ssize_t sel_write_create(struct file *file, char *buf, size_t size) 753static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
741{ 754{
742 char *scon, *tcon; 755 char *scon = NULL, *tcon = NULL;
743 u32 ssid, tsid, newsid; 756 u32 ssid, tsid, newsid;
744 u16 tclass; 757 u16 tclass;
745 ssize_t length; 758 ssize_t length;
746 char *newcon; 759 char *newcon = NULL;
747 u32 len; 760 u32 len;
748 761
749 length = task_has_security(current, SECURITY__COMPUTE_CREATE); 762 length = task_has_security(current, SECURITY__COMPUTE_CREATE);
750 if (length) 763 if (length)
751 return length; 764 goto out;
752 765
753 length = -ENOMEM; 766 length = -ENOMEM;
754 scon = kzalloc(size + 1, GFP_KERNEL); 767 scon = kzalloc(size + 1, GFP_KERNEL);
755 if (!scon) 768 if (!scon)
756 return length; 769 goto out;
757 770
771 length = -ENOMEM;
758 tcon = kzalloc(size + 1, GFP_KERNEL); 772 tcon = kzalloc(size + 1, GFP_KERNEL);
759 if (!tcon) 773 if (!tcon)
760 goto out; 774 goto out;
761 775
762 length = -EINVAL; 776 length = -EINVAL;
763 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 777 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
764 goto out2; 778 goto out;
765 779
766 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 780 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
767 if (length < 0) 781 if (length)
768 goto out2; 782 goto out;
783
769 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 784 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
770 if (length < 0) 785 if (length)
771 goto out2; 786 goto out;
772 787
773 length = security_transition_sid_user(ssid, tsid, tclass, &newsid); 788 length = security_transition_sid_user(ssid, tsid, tclass, &newsid);
774 if (length < 0) 789 if (length)
775 goto out2; 790 goto out;
776 791
777 length = security_sid_to_context(newsid, &newcon, &len); 792 length = security_sid_to_context(newsid, &newcon, &len);
778 if (length < 0) 793 if (length)
779 goto out2; 794 goto out;
780 795
796 length = -ERANGE;
781 if (len > SIMPLE_TRANSACTION_LIMIT) { 797 if (len > SIMPLE_TRANSACTION_LIMIT) {
782 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " 798 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds "
783 "payload max\n", __func__, len); 799 "payload max\n", __func__, len);
784 length = -ERANGE; 800 goto out;
785 goto out3;
786 } 801 }
787 802
788 memcpy(buf, newcon, len); 803 memcpy(buf, newcon, len);
789 length = len; 804 length = len;
790out3: 805out:
791 kfree(newcon); 806 kfree(newcon);
792out2:
793 kfree(tcon); 807 kfree(tcon);
794out:
795 kfree(scon); 808 kfree(scon);
796 return length; 809 return length;
797} 810}
798 811
799static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size) 812static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
800{ 813{
801 char *scon, *tcon; 814 char *scon = NULL, *tcon = NULL;
802 u32 ssid, tsid, newsid; 815 u32 ssid, tsid, newsid;
803 u16 tclass; 816 u16 tclass;
804 ssize_t length; 817 ssize_t length;
805 char *newcon; 818 char *newcon = NULL;
806 u32 len; 819 u32 len;
807 820
808 length = task_has_security(current, SECURITY__COMPUTE_RELABEL); 821 length = task_has_security(current, SECURITY__COMPUTE_RELABEL);
809 if (length) 822 if (length)
810 return length; 823 goto out;
811 824
812 length = -ENOMEM; 825 length = -ENOMEM;
813 scon = kzalloc(size + 1, GFP_KERNEL); 826 scon = kzalloc(size + 1, GFP_KERNEL);
814 if (!scon) 827 if (!scon)
815 return length; 828 goto out;
816 829
830 length = -ENOMEM;
817 tcon = kzalloc(size + 1, GFP_KERNEL); 831 tcon = kzalloc(size + 1, GFP_KERNEL);
818 if (!tcon) 832 if (!tcon)
819 goto out; 833 goto out;
820 834
821 length = -EINVAL; 835 length = -EINVAL;
822 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 836 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
823 goto out2; 837 goto out;
824 838
825 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 839 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
826 if (length < 0) 840 if (length)
827 goto out2; 841 goto out;
842
828 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 843 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
829 if (length < 0) 844 if (length)
830 goto out2; 845 goto out;
831 846
832 length = security_change_sid(ssid, tsid, tclass, &newsid); 847 length = security_change_sid(ssid, tsid, tclass, &newsid);
833 if (length < 0) 848 if (length)
834 goto out2; 849 goto out;
835 850
836 length = security_sid_to_context(newsid, &newcon, &len); 851 length = security_sid_to_context(newsid, &newcon, &len);
837 if (length < 0) 852 if (length)
838 goto out2; 853 goto out;
839 854
840 if (len > SIMPLE_TRANSACTION_LIMIT) { 855 length = -ERANGE;
841 length = -ERANGE; 856 if (len > SIMPLE_TRANSACTION_LIMIT)
842 goto out3; 857 goto out;
843 }
844 858
845 memcpy(buf, newcon, len); 859 memcpy(buf, newcon, len);
846 length = len; 860 length = len;
847out3: 861out:
848 kfree(newcon); 862 kfree(newcon);
849out2:
850 kfree(tcon); 863 kfree(tcon);
851out:
852 kfree(scon); 864 kfree(scon);
853 return length; 865 return length;
854} 866}
855 867
856static ssize_t sel_write_user(struct file *file, char *buf, size_t size) 868static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
857{ 869{
858 char *con, *user, *ptr; 870 char *con = NULL, *user = NULL, *ptr;
859 u32 sid, *sids; 871 u32 sid, *sids = NULL;
860 ssize_t length; 872 ssize_t length;
861 char *newcon; 873 char *newcon;
862 int i, rc; 874 int i, rc;
@@ -864,28 +876,29 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
864 876
865 length = task_has_security(current, SECURITY__COMPUTE_USER); 877 length = task_has_security(current, SECURITY__COMPUTE_USER);
866 if (length) 878 if (length)
867 return length; 879 goto out;;
868 880
869 length = -ENOMEM; 881 length = -ENOMEM;
870 con = kzalloc(size + 1, GFP_KERNEL); 882 con = kzalloc(size + 1, GFP_KERNEL);
871 if (!con) 883 if (!con)
872 return length; 884 goto out;;
873 885
886 length = -ENOMEM;
874 user = kzalloc(size + 1, GFP_KERNEL); 887 user = kzalloc(size + 1, GFP_KERNEL);
875 if (!user) 888 if (!user)
876 goto out; 889 goto out;
877 890
878 length = -EINVAL; 891 length = -EINVAL;
879 if (sscanf(buf, "%s %s", con, user) != 2) 892 if (sscanf(buf, "%s %s", con, user) != 2)
880 goto out2; 893 goto out;
881 894
882 length = security_context_to_sid(con, strlen(con) + 1, &sid); 895 length = security_context_to_sid(con, strlen(con) + 1, &sid);
883 if (length < 0) 896 if (length)
884 goto out2; 897 goto out;
885 898
886 length = security_get_user_sids(sid, user, &sids, &nsids); 899 length = security_get_user_sids(sid, user, &sids, &nsids);
887 if (length < 0) 900 if (length)
888 goto out2; 901 goto out;
889 902
890 length = sprintf(buf, "%u", nsids) + 1; 903 length = sprintf(buf, "%u", nsids) + 1;
891 ptr = buf + length; 904 ptr = buf + length;
@@ -893,82 +906,80 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
893 rc = security_sid_to_context(sids[i], &newcon, &len); 906 rc = security_sid_to_context(sids[i], &newcon, &len);
894 if (rc) { 907 if (rc) {
895 length = rc; 908 length = rc;
896 goto out3; 909 goto out;
897 } 910 }
898 if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) { 911 if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) {
899 kfree(newcon); 912 kfree(newcon);
900 length = -ERANGE; 913 length = -ERANGE;
901 goto out3; 914 goto out;
902 } 915 }
903 memcpy(ptr, newcon, len); 916 memcpy(ptr, newcon, len);
904 kfree(newcon); 917 kfree(newcon);
905 ptr += len; 918 ptr += len;
906 length += len; 919 length += len;
907 } 920 }
908out3: 921out:
909 kfree(sids); 922 kfree(sids);
910out2:
911 kfree(user); 923 kfree(user);
912out:
913 kfree(con); 924 kfree(con);
914 return length; 925 return length;
915} 926}
916 927
917static ssize_t sel_write_member(struct file *file, char *buf, size_t size) 928static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
918{ 929{
919 char *scon, *tcon; 930 char *scon = NULL, *tcon = NULL;
920 u32 ssid, tsid, newsid; 931 u32 ssid, tsid, newsid;
921 u16 tclass; 932 u16 tclass;
922 ssize_t length; 933 ssize_t length;
923 char *newcon; 934 char *newcon = NULL;
924 u32 len; 935 u32 len;
925 936
926 length = task_has_security(current, SECURITY__COMPUTE_MEMBER); 937 length = task_has_security(current, SECURITY__COMPUTE_MEMBER);
927 if (length) 938 if (length)
928 return length; 939 goto out;
929 940
930 length = -ENOMEM; 941 length = -ENOMEM;
931 scon = kzalloc(size + 1, GFP_KERNEL); 942 scon = kzalloc(size + 1, GFP_KERNEL);
932 if (!scon) 943 if (!scon)
933 return length; 944 goto out;;
934 945
946 length = -ENOMEM;
935 tcon = kzalloc(size + 1, GFP_KERNEL); 947 tcon = kzalloc(size + 1, GFP_KERNEL);
936 if (!tcon) 948 if (!tcon)
937 goto out; 949 goto out;
938 950
939 length = -EINVAL; 951 length = -EINVAL;
940 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 952 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
941 goto out2; 953 goto out;
942 954
943 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 955 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
944 if (length < 0) 956 if (length)
945 goto out2; 957 goto out;
958
946 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 959 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
947 if (length < 0) 960 if (length)
948 goto out2; 961 goto out;
949 962
950 length = security_member_sid(ssid, tsid, tclass, &newsid); 963 length = security_member_sid(ssid, tsid, tclass, &newsid);
951 if (length < 0) 964 if (length)
952 goto out2; 965 goto out;
953 966
954 length = security_sid_to_context(newsid, &newcon, &len); 967 length = security_sid_to_context(newsid, &newcon, &len);
955 if (length < 0) 968 if (length)
956 goto out2; 969 goto out;
957 970
971 length = -ERANGE;
958 if (len > SIMPLE_TRANSACTION_LIMIT) { 972 if (len > SIMPLE_TRANSACTION_LIMIT) {
959 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " 973 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds "
960 "payload max\n", __func__, len); 974 "payload max\n", __func__, len);
961 length = -ERANGE; 975 goto out;
962 goto out3;
963 } 976 }
964 977
965 memcpy(buf, newcon, len); 978 memcpy(buf, newcon, len);
966 length = len; 979 length = len;
967out3: 980out:
968 kfree(newcon); 981 kfree(newcon);
969out2:
970 kfree(tcon); 982 kfree(tcon);
971out:
972 kfree(scon); 983 kfree(scon);
973 return length; 984 return length;
974} 985}
@@ -978,7 +989,6 @@ static struct inode *sel_make_inode(struct super_block *sb, int mode)
978 struct inode *ret = new_inode(sb); 989 struct inode *ret = new_inode(sb);
979 990
980 if (ret) { 991 if (ret) {
981 ret->i_ino = get_next_ino();
982 ret->i_mode = mode; 992 ret->i_mode = mode;
983 ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; 993 ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
984 } 994 }
@@ -998,16 +1008,14 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
998 1008
999 mutex_lock(&sel_mutex); 1009 mutex_lock(&sel_mutex);
1000 1010
1001 if (index >= bool_num || strcmp(name, bool_pending_names[index])) { 1011 ret = -EINVAL;
1002 ret = -EINVAL; 1012 if (index >= bool_num || strcmp(name, bool_pending_names[index]))
1003 goto out; 1013 goto out;
1004 }
1005 1014
1015 ret = -ENOMEM;
1006 page = (char *)get_zeroed_page(GFP_KERNEL); 1016 page = (char *)get_zeroed_page(GFP_KERNEL);
1007 if (!page) { 1017 if (!page)
1008 ret = -ENOMEM;
1009 goto out; 1018 goto out;
1010 }
1011 1019
1012 cur_enforcing = security_get_bool_value(index); 1020 cur_enforcing = security_get_bool_value(index);
1013 if (cur_enforcing < 0) { 1021 if (cur_enforcing < 0) {
@@ -1019,8 +1027,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
1019 ret = simple_read_from_buffer(buf, count, ppos, page, length); 1027 ret = simple_read_from_buffer(buf, count, ppos, page, length);
1020out: 1028out:
1021 mutex_unlock(&sel_mutex); 1029 mutex_unlock(&sel_mutex);
1022 if (page) 1030 free_page((unsigned long)page);
1023 free_page((unsigned long)page);
1024 return ret; 1031 return ret;
1025} 1032}
1026 1033
@@ -1040,26 +1047,23 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
1040 if (length) 1047 if (length)
1041 goto out; 1048 goto out;
1042 1049
1043 if (index >= bool_num || strcmp(name, bool_pending_names[index])) { 1050 length = -EINVAL;
1044 length = -EINVAL; 1051 if (index >= bool_num || strcmp(name, bool_pending_names[index]))
1045 goto out; 1052 goto out;
1046 }
1047 1053
1048 if (count >= PAGE_SIZE) { 1054 length = -ENOMEM;
1049 length = -ENOMEM; 1055 if (count >= PAGE_SIZE)
1050 goto out; 1056 goto out;
1051 }
1052 1057
1053 if (*ppos != 0) { 1058 /* No partial writes. */
1054 /* No partial writes. */ 1059 length = -EINVAL;
1055 length = -EINVAL; 1060 if (*ppos != 0)
1056 goto out; 1061 goto out;
1057 } 1062
1063 length = -ENOMEM;
1058 page = (char *)get_zeroed_page(GFP_KERNEL); 1064 page = (char *)get_zeroed_page(GFP_KERNEL);
1059 if (!page) { 1065 if (!page)
1060 length = -ENOMEM;
1061 goto out; 1066 goto out;
1062 }
1063 1067
1064 length = -EFAULT; 1068 length = -EFAULT;
1065 if (copy_from_user(page, buf, count)) 1069 if (copy_from_user(page, buf, count))
@@ -1077,8 +1081,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
1077 1081
1078out: 1082out:
1079 mutex_unlock(&sel_mutex); 1083 mutex_unlock(&sel_mutex);
1080 if (page) 1084 free_page((unsigned long) page);
1081 free_page((unsigned long) page);
1082 return length; 1085 return length;
1083} 1086}
1084 1087
@@ -1102,19 +1105,19 @@ static ssize_t sel_commit_bools_write(struct file *filep,
1102 if (length) 1105 if (length)
1103 goto out; 1106 goto out;
1104 1107
1105 if (count >= PAGE_SIZE) { 1108 length = -ENOMEM;
1106 length = -ENOMEM; 1109 if (count >= PAGE_SIZE)
1107 goto out; 1110 goto out;
1108 } 1111
1109 if (*ppos != 0) { 1112 /* No partial writes. */
1110 /* No partial writes. */ 1113 length = -EINVAL;
1114 if (*ppos != 0)
1111 goto out; 1115 goto out;
1112 } 1116
1117 length = -ENOMEM;
1113 page = (char *)get_zeroed_page(GFP_KERNEL); 1118 page = (char *)get_zeroed_page(GFP_KERNEL);
1114 if (!page) { 1119 if (!page)
1115 length = -ENOMEM;
1116 goto out; 1120 goto out;
1117 }
1118 1121
1119 length = -EFAULT; 1122 length = -EFAULT;
1120 if (copy_from_user(page, buf, count)) 1123 if (copy_from_user(page, buf, count))
@@ -1124,15 +1127,16 @@ static ssize_t sel_commit_bools_write(struct file *filep,
1124 if (sscanf(page, "%d", &new_value) != 1) 1127 if (sscanf(page, "%d", &new_value) != 1)
1125 goto out; 1128 goto out;
1126 1129
1130 length = 0;
1127 if (new_value && bool_pending_values) 1131 if (new_value && bool_pending_values)
1128 security_set_bools(bool_num, bool_pending_values); 1132 length = security_set_bools(bool_num, bool_pending_values);
1129 1133
1130 length = count; 1134 if (!length)
1135 length = count;
1131 1136
1132out: 1137out:
1133 mutex_unlock(&sel_mutex); 1138 mutex_unlock(&sel_mutex);
1134 if (page) 1139 free_page((unsigned long) page);
1135 free_page((unsigned long) page);
1136 return length; 1140 return length;
1137} 1141}
1138 1142
@@ -1173,7 +1177,7 @@ static void sel_remove_entries(struct dentry *de)
1173 1177
1174static int sel_make_bools(void) 1178static int sel_make_bools(void)
1175{ 1179{
1176 int i, ret = 0; 1180 int i, ret;
1177 ssize_t len; 1181 ssize_t len;
1178 struct dentry *dentry = NULL; 1182 struct dentry *dentry = NULL;
1179 struct dentry *dir = bool_dir; 1183 struct dentry *dir = bool_dir;
@@ -1194,38 +1198,40 @@ static int sel_make_bools(void)
1194 1198
1195 sel_remove_entries(dir); 1199 sel_remove_entries(dir);
1196 1200
1201 ret = -ENOMEM;
1197 page = (char *)get_zeroed_page(GFP_KERNEL); 1202 page = (char *)get_zeroed_page(GFP_KERNEL);
1198 if (!page) 1203 if (!page)
1199 return -ENOMEM; 1204 goto out;
1200 1205
1201 ret = security_get_bools(&num, &names, &values); 1206 ret = security_get_bools(&num, &names, &values);
1202 if (ret != 0) 1207 if (ret)
1203 goto out; 1208 goto out;
1204 1209
1205 for (i = 0; i < num; i++) { 1210 for (i = 0; i < num; i++) {
1211 ret = -ENOMEM;
1206 dentry = d_alloc_name(dir, names[i]); 1212 dentry = d_alloc_name(dir, names[i]);
1207 if (!dentry) { 1213 if (!dentry)
1208 ret = -ENOMEM; 1214 goto out;
1209 goto err; 1215
1210 } 1216 ret = -ENOMEM;
1211 inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR); 1217 inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
1212 if (!inode) { 1218 if (!inode)
1213 ret = -ENOMEM; 1219 goto out;
1214 goto err;
1215 }
1216 1220
1221 ret = -EINVAL;
1217 len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]); 1222 len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
1218 if (len < 0) { 1223 if (len < 0)
1219 ret = -EINVAL; 1224 goto out;
1220 goto err; 1225
1221 } else if (len >= PAGE_SIZE) { 1226 ret = -ENAMETOOLONG;
1222 ret = -ENAMETOOLONG; 1227 if (len >= PAGE_SIZE)
1223 goto err; 1228 goto out;
1224 } 1229
1225 isec = (struct inode_security_struct *)inode->i_security; 1230 isec = (struct inode_security_struct *)inode->i_security;
1226 ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid); 1231 ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid);
1227 if (ret) 1232 if (ret)
1228 goto err; 1233 goto out;
1234
1229 isec->sid = sid; 1235 isec->sid = sid;
1230 isec->initialized = 1; 1236 isec->initialized = 1;
1231 inode->i_fop = &sel_bool_ops; 1237 inode->i_fop = &sel_bool_ops;
@@ -1235,10 +1241,12 @@ static int sel_make_bools(void)
1235 bool_num = num; 1241 bool_num = num;
1236 bool_pending_names = names; 1242 bool_pending_names = names;
1237 bool_pending_values = values; 1243 bool_pending_values = values;
1244
1245 free_page((unsigned long)page);
1246 return 0;
1238out: 1247out:
1239 free_page((unsigned long)page); 1248 free_page((unsigned long)page);
1240 return ret; 1249
1241err:
1242 if (names) { 1250 if (names) {
1243 for (i = 0; i < num; i++) 1251 for (i = 0; i < num; i++)
1244 kfree(names[i]); 1252 kfree(names[i]);
@@ -1246,8 +1254,8 @@ err:
1246 } 1254 }
1247 kfree(values); 1255 kfree(values);
1248 sel_remove_entries(dir); 1256 sel_remove_entries(dir);
1249 ret = -ENOMEM; 1257
1250 goto out; 1258 return ret;
1251} 1259}
1252 1260
1253#define NULL_FILE_NAME "null" 1261#define NULL_FILE_NAME "null"
@@ -1269,47 +1277,41 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file,
1269 size_t count, loff_t *ppos) 1277 size_t count, loff_t *ppos)
1270 1278
1271{ 1279{
1272 char *page; 1280 char *page = NULL;
1273 ssize_t ret; 1281 ssize_t ret;
1274 int new_value; 1282 int new_value;
1275 1283
1276 if (count >= PAGE_SIZE) { 1284 ret = task_has_security(current, SECURITY__SETSECPARAM);
1277 ret = -ENOMEM; 1285 if (ret)
1278 goto out; 1286 goto out;
1279 }
1280 1287
1281 if (*ppos != 0) { 1288 ret = -ENOMEM;
1282 /* No partial writes. */ 1289 if (count >= PAGE_SIZE)
1283 ret = -EINVAL;
1284 goto out; 1290 goto out;
1285 }
1286 1291
1292 /* No partial writes. */
1293 ret = -EINVAL;
1294 if (*ppos != 0)
1295 goto out;
1296
1297 ret = -ENOMEM;
1287 page = (char *)get_zeroed_page(GFP_KERNEL); 1298 page = (char *)get_zeroed_page(GFP_KERNEL);
1288 if (!page) { 1299 if (!page)
1289 ret = -ENOMEM;
1290 goto out; 1300 goto out;
1291 }
1292 1301
1293 if (copy_from_user(page, buf, count)) { 1302 ret = -EFAULT;
1294 ret = -EFAULT; 1303 if (copy_from_user(page, buf, count))
1295 goto out_free; 1304 goto out;
1296 }
1297 1305
1298 if (sscanf(page, "%u", &new_value) != 1) { 1306 ret = -EINVAL;
1299 ret = -EINVAL; 1307 if (sscanf(page, "%u", &new_value) != 1)
1300 goto out; 1308 goto out;
1301 }
1302 1309
1303 if (new_value != avc_cache_threshold) { 1310 avc_cache_threshold = new_value;
1304 ret = task_has_security(current, SECURITY__SETSECPARAM); 1311
1305 if (ret)
1306 goto out_free;
1307 avc_cache_threshold = new_value;
1308 }
1309 ret = count; 1312 ret = count;
1310out_free:
1311 free_page((unsigned long)page);
1312out: 1313out:
1314 free_page((unsigned long)page);
1313 return ret; 1315 return ret;
1314} 1316}
1315 1317
@@ -1317,19 +1319,18 @@ static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
1317 size_t count, loff_t *ppos) 1319 size_t count, loff_t *ppos)
1318{ 1320{
1319 char *page; 1321 char *page;
1320 ssize_t ret = 0; 1322 ssize_t length;
1321 1323
1322 page = (char *)__get_free_page(GFP_KERNEL); 1324 page = (char *)__get_free_page(GFP_KERNEL);
1323 if (!page) { 1325 if (!page)
1324 ret = -ENOMEM; 1326 return -ENOMEM;
1325 goto out; 1327
1326 } 1328 length = avc_get_hash_stats(page);
1327 ret = avc_get_hash_stats(page); 1329 if (length >= 0)
1328 if (ret >= 0) 1330 length = simple_read_from_buffer(buf, count, ppos, page, length);
1329 ret = simple_read_from_buffer(buf, count, ppos, page, ret);
1330 free_page((unsigned long)page); 1331 free_page((unsigned long)page);
1331out: 1332
1332 return ret; 1333 return length;
1333} 1334}
1334 1335
1335static const struct file_operations sel_avc_cache_threshold_ops = { 1336static const struct file_operations sel_avc_cache_threshold_ops = {
@@ -1411,7 +1412,7 @@ static const struct file_operations sel_avc_cache_stats_ops = {
1411 1412
1412static int sel_make_avc_files(struct dentry *dir) 1413static int sel_make_avc_files(struct dentry *dir)
1413{ 1414{
1414 int i, ret = 0; 1415 int i;
1415 static struct tree_descr files[] = { 1416 static struct tree_descr files[] = {
1416 { "cache_threshold", 1417 { "cache_threshold",
1417 &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR }, 1418 &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR },
@@ -1426,22 +1427,19 @@ static int sel_make_avc_files(struct dentry *dir)
1426 struct dentry *dentry; 1427 struct dentry *dentry;
1427 1428
1428 dentry = d_alloc_name(dir, files[i].name); 1429 dentry = d_alloc_name(dir, files[i].name);
1429 if (!dentry) { 1430 if (!dentry)
1430 ret = -ENOMEM; 1431 return -ENOMEM;
1431 goto out;
1432 }
1433 1432
1434 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode); 1433 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
1435 if (!inode) { 1434 if (!inode)
1436 ret = -ENOMEM; 1435 return -ENOMEM;
1437 goto out; 1436
1438 }
1439 inode->i_fop = files[i].ops; 1437 inode->i_fop = files[i].ops;
1440 inode->i_ino = ++sel_last_ino; 1438 inode->i_ino = ++sel_last_ino;
1441 d_add(dentry, inode); 1439 d_add(dentry, inode);
1442 } 1440 }
1443out: 1441
1444 return ret; 1442 return 0;
1445} 1443}
1446 1444
1447static ssize_t sel_read_initcon(struct file *file, char __user *buf, 1445static ssize_t sel_read_initcon(struct file *file, char __user *buf,
@@ -1455,7 +1453,7 @@ static ssize_t sel_read_initcon(struct file *file, char __user *buf,
1455 inode = file->f_path.dentry->d_inode; 1453 inode = file->f_path.dentry->d_inode;
1456 sid = inode->i_ino&SEL_INO_MASK; 1454 sid = inode->i_ino&SEL_INO_MASK;
1457 ret = security_sid_to_context(sid, &con, &len); 1455 ret = security_sid_to_context(sid, &con, &len);
1458 if (ret < 0) 1456 if (ret)
1459 return ret; 1457 return ret;
1460 1458
1461 ret = simple_read_from_buffer(buf, count, ppos, con, len); 1459 ret = simple_read_from_buffer(buf, count, ppos, con, len);
@@ -1470,28 +1468,25 @@ static const struct file_operations sel_initcon_ops = {
1470 1468
1471static int sel_make_initcon_files(struct dentry *dir) 1469static int sel_make_initcon_files(struct dentry *dir)
1472{ 1470{
1473 int i, ret = 0; 1471 int i;
1474 1472
1475 for (i = 1; i <= SECINITSID_NUM; i++) { 1473 for (i = 1; i <= SECINITSID_NUM; i++) {
1476 struct inode *inode; 1474 struct inode *inode;
1477 struct dentry *dentry; 1475 struct dentry *dentry;
1478 dentry = d_alloc_name(dir, security_get_initial_sid_context(i)); 1476 dentry = d_alloc_name(dir, security_get_initial_sid_context(i));
1479 if (!dentry) { 1477 if (!dentry)
1480 ret = -ENOMEM; 1478 return -ENOMEM;
1481 goto out;
1482 }
1483 1479
1484 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); 1480 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1485 if (!inode) { 1481 if (!inode)
1486 ret = -ENOMEM; 1482 return -ENOMEM;
1487 goto out; 1483
1488 }
1489 inode->i_fop = &sel_initcon_ops; 1484 inode->i_fop = &sel_initcon_ops;
1490 inode->i_ino = i|SEL_INITCON_INO_OFFSET; 1485 inode->i_ino = i|SEL_INITCON_INO_OFFSET;
1491 d_add(dentry, inode); 1486 d_add(dentry, inode);
1492 } 1487 }
1493out: 1488
1494 return ret; 1489 return 0;
1495} 1490}
1496 1491
1497static inline unsigned int sel_div(unsigned long a, unsigned long b) 1492static inline unsigned int sel_div(unsigned long a, unsigned long b)
@@ -1527,15 +1522,13 @@ static ssize_t sel_read_class(struct file *file, char __user *buf,
1527 unsigned long ino = file->f_path.dentry->d_inode->i_ino; 1522 unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1528 1523
1529 page = (char *)__get_free_page(GFP_KERNEL); 1524 page = (char *)__get_free_page(GFP_KERNEL);
1530 if (!page) { 1525 if (!page)
1531 rc = -ENOMEM; 1526 return -ENOMEM;
1532 goto out;
1533 }
1534 1527
1535 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino)); 1528 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino));
1536 rc = simple_read_from_buffer(buf, count, ppos, page, len); 1529 rc = simple_read_from_buffer(buf, count, ppos, page, len);
1537 free_page((unsigned long)page); 1530 free_page((unsigned long)page);
1538out: 1531
1539 return rc; 1532 return rc;
1540} 1533}
1541 1534
@@ -1552,15 +1545,13 @@ static ssize_t sel_read_perm(struct file *file, char __user *buf,
1552 unsigned long ino = file->f_path.dentry->d_inode->i_ino; 1545 unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1553 1546
1554 page = (char *)__get_free_page(GFP_KERNEL); 1547 page = (char *)__get_free_page(GFP_KERNEL);
1555 if (!page) { 1548 if (!page)
1556 rc = -ENOMEM; 1549 return -ENOMEM;
1557 goto out;
1558 }
1559 1550
1560 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_perm(ino)); 1551 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_perm(ino));
1561 rc = simple_read_from_buffer(buf, count, ppos, page, len); 1552 rc = simple_read_from_buffer(buf, count, ppos, page, len);
1562 free_page((unsigned long)page); 1553 free_page((unsigned long)page);
1563out: 1554
1564 return rc; 1555 return rc;
1565} 1556}
1566 1557
@@ -1591,39 +1582,37 @@ static const struct file_operations sel_policycap_ops = {
1591static int sel_make_perm_files(char *objclass, int classvalue, 1582static int sel_make_perm_files(char *objclass, int classvalue,
1592 struct dentry *dir) 1583 struct dentry *dir)
1593{ 1584{
1594 int i, rc = 0, nperms; 1585 int i, rc, nperms;
1595 char **perms; 1586 char **perms;
1596 1587
1597 rc = security_get_permissions(objclass, &perms, &nperms); 1588 rc = security_get_permissions(objclass, &perms, &nperms);
1598 if (rc) 1589 if (rc)
1599 goto out; 1590 return rc;
1600 1591
1601 for (i = 0; i < nperms; i++) { 1592 for (i = 0; i < nperms; i++) {
1602 struct inode *inode; 1593 struct inode *inode;
1603 struct dentry *dentry; 1594 struct dentry *dentry;
1604 1595
1596 rc = -ENOMEM;
1605 dentry = d_alloc_name(dir, perms[i]); 1597 dentry = d_alloc_name(dir, perms[i]);
1606 if (!dentry) { 1598 if (!dentry)
1607 rc = -ENOMEM; 1599 goto out;
1608 goto out1;
1609 }
1610 1600
1601 rc = -ENOMEM;
1611 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); 1602 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1612 if (!inode) { 1603 if (!inode)
1613 rc = -ENOMEM; 1604 goto out;
1614 goto out1; 1605
1615 }
1616 inode->i_fop = &sel_perm_ops; 1606 inode->i_fop = &sel_perm_ops;
1617 /* i+1 since perm values are 1-indexed */ 1607 /* i+1 since perm values are 1-indexed */
1618 inode->i_ino = sel_perm_to_ino(classvalue, i + 1); 1608 inode->i_ino = sel_perm_to_ino(classvalue, i + 1);
1619 d_add(dentry, inode); 1609 d_add(dentry, inode);
1620 } 1610 }
1621 1611 rc = 0;
1622out1: 1612out:
1623 for (i = 0; i < nperms; i++) 1613 for (i = 0; i < nperms; i++)
1624 kfree(perms[i]); 1614 kfree(perms[i]);
1625 kfree(perms); 1615 kfree(perms);
1626out:
1627 return rc; 1616 return rc;
1628} 1617}
1629 1618
@@ -1635,34 +1624,27 @@ static int sel_make_class_dir_entries(char *classname, int index,
1635 int rc; 1624 int rc;
1636 1625
1637 dentry = d_alloc_name(dir, "index"); 1626 dentry = d_alloc_name(dir, "index");
1638 if (!dentry) { 1627 if (!dentry)
1639 rc = -ENOMEM; 1628 return -ENOMEM;
1640 goto out;
1641 }
1642 1629
1643 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); 1630 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1644 if (!inode) { 1631 if (!inode)
1645 rc = -ENOMEM; 1632 return -ENOMEM;
1646 goto out;
1647 }
1648 1633
1649 inode->i_fop = &sel_class_ops; 1634 inode->i_fop = &sel_class_ops;
1650 inode->i_ino = sel_class_to_ino(index); 1635 inode->i_ino = sel_class_to_ino(index);
1651 d_add(dentry, inode); 1636 d_add(dentry, inode);
1652 1637
1653 dentry = d_alloc_name(dir, "perms"); 1638 dentry = d_alloc_name(dir, "perms");
1654 if (!dentry) { 1639 if (!dentry)
1655 rc = -ENOMEM; 1640 return -ENOMEM;
1656 goto out;
1657 }
1658 1641
1659 rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino); 1642 rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino);
1660 if (rc) 1643 if (rc)
1661 goto out; 1644 return rc;
1662 1645
1663 rc = sel_make_perm_files(classname, index, dentry); 1646 rc = sel_make_perm_files(classname, index, dentry);
1664 1647
1665out:
1666 return rc; 1648 return rc;
1667} 1649}
1668 1650
@@ -1692,15 +1674,15 @@ static void sel_remove_classes(void)
1692 1674
1693static int sel_make_classes(void) 1675static int sel_make_classes(void)
1694{ 1676{
1695 int rc = 0, nclasses, i; 1677 int rc, nclasses, i;
1696 char **classes; 1678 char **classes;
1697 1679
1698 /* delete any existing entries */ 1680 /* delete any existing entries */
1699 sel_remove_classes(); 1681 sel_remove_classes();
1700 1682
1701 rc = security_get_classes(&classes, &nclasses); 1683 rc = security_get_classes(&classes, &nclasses);
1702 if (rc < 0) 1684 if (rc)
1703 goto out; 1685 return rc;
1704 1686
1705 /* +2 since classes are 1-indexed */ 1687 /* +2 since classes are 1-indexed */
1706 last_class_ino = sel_class_to_ino(nclasses + 2); 1688 last_class_ino = sel_class_to_ino(nclasses + 2);
@@ -1708,29 +1690,27 @@ static int sel_make_classes(void)
1708 for (i = 0; i < nclasses; i++) { 1690 for (i = 0; i < nclasses; i++) {
1709 struct dentry *class_name_dir; 1691 struct dentry *class_name_dir;
1710 1692
1693 rc = -ENOMEM;
1711 class_name_dir = d_alloc_name(class_dir, classes[i]); 1694 class_name_dir = d_alloc_name(class_dir, classes[i]);
1712 if (!class_name_dir) { 1695 if (!class_name_dir)
1713 rc = -ENOMEM; 1696 goto out;
1714 goto out1;
1715 }
1716 1697
1717 rc = sel_make_dir(class_dir->d_inode, class_name_dir, 1698 rc = sel_make_dir(class_dir->d_inode, class_name_dir,
1718 &last_class_ino); 1699 &last_class_ino);
1719 if (rc) 1700 if (rc)
1720 goto out1; 1701 goto out;
1721 1702
1722 /* i+1 since class values are 1-indexed */ 1703 /* i+1 since class values are 1-indexed */
1723 rc = sel_make_class_dir_entries(classes[i], i + 1, 1704 rc = sel_make_class_dir_entries(classes[i], i + 1,
1724 class_name_dir); 1705 class_name_dir);
1725 if (rc) 1706 if (rc)
1726 goto out1; 1707 goto out;
1727 } 1708 }
1728 1709 rc = 0;
1729out1: 1710out:
1730 for (i = 0; i < nclasses; i++) 1711 for (i = 0; i < nclasses; i++)
1731 kfree(classes[i]); 1712 kfree(classes[i]);
1732 kfree(classes); 1713 kfree(classes);
1733out:
1734 return rc; 1714 return rc;
1735} 1715}
1736 1716
@@ -1767,14 +1747,12 @@ static int sel_make_policycap(void)
1767static int sel_make_dir(struct inode *dir, struct dentry *dentry, 1747static int sel_make_dir(struct inode *dir, struct dentry *dentry,
1768 unsigned long *ino) 1748 unsigned long *ino)
1769{ 1749{
1770 int ret = 0;
1771 struct inode *inode; 1750 struct inode *inode;
1772 1751
1773 inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO); 1752 inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO);
1774 if (!inode) { 1753 if (!inode)
1775 ret = -ENOMEM; 1754 return -ENOMEM;
1776 goto out; 1755
1777 }
1778 inode->i_op = &simple_dir_inode_operations; 1756 inode->i_op = &simple_dir_inode_operations;
1779 inode->i_fop = &simple_dir_operations; 1757 inode->i_fop = &simple_dir_operations;
1780 inode->i_ino = ++(*ino); 1758 inode->i_ino = ++(*ino);
@@ -1783,8 +1761,8 @@ static int sel_make_dir(struct inode *dir, struct dentry *dentry,
1783 d_add(dentry, inode); 1761 d_add(dentry, inode);
1784 /* bump link count on parent directory, too */ 1762 /* bump link count on parent directory, too */
1785 inc_nlink(dir); 1763 inc_nlink(dir);
1786out: 1764
1787 return ret; 1765 return 0;
1788} 1766}
1789 1767
1790static int sel_fill_super(struct super_block *sb, void *data, int silent) 1768static int sel_fill_super(struct super_block *sb, void *data, int silent)
@@ -1820,11 +1798,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1820 1798
1821 root_inode = sb->s_root->d_inode; 1799 root_inode = sb->s_root->d_inode;
1822 1800
1801 ret = -ENOMEM;
1823 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME); 1802 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME);
1824 if (!dentry) { 1803 if (!dentry)
1825 ret = -ENOMEM;
1826 goto err; 1804 goto err;
1827 }
1828 1805
1829 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1806 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1830 if (ret) 1807 if (ret)
@@ -1832,17 +1809,16 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1832 1809
1833 bool_dir = dentry; 1810 bool_dir = dentry;
1834 1811
1812 ret = -ENOMEM;
1835 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME); 1813 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME);
1836 if (!dentry) { 1814 if (!dentry)
1837 ret = -ENOMEM;
1838 goto err; 1815 goto err;
1839 }
1840 1816
1817 ret = -ENOMEM;
1841 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO); 1818 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO);
1842 if (!inode) { 1819 if (!inode)
1843 ret = -ENOMEM;
1844 goto err; 1820 goto err;
1845 } 1821
1846 inode->i_ino = ++sel_last_ino; 1822 inode->i_ino = ++sel_last_ino;
1847 isec = (struct inode_security_struct *)inode->i_security; 1823 isec = (struct inode_security_struct *)inode->i_security;
1848 isec->sid = SECINITSID_DEVNULL; 1824 isec->sid = SECINITSID_DEVNULL;
@@ -1853,11 +1829,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1853 d_add(dentry, inode); 1829 d_add(dentry, inode);
1854 selinux_null = dentry; 1830 selinux_null = dentry;
1855 1831
1832 ret = -ENOMEM;
1856 dentry = d_alloc_name(sb->s_root, "avc"); 1833 dentry = d_alloc_name(sb->s_root, "avc");
1857 if (!dentry) { 1834 if (!dentry)
1858 ret = -ENOMEM;
1859 goto err; 1835 goto err;
1860 }
1861 1836
1862 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1837 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1863 if (ret) 1838 if (ret)
@@ -1867,11 +1842,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1867 if (ret) 1842 if (ret)
1868 goto err; 1843 goto err;
1869 1844
1845 ret = -ENOMEM;
1870 dentry = d_alloc_name(sb->s_root, "initial_contexts"); 1846 dentry = d_alloc_name(sb->s_root, "initial_contexts");
1871 if (!dentry) { 1847 if (!dentry)
1872 ret = -ENOMEM;
1873 goto err; 1848 goto err;
1874 }
1875 1849
1876 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1850 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1877 if (ret) 1851 if (ret)
@@ -1881,11 +1855,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1881 if (ret) 1855 if (ret)
1882 goto err; 1856 goto err;
1883 1857
1858 ret = -ENOMEM;
1884 dentry = d_alloc_name(sb->s_root, "class"); 1859 dentry = d_alloc_name(sb->s_root, "class");
1885 if (!dentry) { 1860 if (!dentry)
1886 ret = -ENOMEM;
1887 goto err; 1861 goto err;
1888 }
1889 1862
1890 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1863 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1891 if (ret) 1864 if (ret)
@@ -1893,11 +1866,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1893 1866
1894 class_dir = dentry; 1867 class_dir = dentry;
1895 1868
1869 ret = -ENOMEM;
1896 dentry = d_alloc_name(sb->s_root, "policy_capabilities"); 1870 dentry = d_alloc_name(sb->s_root, "policy_capabilities");
1897 if (!dentry) { 1871 if (!dentry)
1898 ret = -ENOMEM;
1899 goto err; 1872 goto err;
1900 }
1901 1873
1902 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1874 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1903 if (ret) 1875 if (ret)
@@ -1905,12 +1877,11 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1905 1877
1906 policycap_dir = dentry; 1878 policycap_dir = dentry;
1907 1879
1908out: 1880 return 0;
1909 return ret;
1910err: 1881err:
1911 printk(KERN_ERR "SELinux: %s: failed while creating inodes\n", 1882 printk(KERN_ERR "SELinux: %s: failed while creating inodes\n",
1912 __func__); 1883 __func__);
1913 goto out; 1884 return ret;
1914} 1885}
1915 1886
1916static struct dentry *sel_mount(struct file_system_type *fs_type, 1887static struct dentry *sel_mount(struct file_system_type *fs_type,
@@ -1934,14 +1905,16 @@ static int __init init_sel_fs(void)
1934 if (!selinux_enabled) 1905 if (!selinux_enabled)
1935 return 0; 1906 return 0;
1936 err = register_filesystem(&sel_fs_type); 1907 err = register_filesystem(&sel_fs_type);
1937 if (!err) { 1908 if (err)
1938 selinuxfs_mount = kern_mount(&sel_fs_type); 1909 return err;
1939 if (IS_ERR(selinuxfs_mount)) { 1910
1940 printk(KERN_ERR "selinuxfs: could not mount!\n"); 1911 selinuxfs_mount = kern_mount(&sel_fs_type);
1941 err = PTR_ERR(selinuxfs_mount); 1912 if (IS_ERR(selinuxfs_mount)) {
1942 selinuxfs_mount = NULL; 1913 printk(KERN_ERR "selinuxfs: could not mount!\n");
1943 } 1914 err = PTR_ERR(selinuxfs_mount);
1915 selinuxfs_mount = NULL;
1944 } 1916 }
1917
1945 return err; 1918 return err;
1946} 1919}
1947 1920
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index 655fe1c6cc69..c3f845cbcd48 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -193,6 +193,7 @@ int cond_index_bool(void *key, void *datum, void *datap)
193{ 193{
194 struct policydb *p; 194 struct policydb *p;
195 struct cond_bool_datum *booldatum; 195 struct cond_bool_datum *booldatum;
196 struct flex_array *fa;
196 197
197 booldatum = datum; 198 booldatum = datum;
198 p = datap; 199 p = datap;
@@ -200,7 +201,10 @@ int cond_index_bool(void *key, void *datum, void *datap)
200 if (!booldatum->value || booldatum->value > p->p_bools.nprim) 201 if (!booldatum->value || booldatum->value > p->p_bools.nprim)
201 return -EINVAL; 202 return -EINVAL;
202 203
203 p->p_bool_val_to_name[booldatum->value - 1] = key; 204 fa = p->sym_val_to_name[SYM_BOOLS];
205 if (flex_array_put_ptr(fa, booldatum->value - 1, key,
206 GFP_KERNEL | __GFP_ZERO))
207 BUG();
204 p->bool_val_to_struct[booldatum->value - 1] = booldatum; 208 p->bool_val_to_struct[booldatum->value - 1] = booldatum;
205 209
206 return 0; 210 return 0;
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index b4eff7a60c50..1ef8e4e89880 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -45,7 +45,7 @@ int mls_compute_context_len(struct context *context)
45 len = 1; /* for the beginning ":" */ 45 len = 1; /* for the beginning ":" */
46 for (l = 0; l < 2; l++) { 46 for (l = 0; l < 2; l++) {
47 int index_sens = context->range.level[l].sens; 47 int index_sens = context->range.level[l].sens;
48 len += strlen(policydb.p_sens_val_to_name[index_sens - 1]); 48 len += strlen(sym_name(&policydb, SYM_LEVELS, index_sens - 1));
49 49
50 /* categories */ 50 /* categories */
51 head = -2; 51 head = -2;
@@ -55,17 +55,17 @@ int mls_compute_context_len(struct context *context)
55 if (i - prev > 1) { 55 if (i - prev > 1) {
56 /* one or more negative bits are skipped */ 56 /* one or more negative bits are skipped */
57 if (head != prev) { 57 if (head != prev) {
58 nm = policydb.p_cat_val_to_name[prev]; 58 nm = sym_name(&policydb, SYM_CATS, prev);
59 len += strlen(nm) + 1; 59 len += strlen(nm) + 1;
60 } 60 }
61 nm = policydb.p_cat_val_to_name[i]; 61 nm = sym_name(&policydb, SYM_CATS, i);
62 len += strlen(nm) + 1; 62 len += strlen(nm) + 1;
63 head = i; 63 head = i;
64 } 64 }
65 prev = i; 65 prev = i;
66 } 66 }
67 if (prev != head) { 67 if (prev != head) {
68 nm = policydb.p_cat_val_to_name[prev]; 68 nm = sym_name(&policydb, SYM_CATS, prev);
69 len += strlen(nm) + 1; 69 len += strlen(nm) + 1;
70 } 70 }
71 if (l == 0) { 71 if (l == 0) {
@@ -102,8 +102,8 @@ void mls_sid_to_context(struct context *context,
102 scontextp++; 102 scontextp++;
103 103
104 for (l = 0; l < 2; l++) { 104 for (l = 0; l < 2; l++) {
105 strcpy(scontextp, 105 strcpy(scontextp, sym_name(&policydb, SYM_LEVELS,
106 policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); 106 context->range.level[l].sens - 1));
107 scontextp += strlen(scontextp); 107 scontextp += strlen(scontextp);
108 108
109 /* categories */ 109 /* categories */
@@ -118,7 +118,7 @@ void mls_sid_to_context(struct context *context,
118 *scontextp++ = '.'; 118 *scontextp++ = '.';
119 else 119 else
120 *scontextp++ = ','; 120 *scontextp++ = ',';
121 nm = policydb.p_cat_val_to_name[prev]; 121 nm = sym_name(&policydb, SYM_CATS, prev);
122 strcpy(scontextp, nm); 122 strcpy(scontextp, nm);
123 scontextp += strlen(nm); 123 scontextp += strlen(nm);
124 } 124 }
@@ -126,7 +126,7 @@ void mls_sid_to_context(struct context *context,
126 *scontextp++ = ':'; 126 *scontextp++ = ':';
127 else 127 else
128 *scontextp++ = ','; 128 *scontextp++ = ',';
129 nm = policydb.p_cat_val_to_name[i]; 129 nm = sym_name(&policydb, SYM_CATS, i);
130 strcpy(scontextp, nm); 130 strcpy(scontextp, nm);
131 scontextp += strlen(nm); 131 scontextp += strlen(nm);
132 head = i; 132 head = i;
@@ -139,7 +139,7 @@ void mls_sid_to_context(struct context *context,
139 *scontextp++ = '.'; 139 *scontextp++ = '.';
140 else 140 else
141 *scontextp++ = ','; 141 *scontextp++ = ',';
142 nm = policydb.p_cat_val_to_name[prev]; 142 nm = sym_name(&policydb, SYM_CATS, prev);
143 strcpy(scontextp, nm); 143 strcpy(scontextp, nm);
144 scontextp += strlen(nm); 144 scontextp += strlen(nm);
145 } 145 }
@@ -166,7 +166,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l)
166 if (!l->sens || l->sens > p->p_levels.nprim) 166 if (!l->sens || l->sens > p->p_levels.nprim)
167 return 0; 167 return 0;
168 levdatum = hashtab_search(p->p_levels.table, 168 levdatum = hashtab_search(p->p_levels.table,
169 p->p_sens_val_to_name[l->sens - 1]); 169 sym_name(p, SYM_LEVELS, l->sens - 1));
170 if (!levdatum) 170 if (!levdatum)
171 return 0; 171 return 0;
172 172
@@ -482,7 +482,8 @@ int mls_convert_context(struct policydb *oldp,
482 482
483 for (l = 0; l < 2; l++) { 483 for (l = 0; l < 2; l++) {
484 levdatum = hashtab_search(newp->p_levels.table, 484 levdatum = hashtab_search(newp->p_levels.table,
485 oldp->p_sens_val_to_name[c->range.level[l].sens - 1]); 485 sym_name(oldp, SYM_LEVELS,
486 c->range.level[l].sens - 1));
486 487
487 if (!levdatum) 488 if (!levdatum)
488 return -EINVAL; 489 return -EINVAL;
@@ -493,7 +494,7 @@ int mls_convert_context(struct policydb *oldp,
493 int rc; 494 int rc;
494 495
495 catdatum = hashtab_search(newp->p_cats.table, 496 catdatum = hashtab_search(newp->p_cats.table,
496 oldp->p_cat_val_to_name[i]); 497 sym_name(oldp, SYM_CATS, i));
497 if (!catdatum) 498 if (!catdatum)
498 return -EINVAL; 499 return -EINVAL;
499 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); 500 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 94f630d93a5c..be9de3872837 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -148,32 +148,30 @@ static int roles_init(struct policydb *p)
148 int rc; 148 int rc;
149 struct role_datum *role; 149 struct role_datum *role;
150 150
151 rc = -ENOMEM;
151 role = kzalloc(sizeof(*role), GFP_KERNEL); 152 role = kzalloc(sizeof(*role), GFP_KERNEL);
152 if (!role) { 153 if (!role)
153 rc = -ENOMEM;
154 goto out; 154 goto out;
155 } 155
156 rc = -EINVAL;
156 role->value = ++p->p_roles.nprim; 157 role->value = ++p->p_roles.nprim;
157 if (role->value != OBJECT_R_VAL) { 158 if (role->value != OBJECT_R_VAL)
158 rc = -EINVAL; 159 goto out;
159 goto out_free_role; 160
160 } 161 rc = -ENOMEM;
161 key = kstrdup(OBJECT_R, GFP_KERNEL); 162 key = kstrdup(OBJECT_R, GFP_KERNEL);
162 if (!key) { 163 if (!key)
163 rc = -ENOMEM; 164 goto out;
164 goto out_free_role; 165
165 }
166 rc = hashtab_insert(p->p_roles.table, key, role); 166 rc = hashtab_insert(p->p_roles.table, key, role);
167 if (rc) 167 if (rc)
168 goto out_free_key; 168 goto out;
169out:
170 return rc;
171 169
172out_free_key: 170 return 0;
171out:
173 kfree(key); 172 kfree(key);
174out_free_role:
175 kfree(role); 173 kfree(role);
176 goto out; 174 return rc;
177} 175}
178 176
179static u32 rangetr_hash(struct hashtab *h, const void *k) 177static u32 rangetr_hash(struct hashtab *h, const void *k)
@@ -213,35 +211,33 @@ static int policydb_init(struct policydb *p)
213 for (i = 0; i < SYM_NUM; i++) { 211 for (i = 0; i < SYM_NUM; i++) {
214 rc = symtab_init(&p->symtab[i], symtab_sizes[i]); 212 rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
215 if (rc) 213 if (rc)
216 goto out_free_symtab; 214 goto out;
217 } 215 }
218 216
219 rc = avtab_init(&p->te_avtab); 217 rc = avtab_init(&p->te_avtab);
220 if (rc) 218 if (rc)
221 goto out_free_symtab; 219 goto out;
222 220
223 rc = roles_init(p); 221 rc = roles_init(p);
224 if (rc) 222 if (rc)
225 goto out_free_symtab; 223 goto out;
226 224
227 rc = cond_policydb_init(p); 225 rc = cond_policydb_init(p);
228 if (rc) 226 if (rc)
229 goto out_free_symtab; 227 goto out;
230 228
231 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); 229 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
232 if (!p->range_tr) 230 if (!p->range_tr)
233 goto out_free_symtab; 231 goto out;
234 232
235 ebitmap_init(&p->policycaps); 233 ebitmap_init(&p->policycaps);
236 ebitmap_init(&p->permissive_map); 234 ebitmap_init(&p->permissive_map);
237 235
236 return 0;
238out: 237out:
239 return rc;
240
241out_free_symtab:
242 for (i = 0; i < SYM_NUM; i++) 238 for (i = 0; i < SYM_NUM; i++)
243 hashtab_destroy(p->symtab[i].table); 239 hashtab_destroy(p->symtab[i].table);
244 goto out; 240 return rc;
245} 241}
246 242
247/* 243/*
@@ -258,12 +254,17 @@ static int common_index(void *key, void *datum, void *datap)
258{ 254{
259 struct policydb *p; 255 struct policydb *p;
260 struct common_datum *comdatum; 256 struct common_datum *comdatum;
257 struct flex_array *fa;
261 258
262 comdatum = datum; 259 comdatum = datum;
263 p = datap; 260 p = datap;
264 if (!comdatum->value || comdatum->value > p->p_commons.nprim) 261 if (!comdatum->value || comdatum->value > p->p_commons.nprim)
265 return -EINVAL; 262 return -EINVAL;
266 p->p_common_val_to_name[comdatum->value - 1] = key; 263
264 fa = p->sym_val_to_name[SYM_COMMONS];
265 if (flex_array_put_ptr(fa, comdatum->value - 1, key,
266 GFP_KERNEL | __GFP_ZERO))
267 BUG();
267 return 0; 268 return 0;
268} 269}
269 270
@@ -271,12 +272,16 @@ static int class_index(void *key, void *datum, void *datap)
271{ 272{
272 struct policydb *p; 273 struct policydb *p;
273 struct class_datum *cladatum; 274 struct class_datum *cladatum;
275 struct flex_array *fa;
274 276
275 cladatum = datum; 277 cladatum = datum;
276 p = datap; 278 p = datap;
277 if (!cladatum->value || cladatum->value > p->p_classes.nprim) 279 if (!cladatum->value || cladatum->value > p->p_classes.nprim)
278 return -EINVAL; 280 return -EINVAL;
279 p->p_class_val_to_name[cladatum->value - 1] = key; 281 fa = p->sym_val_to_name[SYM_CLASSES];
282 if (flex_array_put_ptr(fa, cladatum->value - 1, key,
283 GFP_KERNEL | __GFP_ZERO))
284 BUG();
280 p->class_val_to_struct[cladatum->value - 1] = cladatum; 285 p->class_val_to_struct[cladatum->value - 1] = cladatum;
281 return 0; 286 return 0;
282} 287}
@@ -285,6 +290,7 @@ static int role_index(void *key, void *datum, void *datap)
285{ 290{
286 struct policydb *p; 291 struct policydb *p;
287 struct role_datum *role; 292 struct role_datum *role;
293 struct flex_array *fa;
288 294
289 role = datum; 295 role = datum;
290 p = datap; 296 p = datap;
@@ -292,7 +298,11 @@ static int role_index(void *key, void *datum, void *datap)
292 || role->value > p->p_roles.nprim 298 || role->value > p->p_roles.nprim
293 || role->bounds > p->p_roles.nprim) 299 || role->bounds > p->p_roles.nprim)
294 return -EINVAL; 300 return -EINVAL;
295 p->p_role_val_to_name[role->value - 1] = key; 301
302 fa = p->sym_val_to_name[SYM_ROLES];
303 if (flex_array_put_ptr(fa, role->value - 1, key,
304 GFP_KERNEL | __GFP_ZERO))
305 BUG();
296 p->role_val_to_struct[role->value - 1] = role; 306 p->role_val_to_struct[role->value - 1] = role;
297 return 0; 307 return 0;
298} 308}
@@ -301,6 +311,7 @@ static int type_index(void *key, void *datum, void *datap)
301{ 311{
302 struct policydb *p; 312 struct policydb *p;
303 struct type_datum *typdatum; 313 struct type_datum *typdatum;
314 struct flex_array *fa;
304 315
305 typdatum = datum; 316 typdatum = datum;
306 p = datap; 317 p = datap;
@@ -310,8 +321,15 @@ static int type_index(void *key, void *datum, void *datap)
310 || typdatum->value > p->p_types.nprim 321 || typdatum->value > p->p_types.nprim
311 || typdatum->bounds > p->p_types.nprim) 322 || typdatum->bounds > p->p_types.nprim)
312 return -EINVAL; 323 return -EINVAL;
313 p->p_type_val_to_name[typdatum->value - 1] = key; 324 fa = p->sym_val_to_name[SYM_TYPES];
314 p->type_val_to_struct[typdatum->value - 1] = typdatum; 325 if (flex_array_put_ptr(fa, typdatum->value - 1, key,
326 GFP_KERNEL | __GFP_ZERO))
327 BUG();
328
329 fa = p->type_val_to_struct_array;
330 if (flex_array_put_ptr(fa, typdatum->value - 1, typdatum,
331 GFP_KERNEL | __GFP_ZERO))
332 BUG();
315 } 333 }
316 334
317 return 0; 335 return 0;
@@ -321,6 +339,7 @@ static int user_index(void *key, void *datum, void *datap)
321{ 339{
322 struct policydb *p; 340 struct policydb *p;
323 struct user_datum *usrdatum; 341 struct user_datum *usrdatum;
342 struct flex_array *fa;
324 343
325 usrdatum = datum; 344 usrdatum = datum;
326 p = datap; 345 p = datap;
@@ -328,7 +347,11 @@ static int user_index(void *key, void *datum, void *datap)
328 || usrdatum->value > p->p_users.nprim 347 || usrdatum->value > p->p_users.nprim
329 || usrdatum->bounds > p->p_users.nprim) 348 || usrdatum->bounds > p->p_users.nprim)
330 return -EINVAL; 349 return -EINVAL;
331 p->p_user_val_to_name[usrdatum->value - 1] = key; 350
351 fa = p->sym_val_to_name[SYM_USERS];
352 if (flex_array_put_ptr(fa, usrdatum->value - 1, key,
353 GFP_KERNEL | __GFP_ZERO))
354 BUG();
332 p->user_val_to_struct[usrdatum->value - 1] = usrdatum; 355 p->user_val_to_struct[usrdatum->value - 1] = usrdatum;
333 return 0; 356 return 0;
334} 357}
@@ -337,6 +360,7 @@ static int sens_index(void *key, void *datum, void *datap)
337{ 360{
338 struct policydb *p; 361 struct policydb *p;
339 struct level_datum *levdatum; 362 struct level_datum *levdatum;
363 struct flex_array *fa;
340 364
341 levdatum = datum; 365 levdatum = datum;
342 p = datap; 366 p = datap;
@@ -345,7 +369,10 @@ static int sens_index(void *key, void *datum, void *datap)
345 if (!levdatum->level->sens || 369 if (!levdatum->level->sens ||
346 levdatum->level->sens > p->p_levels.nprim) 370 levdatum->level->sens > p->p_levels.nprim)
347 return -EINVAL; 371 return -EINVAL;
348 p->p_sens_val_to_name[levdatum->level->sens - 1] = key; 372 fa = p->sym_val_to_name[SYM_LEVELS];
373 if (flex_array_put_ptr(fa, levdatum->level->sens - 1, key,
374 GFP_KERNEL | __GFP_ZERO))
375 BUG();
349 } 376 }
350 377
351 return 0; 378 return 0;
@@ -355,6 +382,7 @@ static int cat_index(void *key, void *datum, void *datap)
355{ 382{
356 struct policydb *p; 383 struct policydb *p;
357 struct cat_datum *catdatum; 384 struct cat_datum *catdatum;
385 struct flex_array *fa;
358 386
359 catdatum = datum; 387 catdatum = datum;
360 p = datap; 388 p = datap;
@@ -362,7 +390,10 @@ static int cat_index(void *key, void *datum, void *datap)
362 if (!catdatum->isalias) { 390 if (!catdatum->isalias) {
363 if (!catdatum->value || catdatum->value > p->p_cats.nprim) 391 if (!catdatum->value || catdatum->value > p->p_cats.nprim)
364 return -EINVAL; 392 return -EINVAL;
365 p->p_cat_val_to_name[catdatum->value - 1] = key; 393 fa = p->sym_val_to_name[SYM_CATS];
394 if (flex_array_put_ptr(fa, catdatum->value - 1, key,
395 GFP_KERNEL | __GFP_ZERO))
396 BUG();
366 } 397 }
367 398
368 return 0; 399 return 0;
@@ -380,47 +411,6 @@ static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) =
380 cat_index, 411 cat_index,
381}; 412};
382 413
383/*
384 * Define the common val_to_name array and the class
385 * val_to_name and val_to_struct arrays in a policy
386 * database structure.
387 *
388 * Caller must clean up upon failure.
389 */
390static int policydb_index_classes(struct policydb *p)
391{
392 int rc;
393
394 p->p_common_val_to_name =
395 kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL);
396 if (!p->p_common_val_to_name) {
397 rc = -ENOMEM;
398 goto out;
399 }
400
401 rc = hashtab_map(p->p_commons.table, common_index, p);
402 if (rc)
403 goto out;
404
405 p->class_val_to_struct =
406 kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), GFP_KERNEL);
407 if (!p->class_val_to_struct) {
408 rc = -ENOMEM;
409 goto out;
410 }
411
412 p->p_class_val_to_name =
413 kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL);
414 if (!p->p_class_val_to_name) {
415 rc = -ENOMEM;
416 goto out;
417 }
418
419 rc = hashtab_map(p->p_classes.table, class_index, p);
420out:
421 return rc;
422}
423
424#ifdef DEBUG_HASHES 414#ifdef DEBUG_HASHES
425static void symtab_hash_eval(struct symtab *s) 415static void symtab_hash_eval(struct symtab *s)
426{ 416{
@@ -458,9 +448,9 @@ static inline void rangetr_hash_eval(struct hashtab *h)
458 * 448 *
459 * Caller must clean up on failure. 449 * Caller must clean up on failure.
460 */ 450 */
461static int policydb_index_others(struct policydb *p) 451static int policydb_index(struct policydb *p)
462{ 452{
463 int i, rc = 0; 453 int i, rc;
464 454
465 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", 455 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools",
466 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); 456 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
@@ -477,47 +467,63 @@ static int policydb_index_others(struct policydb *p)
477 symtab_hash_eval(p->symtab); 467 symtab_hash_eval(p->symtab);
478#endif 468#endif
479 469
470 rc = -ENOMEM;
471 p->class_val_to_struct =
472 kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)),
473 GFP_KERNEL);
474 if (!p->class_val_to_struct)
475 goto out;
476
477 rc = -ENOMEM;
480 p->role_val_to_struct = 478 p->role_val_to_struct =
481 kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)), 479 kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),
482 GFP_KERNEL); 480 GFP_KERNEL);
483 if (!p->role_val_to_struct) { 481 if (!p->role_val_to_struct)
484 rc = -ENOMEM;
485 goto out; 482 goto out;
486 }
487 483
484 rc = -ENOMEM;
488 p->user_val_to_struct = 485 p->user_val_to_struct =
489 kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)), 486 kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),
490 GFP_KERNEL); 487 GFP_KERNEL);
491 if (!p->user_val_to_struct) { 488 if (!p->user_val_to_struct)
492 rc = -ENOMEM;
493 goto out; 489 goto out;
494 }
495 490
496 p->type_val_to_struct = 491 /* Yes, I want the sizeof the pointer, not the structure */
497 kmalloc(p->p_types.nprim * sizeof(*(p->type_val_to_struct)), 492 rc = -ENOMEM;
498 GFP_KERNEL); 493 p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *),
499 if (!p->type_val_to_struct) { 494 p->p_types.nprim,
500 rc = -ENOMEM; 495 GFP_KERNEL | __GFP_ZERO);
496 if (!p->type_val_to_struct_array)
501 goto out; 497 goto out;
502 }
503 498
504 if (cond_init_bool_indexes(p)) { 499 rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
505 rc = -ENOMEM; 500 p->p_types.nprim - 1, GFP_KERNEL | __GFP_ZERO);
501 if (rc)
506 goto out; 502 goto out;
507 }
508 503
509 for (i = SYM_ROLES; i < SYM_NUM; i++) { 504 rc = -ENOMEM;
510 p->sym_val_to_name[i] = 505 if (cond_init_bool_indexes(p))
511 kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL); 506 goto out;
512 if (!p->sym_val_to_name[i]) { 507
513 rc = -ENOMEM; 508 for (i = 0; i < SYM_NUM; i++) {
509 rc = -ENOMEM;
510 p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *),
511 p->symtab[i].nprim,
512 GFP_KERNEL | __GFP_ZERO);
513 if (!p->sym_val_to_name[i])
514 goto out; 514 goto out;
515 } 515
516 rc = flex_array_prealloc(p->sym_val_to_name[i],
517 0, p->symtab[i].nprim - 1,
518 GFP_KERNEL | __GFP_ZERO);
519 if (rc)
520 goto out;
521
516 rc = hashtab_map(p->symtab[i].table, index_f[i], p); 522 rc = hashtab_map(p->symtab[i].table, index_f[i], p);
517 if (rc) 523 if (rc)
518 goto out; 524 goto out;
519 } 525 }
520 526 rc = 0;
521out: 527out:
522 return rc; 528 return rc;
523} 529}
@@ -540,9 +546,11 @@ static int common_destroy(void *key, void *datum, void *p)
540 struct common_datum *comdatum; 546 struct common_datum *comdatum;
541 547
542 kfree(key); 548 kfree(key);
543 comdatum = datum; 549 if (datum) {
544 hashtab_map(comdatum->permissions.table, perm_destroy, NULL); 550 comdatum = datum;
545 hashtab_destroy(comdatum->permissions.table); 551 hashtab_map(comdatum->permissions.table, perm_destroy, NULL);
552 hashtab_destroy(comdatum->permissions.table);
553 }
546 kfree(datum); 554 kfree(datum);
547 return 0; 555 return 0;
548} 556}
@@ -554,38 +562,40 @@ static int cls_destroy(void *key, void *datum, void *p)
554 struct constraint_expr *e, *etmp; 562 struct constraint_expr *e, *etmp;
555 563
556 kfree(key); 564 kfree(key);
557 cladatum = datum; 565 if (datum) {
558 hashtab_map(cladatum->permissions.table, perm_destroy, NULL); 566 cladatum = datum;
559 hashtab_destroy(cladatum->permissions.table); 567 hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
560 constraint = cladatum->constraints; 568 hashtab_destroy(cladatum->permissions.table);
561 while (constraint) { 569 constraint = cladatum->constraints;
562 e = constraint->expr; 570 while (constraint) {
563 while (e) { 571 e = constraint->expr;
564 ebitmap_destroy(&e->names); 572 while (e) {
565 etmp = e; 573 ebitmap_destroy(&e->names);
566 e = e->next; 574 etmp = e;
567 kfree(etmp); 575 e = e->next;
576 kfree(etmp);
577 }
578 ctemp = constraint;
579 constraint = constraint->next;
580 kfree(ctemp);
568 } 581 }
569 ctemp = constraint; 582
570 constraint = constraint->next; 583 constraint = cladatum->validatetrans;
571 kfree(ctemp); 584 while (constraint) {
572 } 585 e = constraint->expr;
573 586 while (e) {
574 constraint = cladatum->validatetrans; 587 ebitmap_destroy(&e->names);
575 while (constraint) { 588 etmp = e;
576 e = constraint->expr; 589 e = e->next;
577 while (e) { 590 kfree(etmp);
578 ebitmap_destroy(&e->names); 591 }
579 etmp = e; 592 ctemp = constraint;
580 e = e->next; 593 constraint = constraint->next;
581 kfree(etmp); 594 kfree(ctemp);
582 } 595 }
583 ctemp = constraint;
584 constraint = constraint->next;
585 kfree(ctemp);
586 }
587 596
588 kfree(cladatum->comkey); 597 kfree(cladatum->comkey);
598 }
589 kfree(datum); 599 kfree(datum);
590 return 0; 600 return 0;
591} 601}
@@ -595,9 +605,11 @@ static int role_destroy(void *key, void *datum, void *p)
595 struct role_datum *role; 605 struct role_datum *role;
596 606
597 kfree(key); 607 kfree(key);
598 role = datum; 608 if (datum) {
599 ebitmap_destroy(&role->dominates); 609 role = datum;
600 ebitmap_destroy(&role->types); 610 ebitmap_destroy(&role->dominates);
611 ebitmap_destroy(&role->types);
612 }
601 kfree(datum); 613 kfree(datum);
602 return 0; 614 return 0;
603} 615}
@@ -614,11 +626,13 @@ static int user_destroy(void *key, void *datum, void *p)
614 struct user_datum *usrdatum; 626 struct user_datum *usrdatum;
615 627
616 kfree(key); 628 kfree(key);
617 usrdatum = datum; 629 if (datum) {
618 ebitmap_destroy(&usrdatum->roles); 630 usrdatum = datum;
619 ebitmap_destroy(&usrdatum->range.level[0].cat); 631 ebitmap_destroy(&usrdatum->roles);
620 ebitmap_destroy(&usrdatum->range.level[1].cat); 632 ebitmap_destroy(&usrdatum->range.level[0].cat);
621 ebitmap_destroy(&usrdatum->dfltlevel.cat); 633 ebitmap_destroy(&usrdatum->range.level[1].cat);
634 ebitmap_destroy(&usrdatum->dfltlevel.cat);
635 }
622 kfree(datum); 636 kfree(datum);
623 return 0; 637 return 0;
624} 638}
@@ -628,9 +642,11 @@ static int sens_destroy(void *key, void *datum, void *p)
628 struct level_datum *levdatum; 642 struct level_datum *levdatum;
629 643
630 kfree(key); 644 kfree(key);
631 levdatum = datum; 645 if (datum) {
632 ebitmap_destroy(&levdatum->level->cat); 646 levdatum = datum;
633 kfree(levdatum->level); 647 ebitmap_destroy(&levdatum->level->cat);
648 kfree(levdatum->level);
649 }
634 kfree(datum); 650 kfree(datum);
635 return 0; 651 return 0;
636} 652}
@@ -695,13 +711,16 @@ void policydb_destroy(struct policydb *p)
695 hashtab_destroy(p->symtab[i].table); 711 hashtab_destroy(p->symtab[i].table);
696 } 712 }
697 713
698 for (i = 0; i < SYM_NUM; i++) 714 for (i = 0; i < SYM_NUM; i++) {
699 kfree(p->sym_val_to_name[i]); 715 if (p->sym_val_to_name[i])
716 flex_array_free(p->sym_val_to_name[i]);
717 }
700 718
701 kfree(p->class_val_to_struct); 719 kfree(p->class_val_to_struct);
702 kfree(p->role_val_to_struct); 720 kfree(p->role_val_to_struct);
703 kfree(p->user_val_to_struct); 721 kfree(p->user_val_to_struct);
704 kfree(p->type_val_to_struct); 722 if (p->type_val_to_struct_array)
723 flex_array_free(p->type_val_to_struct_array);
705 724
706 avtab_destroy(&p->te_avtab); 725 avtab_destroy(&p->te_avtab);
707 726
@@ -785,19 +804,21 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
785 804
786 head = p->ocontexts[OCON_ISID]; 805 head = p->ocontexts[OCON_ISID];
787 for (c = head; c; c = c->next) { 806 for (c = head; c; c = c->next) {
807 rc = -EINVAL;
788 if (!c->context[0].user) { 808 if (!c->context[0].user) {
789 printk(KERN_ERR "SELinux: SID %s was never " 809 printk(KERN_ERR "SELinux: SID %s was never defined.\n",
790 "defined.\n", c->u.name); 810 c->u.name);
791 rc = -EINVAL;
792 goto out; 811 goto out;
793 } 812 }
794 if (sidtab_insert(s, c->sid[0], &c->context[0])) { 813
795 printk(KERN_ERR "SELinux: unable to load initial " 814 rc = sidtab_insert(s, c->sid[0], &c->context[0]);
796 "SID %s.\n", c->u.name); 815 if (rc) {
797 rc = -EINVAL; 816 printk(KERN_ERR "SELinux: unable to load initial SID %s.\n",
817 c->u.name);
798 goto out; 818 goto out;
799 } 819 }
800 } 820 }
821 rc = 0;
801out: 822out:
802 return rc; 823 return rc;
803} 824}
@@ -846,8 +867,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
846 * Role must be authorized for the type. 867 * Role must be authorized for the type.
847 */ 868 */
848 role = p->role_val_to_struct[c->role - 1]; 869 role = p->role_val_to_struct[c->role - 1];
849 if (!ebitmap_get_bit(&role->types, 870 if (!ebitmap_get_bit(&role->types, c->type - 1))
850 c->type - 1))
851 /* role may not be associated with type */ 871 /* role may not be associated with type */
852 return 0; 872 return 0;
853 873
@@ -858,8 +878,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
858 if (!usrdatum) 878 if (!usrdatum)
859 return 0; 879 return 0;
860 880
861 if (!ebitmap_get_bit(&usrdatum->roles, 881 if (!ebitmap_get_bit(&usrdatum->roles, c->role - 1))
862 c->role - 1))
863 /* user may not be associated with role */ 882 /* user may not be associated with role */
864 return 0; 883 return 0;
865 } 884 }
@@ -881,20 +900,22 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
881 int rc; 900 int rc;
882 901
883 rc = next_entry(buf, fp, sizeof(u32)); 902 rc = next_entry(buf, fp, sizeof(u32));
884 if (rc < 0) 903 if (rc)
885 goto out; 904 goto out;
886 905
906 rc = -EINVAL;
887 items = le32_to_cpu(buf[0]); 907 items = le32_to_cpu(buf[0]);
888 if (items > ARRAY_SIZE(buf)) { 908 if (items > ARRAY_SIZE(buf)) {
889 printk(KERN_ERR "SELinux: mls: range overflow\n"); 909 printk(KERN_ERR "SELinux: mls: range overflow\n");
890 rc = -EINVAL;
891 goto out; 910 goto out;
892 } 911 }
912
893 rc = next_entry(buf, fp, sizeof(u32) * items); 913 rc = next_entry(buf, fp, sizeof(u32) * items);
894 if (rc < 0) { 914 if (rc) {
895 printk(KERN_ERR "SELinux: mls: truncated range\n"); 915 printk(KERN_ERR "SELinux: mls: truncated range\n");
896 goto out; 916 goto out;
897 } 917 }
918
898 r->level[0].sens = le32_to_cpu(buf[0]); 919 r->level[0].sens = le32_to_cpu(buf[0]);
899 if (items > 1) 920 if (items > 1)
900 r->level[1].sens = le32_to_cpu(buf[1]); 921 r->level[1].sens = le32_to_cpu(buf[1]);
@@ -903,15 +924,13 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
903 924
904 rc = ebitmap_read(&r->level[0].cat, fp); 925 rc = ebitmap_read(&r->level[0].cat, fp);
905 if (rc) { 926 if (rc) {
906 printk(KERN_ERR "SELinux: mls: error reading low " 927 printk(KERN_ERR "SELinux: mls: error reading low categories\n");
907 "categories\n");
908 goto out; 928 goto out;
909 } 929 }
910 if (items > 1) { 930 if (items > 1) {
911 rc = ebitmap_read(&r->level[1].cat, fp); 931 rc = ebitmap_read(&r->level[1].cat, fp);
912 if (rc) { 932 if (rc) {
913 printk(KERN_ERR "SELinux: mls: error reading high " 933 printk(KERN_ERR "SELinux: mls: error reading high categories\n");
914 "categories\n");
915 goto bad_high; 934 goto bad_high;
916 } 935 }
917 } else { 936 } else {
@@ -922,12 +941,11 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
922 } 941 }
923 } 942 }
924 943
925 rc = 0; 944 return 0;
926out:
927 return rc;
928bad_high: 945bad_high:
929 ebitmap_destroy(&r->level[0].cat); 946 ebitmap_destroy(&r->level[0].cat);
930 goto out; 947out:
948 return rc;
931} 949}
932 950
933/* 951/*
@@ -942,7 +960,7 @@ static int context_read_and_validate(struct context *c,
942 int rc; 960 int rc;
943 961
944 rc = next_entry(buf, fp, sizeof buf); 962 rc = next_entry(buf, fp, sizeof buf);
945 if (rc < 0) { 963 if (rc) {
946 printk(KERN_ERR "SELinux: context truncated\n"); 964 printk(KERN_ERR "SELinux: context truncated\n");
947 goto out; 965 goto out;
948 } 966 }
@@ -950,19 +968,20 @@ static int context_read_and_validate(struct context *c,
950 c->role = le32_to_cpu(buf[1]); 968 c->role = le32_to_cpu(buf[1]);
951 c->type = le32_to_cpu(buf[2]); 969 c->type = le32_to_cpu(buf[2]);
952 if (p->policyvers >= POLICYDB_VERSION_MLS) { 970 if (p->policyvers >= POLICYDB_VERSION_MLS) {
953 if (mls_read_range_helper(&c->range, fp)) { 971 rc = mls_read_range_helper(&c->range, fp);
954 printk(KERN_ERR "SELinux: error reading MLS range of " 972 if (rc) {
955 "context\n"); 973 printk(KERN_ERR "SELinux: error reading MLS range of context\n");
956 rc = -EINVAL;
957 goto out; 974 goto out;
958 } 975 }
959 } 976 }
960 977
978 rc = -EINVAL;
961 if (!policydb_context_isvalid(p, c)) { 979 if (!policydb_context_isvalid(p, c)) {
962 printk(KERN_ERR "SELinux: invalid security context\n"); 980 printk(KERN_ERR "SELinux: invalid security context\n");
963 context_destroy(c); 981 context_destroy(c);
964 rc = -EINVAL; 982 goto out;
965 } 983 }
984 rc = 0;
966out: 985out:
967 return rc; 986 return rc;
968} 987}
@@ -981,37 +1000,36 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
981 __le32 buf[2]; 1000 __le32 buf[2];
982 u32 len; 1001 u32 len;
983 1002
1003 rc = -ENOMEM;
984 perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL); 1004 perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);
985 if (!perdatum) { 1005 if (!perdatum)
986 rc = -ENOMEM; 1006 goto bad;
987 goto out;
988 }
989 1007
990 rc = next_entry(buf, fp, sizeof buf); 1008 rc = next_entry(buf, fp, sizeof buf);
991 if (rc < 0) 1009 if (rc)
992 goto bad; 1010 goto bad;
993 1011
994 len = le32_to_cpu(buf[0]); 1012 len = le32_to_cpu(buf[0]);
995 perdatum->value = le32_to_cpu(buf[1]); 1013 perdatum->value = le32_to_cpu(buf[1]);
996 1014
1015 rc = -ENOMEM;
997 key = kmalloc(len + 1, GFP_KERNEL); 1016 key = kmalloc(len + 1, GFP_KERNEL);
998 if (!key) { 1017 if (!key)
999 rc = -ENOMEM;
1000 goto bad; 1018 goto bad;
1001 } 1019
1002 rc = next_entry(key, fp, len); 1020 rc = next_entry(key, fp, len);
1003 if (rc < 0) 1021 if (rc)
1004 goto bad; 1022 goto bad;
1005 key[len] = '\0'; 1023 key[len] = '\0';
1006 1024
1007 rc = hashtab_insert(h, key, perdatum); 1025 rc = hashtab_insert(h, key, perdatum);
1008 if (rc) 1026 if (rc)
1009 goto bad; 1027 goto bad;
1010out: 1028
1011 return rc; 1029 return 0;
1012bad: 1030bad:
1013 perm_destroy(key, perdatum, NULL); 1031 perm_destroy(key, perdatum, NULL);
1014 goto out; 1032 return rc;
1015} 1033}
1016 1034
1017static int common_read(struct policydb *p, struct hashtab *h, void *fp) 1035static int common_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1022,14 +1040,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1022 u32 len, nel; 1040 u32 len, nel;
1023 int i, rc; 1041 int i, rc;
1024 1042
1043 rc = -ENOMEM;
1025 comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL); 1044 comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
1026 if (!comdatum) { 1045 if (!comdatum)
1027 rc = -ENOMEM; 1046 goto bad;
1028 goto out;
1029 }
1030 1047
1031 rc = next_entry(buf, fp, sizeof buf); 1048 rc = next_entry(buf, fp, sizeof buf);
1032 if (rc < 0) 1049 if (rc)
1033 goto bad; 1050 goto bad;
1034 1051
1035 len = le32_to_cpu(buf[0]); 1052 len = le32_to_cpu(buf[0]);
@@ -1041,13 +1058,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1041 comdatum->permissions.nprim = le32_to_cpu(buf[2]); 1058 comdatum->permissions.nprim = le32_to_cpu(buf[2]);
1042 nel = le32_to_cpu(buf[3]); 1059 nel = le32_to_cpu(buf[3]);
1043 1060
1061 rc = -ENOMEM;
1044 key = kmalloc(len + 1, GFP_KERNEL); 1062 key = kmalloc(len + 1, GFP_KERNEL);
1045 if (!key) { 1063 if (!key)
1046 rc = -ENOMEM;
1047 goto bad; 1064 goto bad;
1048 } 1065
1049 rc = next_entry(key, fp, len); 1066 rc = next_entry(key, fp, len);
1050 if (rc < 0) 1067 if (rc)
1051 goto bad; 1068 goto bad;
1052 key[len] = '\0'; 1069 key[len] = '\0';
1053 1070
@@ -1060,11 +1077,10 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1060 rc = hashtab_insert(h, key, comdatum); 1077 rc = hashtab_insert(h, key, comdatum);
1061 if (rc) 1078 if (rc)
1062 goto bad; 1079 goto bad;
1063out: 1080 return 0;
1064 return rc;
1065bad: 1081bad:
1066 common_destroy(key, comdatum, NULL); 1082 common_destroy(key, comdatum, NULL);
1067 goto out; 1083 return rc;
1068} 1084}
1069 1085
1070static int read_cons_helper(struct constraint_node **nodep, int ncons, 1086static int read_cons_helper(struct constraint_node **nodep, int ncons,
@@ -1088,7 +1104,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1088 *nodep = c; 1104 *nodep = c;
1089 1105
1090 rc = next_entry(buf, fp, (sizeof(u32) * 2)); 1106 rc = next_entry(buf, fp, (sizeof(u32) * 2));
1091 if (rc < 0) 1107 if (rc)
1092 return rc; 1108 return rc;
1093 c->permissions = le32_to_cpu(buf[0]); 1109 c->permissions = le32_to_cpu(buf[0]);
1094 nexpr = le32_to_cpu(buf[1]); 1110 nexpr = le32_to_cpu(buf[1]);
@@ -1105,7 +1121,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1105 c->expr = e; 1121 c->expr = e;
1106 1122
1107 rc = next_entry(buf, fp, (sizeof(u32) * 3)); 1123 rc = next_entry(buf, fp, (sizeof(u32) * 3));
1108 if (rc < 0) 1124 if (rc)
1109 return rc; 1125 return rc;
1110 e->expr_type = le32_to_cpu(buf[0]); 1126 e->expr_type = le32_to_cpu(buf[0]);
1111 e->attr = le32_to_cpu(buf[1]); 1127 e->attr = le32_to_cpu(buf[1]);
@@ -1133,8 +1149,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1133 if (depth == (CEXPR_MAXDEPTH - 1)) 1149 if (depth == (CEXPR_MAXDEPTH - 1))
1134 return -EINVAL; 1150 return -EINVAL;
1135 depth++; 1151 depth++;
1136 if (ebitmap_read(&e->names, fp)) 1152 rc = ebitmap_read(&e->names, fp);
1137 return -EINVAL; 1153 if (rc)
1154 return rc;
1138 break; 1155 break;
1139 default: 1156 default:
1140 return -EINVAL; 1157 return -EINVAL;
@@ -1157,14 +1174,13 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1157 u32 len, len2, ncons, nel; 1174 u32 len, len2, ncons, nel;
1158 int i, rc; 1175 int i, rc;
1159 1176
1177 rc = -ENOMEM;
1160 cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL); 1178 cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
1161 if (!cladatum) { 1179 if (!cladatum)
1162 rc = -ENOMEM; 1180 goto bad;
1163 goto out;
1164 }
1165 1181
1166 rc = next_entry(buf, fp, sizeof(u32)*6); 1182 rc = next_entry(buf, fp, sizeof(u32)*6);
1167 if (rc < 0) 1183 if (rc)
1168 goto bad; 1184 goto bad;
1169 1185
1170 len = le32_to_cpu(buf[0]); 1186 len = le32_to_cpu(buf[0]);
@@ -1179,33 +1195,30 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1179 1195
1180 ncons = le32_to_cpu(buf[5]); 1196 ncons = le32_to_cpu(buf[5]);
1181 1197
1198 rc = -ENOMEM;
1182 key = kmalloc(len + 1, GFP_KERNEL); 1199 key = kmalloc(len + 1, GFP_KERNEL);
1183 if (!key) { 1200 if (!key)
1184 rc = -ENOMEM;
1185 goto bad; 1201 goto bad;
1186 } 1202
1187 rc = next_entry(key, fp, len); 1203 rc = next_entry(key, fp, len);
1188 if (rc < 0) 1204 if (rc)
1189 goto bad; 1205 goto bad;
1190 key[len] = '\0'; 1206 key[len] = '\0';
1191 1207
1192 if (len2) { 1208 if (len2) {
1209 rc = -ENOMEM;
1193 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL); 1210 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL);
1194 if (!cladatum->comkey) { 1211 if (!cladatum->comkey)
1195 rc = -ENOMEM;
1196 goto bad; 1212 goto bad;
1197 }
1198 rc = next_entry(cladatum->comkey, fp, len2); 1213 rc = next_entry(cladatum->comkey, fp, len2);
1199 if (rc < 0) 1214 if (rc)
1200 goto bad; 1215 goto bad;
1201 cladatum->comkey[len2] = '\0'; 1216 cladatum->comkey[len2] = '\0';
1202 1217
1203 cladatum->comdatum = hashtab_search(p->p_commons.table, 1218 rc = -EINVAL;
1204 cladatum->comkey); 1219 cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey);
1205 if (!cladatum->comdatum) { 1220 if (!cladatum->comdatum) {
1206 printk(KERN_ERR "SELinux: unknown common %s\n", 1221 printk(KERN_ERR "SELinux: unknown common %s\n", cladatum->comkey);
1207 cladatum->comkey);
1208 rc = -EINVAL;
1209 goto bad; 1222 goto bad;
1210 } 1223 }
1211 } 1224 }
@@ -1222,7 +1235,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1222 if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) { 1235 if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) {
1223 /* grab the validatetrans rules */ 1236 /* grab the validatetrans rules */
1224 rc = next_entry(buf, fp, sizeof(u32)); 1237 rc = next_entry(buf, fp, sizeof(u32));
1225 if (rc < 0) 1238 if (rc)
1226 goto bad; 1239 goto bad;
1227 ncons = le32_to_cpu(buf[0]); 1240 ncons = le32_to_cpu(buf[0]);
1228 rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); 1241 rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp);
@@ -1234,12 +1247,10 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1234 if (rc) 1247 if (rc)
1235 goto bad; 1248 goto bad;
1236 1249
1237 rc = 0; 1250 return 0;
1238out:
1239 return rc;
1240bad: 1251bad:
1241 cls_destroy(key, cladatum, NULL); 1252 cls_destroy(key, cladatum, NULL);
1242 goto out; 1253 return rc;
1243} 1254}
1244 1255
1245static int role_read(struct policydb *p, struct hashtab *h, void *fp) 1256static int role_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1250,17 +1261,16 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1250 __le32 buf[3]; 1261 __le32 buf[3];
1251 u32 len; 1262 u32 len;
1252 1263
1264 rc = -ENOMEM;
1253 role = kzalloc(sizeof(*role), GFP_KERNEL); 1265 role = kzalloc(sizeof(*role), GFP_KERNEL);
1254 if (!role) { 1266 if (!role)
1255 rc = -ENOMEM; 1267 goto bad;
1256 goto out;
1257 }
1258 1268
1259 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1269 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1260 to_read = 3; 1270 to_read = 3;
1261 1271
1262 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1272 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1263 if (rc < 0) 1273 if (rc)
1264 goto bad; 1274 goto bad;
1265 1275
1266 len = le32_to_cpu(buf[0]); 1276 len = le32_to_cpu(buf[0]);
@@ -1268,13 +1278,13 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1268 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1278 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1269 role->bounds = le32_to_cpu(buf[2]); 1279 role->bounds = le32_to_cpu(buf[2]);
1270 1280
1281 rc = -ENOMEM;
1271 key = kmalloc(len + 1, GFP_KERNEL); 1282 key = kmalloc(len + 1, GFP_KERNEL);
1272 if (!key) { 1283 if (!key)
1273 rc = -ENOMEM;
1274 goto bad; 1284 goto bad;
1275 } 1285
1276 rc = next_entry(key, fp, len); 1286 rc = next_entry(key, fp, len);
1277 if (rc < 0) 1287 if (rc)
1278 goto bad; 1288 goto bad;
1279 key[len] = '\0'; 1289 key[len] = '\0';
1280 1290
@@ -1287,10 +1297,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1287 goto bad; 1297 goto bad;
1288 1298
1289 if (strcmp(key, OBJECT_R) == 0) { 1299 if (strcmp(key, OBJECT_R) == 0) {
1300 rc = -EINVAL;
1290 if (role->value != OBJECT_R_VAL) { 1301 if (role->value != OBJECT_R_VAL) {
1291 printk(KERN_ERR "SELinux: Role %s has wrong value %d\n", 1302 printk(KERN_ERR "SELinux: Role %s has wrong value %d\n",
1292 OBJECT_R, role->value); 1303 OBJECT_R, role->value);
1293 rc = -EINVAL;
1294 goto bad; 1304 goto bad;
1295 } 1305 }
1296 rc = 0; 1306 rc = 0;
@@ -1300,11 +1310,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1300 rc = hashtab_insert(h, key, role); 1310 rc = hashtab_insert(h, key, role);
1301 if (rc) 1311 if (rc)
1302 goto bad; 1312 goto bad;
1303out: 1313 return 0;
1304 return rc;
1305bad: 1314bad:
1306 role_destroy(key, role, NULL); 1315 role_destroy(key, role, NULL);
1307 goto out; 1316 return rc;
1308} 1317}
1309 1318
1310static int type_read(struct policydb *p, struct hashtab *h, void *fp) 1319static int type_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1315,17 +1324,16 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1315 __le32 buf[4]; 1324 __le32 buf[4];
1316 u32 len; 1325 u32 len;
1317 1326
1327 rc = -ENOMEM;
1318 typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL); 1328 typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL);
1319 if (!typdatum) { 1329 if (!typdatum)
1320 rc = -ENOMEM; 1330 goto bad;
1321 return rc;
1322 }
1323 1331
1324 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1332 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1325 to_read = 4; 1333 to_read = 4;
1326 1334
1327 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1335 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1328 if (rc < 0) 1336 if (rc)
1329 goto bad; 1337 goto bad;
1330 1338
1331 len = le32_to_cpu(buf[0]); 1339 len = le32_to_cpu(buf[0]);
@@ -1343,24 +1351,22 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1343 typdatum->primary = le32_to_cpu(buf[2]); 1351 typdatum->primary = le32_to_cpu(buf[2]);
1344 } 1352 }
1345 1353
1354 rc = -ENOMEM;
1346 key = kmalloc(len + 1, GFP_KERNEL); 1355 key = kmalloc(len + 1, GFP_KERNEL);
1347 if (!key) { 1356 if (!key)
1348 rc = -ENOMEM;
1349 goto bad; 1357 goto bad;
1350 }
1351 rc = next_entry(key, fp, len); 1358 rc = next_entry(key, fp, len);
1352 if (rc < 0) 1359 if (rc)
1353 goto bad; 1360 goto bad;
1354 key[len] = '\0'; 1361 key[len] = '\0';
1355 1362
1356 rc = hashtab_insert(h, key, typdatum); 1363 rc = hashtab_insert(h, key, typdatum);
1357 if (rc) 1364 if (rc)
1358 goto bad; 1365 goto bad;
1359out: 1366 return 0;
1360 return rc;
1361bad: 1367bad:
1362 type_destroy(key, typdatum, NULL); 1368 type_destroy(key, typdatum, NULL);
1363 goto out; 1369 return rc;
1364} 1370}
1365 1371
1366 1372
@@ -1376,22 +1382,18 @@ static int mls_read_level(struct mls_level *lp, void *fp)
1376 memset(lp, 0, sizeof(*lp)); 1382 memset(lp, 0, sizeof(*lp));
1377 1383
1378 rc = next_entry(buf, fp, sizeof buf); 1384 rc = next_entry(buf, fp, sizeof buf);
1379 if (rc < 0) { 1385 if (rc) {
1380 printk(KERN_ERR "SELinux: mls: truncated level\n"); 1386 printk(KERN_ERR "SELinux: mls: truncated level\n");
1381 goto bad; 1387 return rc;
1382 } 1388 }
1383 lp->sens = le32_to_cpu(buf[0]); 1389 lp->sens = le32_to_cpu(buf[0]);
1384 1390
1385 if (ebitmap_read(&lp->cat, fp)) { 1391 rc = ebitmap_read(&lp->cat, fp);
1386 printk(KERN_ERR "SELinux: mls: error reading level " 1392 if (rc) {
1387 "categories\n"); 1393 printk(KERN_ERR "SELinux: mls: error reading level categories\n");
1388 goto bad; 1394 return rc;
1389 } 1395 }
1390
1391 return 0; 1396 return 0;
1392
1393bad:
1394 return -EINVAL;
1395} 1397}
1396 1398
1397static int user_read(struct policydb *p, struct hashtab *h, void *fp) 1399static int user_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1402,17 +1404,16 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1402 __le32 buf[3]; 1404 __le32 buf[3];
1403 u32 len; 1405 u32 len;
1404 1406
1407 rc = -ENOMEM;
1405 usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL); 1408 usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
1406 if (!usrdatum) { 1409 if (!usrdatum)
1407 rc = -ENOMEM; 1410 goto bad;
1408 goto out;
1409 }
1410 1411
1411 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1412 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1412 to_read = 3; 1413 to_read = 3;
1413 1414
1414 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1415 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1415 if (rc < 0) 1416 if (rc)
1416 goto bad; 1417 goto bad;
1417 1418
1418 len = le32_to_cpu(buf[0]); 1419 len = le32_to_cpu(buf[0]);
@@ -1420,13 +1421,12 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1420 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1421 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1421 usrdatum->bounds = le32_to_cpu(buf[2]); 1422 usrdatum->bounds = le32_to_cpu(buf[2]);
1422 1423
1424 rc = -ENOMEM;
1423 key = kmalloc(len + 1, GFP_KERNEL); 1425 key = kmalloc(len + 1, GFP_KERNEL);
1424 if (!key) { 1426 if (!key)
1425 rc = -ENOMEM;
1426 goto bad; 1427 goto bad;
1427 }
1428 rc = next_entry(key, fp, len); 1428 rc = next_entry(key, fp, len);
1429 if (rc < 0) 1429 if (rc)
1430 goto bad; 1430 goto bad;
1431 key[len] = '\0'; 1431 key[len] = '\0';
1432 1432
@@ -1446,11 +1446,10 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1446 rc = hashtab_insert(h, key, usrdatum); 1446 rc = hashtab_insert(h, key, usrdatum);
1447 if (rc) 1447 if (rc)
1448 goto bad; 1448 goto bad;
1449out: 1449 return 0;
1450 return rc;
1451bad: 1450bad:
1452 user_destroy(key, usrdatum, NULL); 1451 user_destroy(key, usrdatum, NULL);
1453 goto out; 1452 return rc;
1454} 1453}
1455 1454
1456static int sens_read(struct policydb *p, struct hashtab *h, void *fp) 1455static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1461,47 +1460,43 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
1461 __le32 buf[2]; 1460 __le32 buf[2];
1462 u32 len; 1461 u32 len;
1463 1462
1463 rc = -ENOMEM;
1464 levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC); 1464 levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
1465 if (!levdatum) { 1465 if (!levdatum)
1466 rc = -ENOMEM; 1466 goto bad;
1467 goto out;
1468 }
1469 1467
1470 rc = next_entry(buf, fp, sizeof buf); 1468 rc = next_entry(buf, fp, sizeof buf);
1471 if (rc < 0) 1469 if (rc)
1472 goto bad; 1470 goto bad;
1473 1471
1474 len = le32_to_cpu(buf[0]); 1472 len = le32_to_cpu(buf[0]);
1475 levdatum->isalias = le32_to_cpu(buf[1]); 1473 levdatum->isalias = le32_to_cpu(buf[1]);
1476 1474
1475 rc = -ENOMEM;
1477 key = kmalloc(len + 1, GFP_ATOMIC); 1476 key = kmalloc(len + 1, GFP_ATOMIC);
1478 if (!key) { 1477 if (!key)
1479 rc = -ENOMEM;
1480 goto bad; 1478 goto bad;
1481 }
1482 rc = next_entry(key, fp, len); 1479 rc = next_entry(key, fp, len);
1483 if (rc < 0) 1480 if (rc)
1484 goto bad; 1481 goto bad;
1485 key[len] = '\0'; 1482 key[len] = '\0';
1486 1483
1484 rc = -ENOMEM;
1487 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); 1485 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);
1488 if (!levdatum->level) { 1486 if (!levdatum->level)
1489 rc = -ENOMEM;
1490 goto bad; 1487 goto bad;
1491 } 1488
1492 if (mls_read_level(levdatum->level, fp)) { 1489 rc = mls_read_level(levdatum->level, fp);
1493 rc = -EINVAL; 1490 if (rc)
1494 goto bad; 1491 goto bad;
1495 }
1496 1492
1497 rc = hashtab_insert(h, key, levdatum); 1493 rc = hashtab_insert(h, key, levdatum);
1498 if (rc) 1494 if (rc)
1499 goto bad; 1495 goto bad;
1500out: 1496 return 0;
1501 return rc;
1502bad: 1497bad:
1503 sens_destroy(key, levdatum, NULL); 1498 sens_destroy(key, levdatum, NULL);
1504 goto out; 1499 return rc;
1505} 1500}
1506 1501
1507static int cat_read(struct policydb *p, struct hashtab *h, void *fp) 1502static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1512,39 +1507,35 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
1512 __le32 buf[3]; 1507 __le32 buf[3];
1513 u32 len; 1508 u32 len;
1514 1509
1510 rc = -ENOMEM;
1515 catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC); 1511 catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
1516 if (!catdatum) { 1512 if (!catdatum)
1517 rc = -ENOMEM; 1513 goto bad;
1518 goto out;
1519 }
1520 1514
1521 rc = next_entry(buf, fp, sizeof buf); 1515 rc = next_entry(buf, fp, sizeof buf);
1522 if (rc < 0) 1516 if (rc)
1523 goto bad; 1517 goto bad;
1524 1518
1525 len = le32_to_cpu(buf[0]); 1519 len = le32_to_cpu(buf[0]);
1526 catdatum->value = le32_to_cpu(buf[1]); 1520 catdatum->value = le32_to_cpu(buf[1]);
1527 catdatum->isalias = le32_to_cpu(buf[2]); 1521 catdatum->isalias = le32_to_cpu(buf[2]);
1528 1522
1523 rc = -ENOMEM;
1529 key = kmalloc(len + 1, GFP_ATOMIC); 1524 key = kmalloc(len + 1, GFP_ATOMIC);
1530 if (!key) { 1525 if (!key)
1531 rc = -ENOMEM;
1532 goto bad; 1526 goto bad;
1533 }
1534 rc = next_entry(key, fp, len); 1527 rc = next_entry(key, fp, len);
1535 if (rc < 0) 1528 if (rc)
1536 goto bad; 1529 goto bad;
1537 key[len] = '\0'; 1530 key[len] = '\0';
1538 1531
1539 rc = hashtab_insert(h, key, catdatum); 1532 rc = hashtab_insert(h, key, catdatum);
1540 if (rc) 1533 if (rc)
1541 goto bad; 1534 goto bad;
1542out: 1535 return 0;
1543 return rc;
1544
1545bad: 1536bad:
1546 cat_destroy(key, catdatum, NULL); 1537 cat_destroy(key, catdatum, NULL);
1547 goto out; 1538 return rc;
1548} 1539}
1549 1540
1550static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) = 1541static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) =
@@ -1585,9 +1576,9 @@ static int user_bounds_sanity_check(void *key, void *datum, void *datap)
1585 printk(KERN_ERR 1576 printk(KERN_ERR
1586 "SELinux: boundary violated policy: " 1577 "SELinux: boundary violated policy: "
1587 "user=%s role=%s bounds=%s\n", 1578 "user=%s role=%s bounds=%s\n",
1588 p->p_user_val_to_name[user->value - 1], 1579 sym_name(p, SYM_USERS, user->value - 1),
1589 p->p_role_val_to_name[bit], 1580 sym_name(p, SYM_ROLES, bit),
1590 p->p_user_val_to_name[upper->value - 1]); 1581 sym_name(p, SYM_USERS, upper->value - 1));
1591 1582
1592 return -EINVAL; 1583 return -EINVAL;
1593 } 1584 }
@@ -1622,9 +1613,9 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap)
1622 printk(KERN_ERR 1613 printk(KERN_ERR
1623 "SELinux: boundary violated policy: " 1614 "SELinux: boundary violated policy: "
1624 "role=%s type=%s bounds=%s\n", 1615 "role=%s type=%s bounds=%s\n",
1625 p->p_role_val_to_name[role->value - 1], 1616 sym_name(p, SYM_ROLES, role->value - 1),
1626 p->p_type_val_to_name[bit], 1617 sym_name(p, SYM_TYPES, bit),
1627 p->p_role_val_to_name[upper->value - 1]); 1618 sym_name(p, SYM_ROLES, upper->value - 1));
1628 1619
1629 return -EINVAL; 1620 return -EINVAL;
1630 } 1621 }
@@ -1648,12 +1639,15 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap)
1648 return -EINVAL; 1639 return -EINVAL;
1649 } 1640 }
1650 1641
1651 upper = p->type_val_to_struct[upper->bounds - 1]; 1642 upper = flex_array_get_ptr(p->type_val_to_struct_array,
1643 upper->bounds - 1);
1644 BUG_ON(!upper);
1645
1652 if (upper->attribute) { 1646 if (upper->attribute) {
1653 printk(KERN_ERR "SELinux: type %s: " 1647 printk(KERN_ERR "SELinux: type %s: "
1654 "bounded by attribute %s", 1648 "bounded by attribute %s",
1655 (char *) key, 1649 (char *) key,
1656 p->p_type_val_to_name[upper->value - 1]); 1650 sym_name(p, SYM_TYPES, upper->value - 1));
1657 return -EINVAL; 1651 return -EINVAL;
1658 } 1652 }
1659 } 1653 }
@@ -2066,13 +2060,14 @@ int policydb_read(struct policydb *p, void *fp)
2066 2060
2067 rc = policydb_init(p); 2061 rc = policydb_init(p);
2068 if (rc) 2062 if (rc)
2069 goto out; 2063 return rc;
2070 2064
2071 /* Read the magic number and string length. */ 2065 /* Read the magic number and string length. */
2072 rc = next_entry(buf, fp, sizeof(u32) * 2); 2066 rc = next_entry(buf, fp, sizeof(u32) * 2);
2073 if (rc < 0) 2067 if (rc)
2074 goto bad; 2068 goto bad;
2075 2069
2070 rc = -EINVAL;
2076 if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { 2071 if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) {
2077 printk(KERN_ERR "SELinux: policydb magic number 0x%x does " 2072 printk(KERN_ERR "SELinux: policydb magic number 0x%x does "
2078 "not match expected magic number 0x%x\n", 2073 "not match expected magic number 0x%x\n",
@@ -2080,6 +2075,7 @@ int policydb_read(struct policydb *p, void *fp)
2080 goto bad; 2075 goto bad;
2081 } 2076 }
2082 2077
2078 rc = -EINVAL;
2083 len = le32_to_cpu(buf[1]); 2079 len = le32_to_cpu(buf[1]);
2084 if (len != strlen(POLICYDB_STRING)) { 2080 if (len != strlen(POLICYDB_STRING)) {
2085 printk(KERN_ERR "SELinux: policydb string length %d does not " 2081 printk(KERN_ERR "SELinux: policydb string length %d does not "
@@ -2087,19 +2083,23 @@ int policydb_read(struct policydb *p, void *fp)
2087 len, strlen(POLICYDB_STRING)); 2083 len, strlen(POLICYDB_STRING));
2088 goto bad; 2084 goto bad;
2089 } 2085 }
2086
2087 rc = -ENOMEM;
2090 policydb_str = kmalloc(len + 1, GFP_KERNEL); 2088 policydb_str = kmalloc(len + 1, GFP_KERNEL);
2091 if (!policydb_str) { 2089 if (!policydb_str) {
2092 printk(KERN_ERR "SELinux: unable to allocate memory for policydb " 2090 printk(KERN_ERR "SELinux: unable to allocate memory for policydb "
2093 "string of length %d\n", len); 2091 "string of length %d\n", len);
2094 rc = -ENOMEM;
2095 goto bad; 2092 goto bad;
2096 } 2093 }
2094
2097 rc = next_entry(policydb_str, fp, len); 2095 rc = next_entry(policydb_str, fp, len);
2098 if (rc < 0) { 2096 if (rc) {
2099 printk(KERN_ERR "SELinux: truncated policydb string identifier\n"); 2097 printk(KERN_ERR "SELinux: truncated policydb string identifier\n");
2100 kfree(policydb_str); 2098 kfree(policydb_str);
2101 goto bad; 2099 goto bad;
2102 } 2100 }
2101
2102 rc = -EINVAL;
2103 policydb_str[len] = '\0'; 2103 policydb_str[len] = '\0';
2104 if (strcmp(policydb_str, POLICYDB_STRING)) { 2104 if (strcmp(policydb_str, POLICYDB_STRING)) {
2105 printk(KERN_ERR "SELinux: policydb string %s does not match " 2105 printk(KERN_ERR "SELinux: policydb string %s does not match "
@@ -2113,9 +2113,10 @@ int policydb_read(struct policydb *p, void *fp)
2113 2113
2114 /* Read the version and table sizes. */ 2114 /* Read the version and table sizes. */
2115 rc = next_entry(buf, fp, sizeof(u32)*4); 2115 rc = next_entry(buf, fp, sizeof(u32)*4);
2116 if (rc < 0) 2116 if (rc)
2117 goto bad; 2117 goto bad;
2118 2118
2119 rc = -EINVAL;
2119 p->policyvers = le32_to_cpu(buf[0]); 2120 p->policyvers = le32_to_cpu(buf[0]);
2120 if (p->policyvers < POLICYDB_VERSION_MIN || 2121 if (p->policyvers < POLICYDB_VERSION_MIN ||
2121 p->policyvers > POLICYDB_VERSION_MAX) { 2122 p->policyvers > POLICYDB_VERSION_MAX) {
@@ -2128,6 +2129,7 @@ int policydb_read(struct policydb *p, void *fp)
2128 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { 2129 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
2129 p->mls_enabled = 1; 2130 p->mls_enabled = 1;
2130 2131
2132 rc = -EINVAL;
2131 if (p->policyvers < POLICYDB_VERSION_MLS) { 2133 if (p->policyvers < POLICYDB_VERSION_MLS) {
2132 printk(KERN_ERR "SELinux: security policydb version %d " 2134 printk(KERN_ERR "SELinux: security policydb version %d "
2133 "(MLS) not backwards compatible\n", 2135 "(MLS) not backwards compatible\n",
@@ -2138,14 +2140,19 @@ int policydb_read(struct policydb *p, void *fp)
2138 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); 2140 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
2139 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); 2141 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
2140 2142
2141 if (p->policyvers >= POLICYDB_VERSION_POLCAP && 2143 if (p->policyvers >= POLICYDB_VERSION_POLCAP) {
2142 ebitmap_read(&p->policycaps, fp) != 0) 2144 rc = ebitmap_read(&p->policycaps, fp);
2143 goto bad; 2145 if (rc)
2146 goto bad;
2147 }
2144 2148
2145 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && 2149 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE) {
2146 ebitmap_read(&p->permissive_map, fp) != 0) 2150 rc = ebitmap_read(&p->permissive_map, fp);
2147 goto bad; 2151 if (rc)
2152 goto bad;
2153 }
2148 2154
2155 rc = -EINVAL;
2149 info = policydb_lookup_compat(p->policyvers); 2156 info = policydb_lookup_compat(p->policyvers);
2150 if (!info) { 2157 if (!info) {
2151 printk(KERN_ERR "SELinux: unable to find policy compat info " 2158 printk(KERN_ERR "SELinux: unable to find policy compat info "
@@ -2153,6 +2160,7 @@ int policydb_read(struct policydb *p, void *fp)
2153 goto bad; 2160 goto bad;
2154 } 2161 }
2155 2162
2163 rc = -EINVAL;
2156 if (le32_to_cpu(buf[2]) != info->sym_num || 2164 if (le32_to_cpu(buf[2]) != info->sym_num ||
2157 le32_to_cpu(buf[3]) != info->ocon_num) { 2165 le32_to_cpu(buf[3]) != info->ocon_num) {
2158 printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do " 2166 printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do "
@@ -2164,7 +2172,7 @@ int policydb_read(struct policydb *p, void *fp)
2164 2172
2165 for (i = 0; i < info->sym_num; i++) { 2173 for (i = 0; i < info->sym_num; i++) {
2166 rc = next_entry(buf, fp, sizeof(u32)*2); 2174 rc = next_entry(buf, fp, sizeof(u32)*2);
2167 if (rc < 0) 2175 if (rc)
2168 goto bad; 2176 goto bad;
2169 nprim = le32_to_cpu(buf[0]); 2177 nprim = le32_to_cpu(buf[0]);
2170 nel = le32_to_cpu(buf[1]); 2178 nel = le32_to_cpu(buf[1]);
@@ -2188,78 +2196,73 @@ int policydb_read(struct policydb *p, void *fp)
2188 } 2196 }
2189 2197
2190 rc = next_entry(buf, fp, sizeof(u32)); 2198 rc = next_entry(buf, fp, sizeof(u32));
2191 if (rc < 0) 2199 if (rc)
2192 goto bad; 2200 goto bad;
2193 nel = le32_to_cpu(buf[0]); 2201 nel = le32_to_cpu(buf[0]);
2194 ltr = NULL; 2202 ltr = NULL;
2195 for (i = 0; i < nel; i++) { 2203 for (i = 0; i < nel; i++) {
2204 rc = -ENOMEM;
2196 tr = kzalloc(sizeof(*tr), GFP_KERNEL); 2205 tr = kzalloc(sizeof(*tr), GFP_KERNEL);
2197 if (!tr) { 2206 if (!tr)
2198 rc = -ENOMEM;
2199 goto bad; 2207 goto bad;
2200 }
2201 if (ltr) 2208 if (ltr)
2202 ltr->next = tr; 2209 ltr->next = tr;
2203 else 2210 else
2204 p->role_tr = tr; 2211 p->role_tr = tr;
2205 rc = next_entry(buf, fp, sizeof(u32)*3); 2212 rc = next_entry(buf, fp, sizeof(u32)*3);
2206 if (rc < 0) 2213 if (rc)
2207 goto bad; 2214 goto bad;
2215
2216 rc = -EINVAL;
2208 tr->role = le32_to_cpu(buf[0]); 2217 tr->role = le32_to_cpu(buf[0]);
2209 tr->type = le32_to_cpu(buf[1]); 2218 tr->type = le32_to_cpu(buf[1]);
2210 tr->new_role = le32_to_cpu(buf[2]); 2219 tr->new_role = le32_to_cpu(buf[2]);
2211 if (!policydb_role_isvalid(p, tr->role) || 2220 if (!policydb_role_isvalid(p, tr->role) ||
2212 !policydb_type_isvalid(p, tr->type) || 2221 !policydb_type_isvalid(p, tr->type) ||
2213 !policydb_role_isvalid(p, tr->new_role)) { 2222 !policydb_role_isvalid(p, tr->new_role))
2214 rc = -EINVAL;
2215 goto bad; 2223 goto bad;
2216 }
2217 ltr = tr; 2224 ltr = tr;
2218 } 2225 }
2219 2226
2220 rc = next_entry(buf, fp, sizeof(u32)); 2227 rc = next_entry(buf, fp, sizeof(u32));
2221 if (rc < 0) 2228 if (rc)
2222 goto bad; 2229 goto bad;
2223 nel = le32_to_cpu(buf[0]); 2230 nel = le32_to_cpu(buf[0]);
2224 lra = NULL; 2231 lra = NULL;
2225 for (i = 0; i < nel; i++) { 2232 for (i = 0; i < nel; i++) {
2233 rc = -ENOMEM;
2226 ra = kzalloc(sizeof(*ra), GFP_KERNEL); 2234 ra = kzalloc(sizeof(*ra), GFP_KERNEL);
2227 if (!ra) { 2235 if (!ra)
2228 rc = -ENOMEM;
2229 goto bad; 2236 goto bad;
2230 }
2231 if (lra) 2237 if (lra)
2232 lra->next = ra; 2238 lra->next = ra;
2233 else 2239 else
2234 p->role_allow = ra; 2240 p->role_allow = ra;
2235 rc = next_entry(buf, fp, sizeof(u32)*2); 2241 rc = next_entry(buf, fp, sizeof(u32)*2);
2236 if (rc < 0) 2242 if (rc)
2237 goto bad; 2243 goto bad;
2244
2245 rc = -EINVAL;
2238 ra->role = le32_to_cpu(buf[0]); 2246 ra->role = le32_to_cpu(buf[0]);
2239 ra->new_role = le32_to_cpu(buf[1]); 2247 ra->new_role = le32_to_cpu(buf[1]);
2240 if (!policydb_role_isvalid(p, ra->role) || 2248 if (!policydb_role_isvalid(p, ra->role) ||
2241 !policydb_role_isvalid(p, ra->new_role)) { 2249 !policydb_role_isvalid(p, ra->new_role))
2242 rc = -EINVAL;
2243 goto bad; 2250 goto bad;
2244 }
2245 lra = ra; 2251 lra = ra;
2246 } 2252 }
2247 2253
2248 rc = policydb_index_classes(p); 2254 rc = policydb_index(p);
2249 if (rc)
2250 goto bad;
2251
2252 rc = policydb_index_others(p);
2253 if (rc) 2255 if (rc)
2254 goto bad; 2256 goto bad;
2255 2257
2258 rc = -EINVAL;
2256 p->process_class = string_to_security_class(p, "process"); 2259 p->process_class = string_to_security_class(p, "process");
2257 if (!p->process_class) 2260 if (!p->process_class)
2258 goto bad; 2261 goto bad;
2259 p->process_trans_perms = string_to_av_perm(p, p->process_class, 2262
2260 "transition"); 2263 rc = -EINVAL;
2261 p->process_trans_perms |= string_to_av_perm(p, p->process_class, 2264 p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition");
2262 "dyntransition"); 2265 p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition");
2263 if (!p->process_trans_perms) 2266 if (!p->process_trans_perms)
2264 goto bad; 2267 goto bad;
2265 2268
@@ -2312,8 +2315,6 @@ int policydb_read(struct policydb *p, void *fp)
2312out: 2315out:
2313 return rc; 2316 return rc;
2314bad: 2317bad:
2315 if (!rc)
2316 rc = -EINVAL;
2317 policydb_destroy(p); 2318 policydb_destroy(p);
2318 goto out; 2319 goto out;
2319} 2320}
@@ -3076,7 +3077,7 @@ int policydb_write(struct policydb *p, void *fp)
3076 if (!info) { 3077 if (!info) {
3077 printk(KERN_ERR "SELinux: compatibility lookup failed for policy " 3078 printk(KERN_ERR "SELinux: compatibility lookup failed for policy "
3078 "version %d", p->policyvers); 3079 "version %d", p->policyvers);
3079 return rc; 3080 return -EINVAL;
3080 } 3081 }
3081 3082
3082 buf[0] = cpu_to_le32(p->policyvers); 3083 buf[0] = cpu_to_le32(p->policyvers);
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 95d3d7de361e..4e3ab9d0b315 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -203,21 +203,13 @@ struct policydb {
203#define p_cats symtab[SYM_CATS] 203#define p_cats symtab[SYM_CATS]
204 204
205 /* symbol names indexed by (value - 1) */ 205 /* symbol names indexed by (value - 1) */
206 char **sym_val_to_name[SYM_NUM]; 206 struct flex_array *sym_val_to_name[SYM_NUM];
207#define p_common_val_to_name sym_val_to_name[SYM_COMMONS]
208#define p_class_val_to_name sym_val_to_name[SYM_CLASSES]
209#define p_role_val_to_name sym_val_to_name[SYM_ROLES]
210#define p_type_val_to_name sym_val_to_name[SYM_TYPES]
211#define p_user_val_to_name sym_val_to_name[SYM_USERS]
212#define p_bool_val_to_name sym_val_to_name[SYM_BOOLS]
213#define p_sens_val_to_name sym_val_to_name[SYM_LEVELS]
214#define p_cat_val_to_name sym_val_to_name[SYM_CATS]
215 207
216 /* class, role, and user attributes indexed by (value - 1) */ 208 /* class, role, and user attributes indexed by (value - 1) */
217 struct class_datum **class_val_to_struct; 209 struct class_datum **class_val_to_struct;
218 struct role_datum **role_val_to_struct; 210 struct role_datum **role_val_to_struct;
219 struct user_datum **user_val_to_struct; 211 struct user_datum **user_val_to_struct;
220 struct type_datum **type_val_to_struct; 212 struct flex_array *type_val_to_struct_array;
221 213
222 /* type enforcement access vectors and transitions */ 214 /* type enforcement access vectors and transitions */
223 struct avtab te_avtab; 215 struct avtab te_avtab;
@@ -321,6 +313,13 @@ static inline int put_entry(void *buf, size_t bytes, int num, struct policy_file
321 return 0; 313 return 0;
322} 314}
323 315
316static inline char *sym_name(struct policydb *p, unsigned int sym_num, unsigned int element_nr)
317{
318 struct flex_array *fa = p->sym_val_to_name[sym_num];
319
320 return flex_array_get_ptr(fa, element_nr);
321}
322
324extern u16 string_to_security_class(struct policydb *p, const char *name); 323extern u16 string_to_security_class(struct policydb *p, const char *name);
325extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name); 324extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name);
326 325
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 223c1ff6ef23..a03cfaf0ee07 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -464,7 +464,7 @@ static void security_dump_masked_av(struct context *scontext,
464 if (!permissions) 464 if (!permissions)
465 return; 465 return;
466 466
467 tclass_name = policydb.p_class_val_to_name[tclass - 1]; 467 tclass_name = sym_name(&policydb, SYM_CLASSES, tclass - 1);
468 tclass_dat = policydb.class_val_to_struct[tclass - 1]; 468 tclass_dat = policydb.class_val_to_struct[tclass - 1];
469 common_dat = tclass_dat->comdatum; 469 common_dat = tclass_dat->comdatum;
470 470
@@ -530,12 +530,18 @@ static void type_attribute_bounds_av(struct context *scontext,
530 struct context lo_scontext; 530 struct context lo_scontext;
531 struct context lo_tcontext; 531 struct context lo_tcontext;
532 struct av_decision lo_avd; 532 struct av_decision lo_avd;
533 struct type_datum *source 533 struct type_datum *source;
534 = policydb.type_val_to_struct[scontext->type - 1]; 534 struct type_datum *target;
535 struct type_datum *target
536 = policydb.type_val_to_struct[tcontext->type - 1];
537 u32 masked = 0; 535 u32 masked = 0;
538 536
537 source = flex_array_get_ptr(policydb.type_val_to_struct_array,
538 scontext->type - 1);
539 BUG_ON(!source);
540
541 target = flex_array_get_ptr(policydb.type_val_to_struct_array,
542 tcontext->type - 1);
543 BUG_ON(!target);
544
539 if (source->bounds) { 545 if (source->bounds) {
540 memset(&lo_avd, 0, sizeof(lo_avd)); 546 memset(&lo_avd, 0, sizeof(lo_avd));
541 547
@@ -701,16 +707,16 @@ static int security_validtrans_handle_fail(struct context *ocontext,
701 char *o = NULL, *n = NULL, *t = NULL; 707 char *o = NULL, *n = NULL, *t = NULL;
702 u32 olen, nlen, tlen; 708 u32 olen, nlen, tlen;
703 709
704 if (context_struct_to_string(ocontext, &o, &olen) < 0) 710 if (context_struct_to_string(ocontext, &o, &olen))
705 goto out; 711 goto out;
706 if (context_struct_to_string(ncontext, &n, &nlen) < 0) 712 if (context_struct_to_string(ncontext, &n, &nlen))
707 goto out; 713 goto out;
708 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 714 if (context_struct_to_string(tcontext, &t, &tlen))
709 goto out; 715 goto out;
710 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 716 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
711 "security_validate_transition: denied for" 717 "security_validate_transition: denied for"
712 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", 718 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
713 o, n, t, policydb.p_class_val_to_name[tclass-1]); 719 o, n, t, sym_name(&policydb, SYM_CLASSES, tclass-1));
714out: 720out:
715 kfree(o); 721 kfree(o);
716 kfree(n); 722 kfree(n);
@@ -801,10 +807,11 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
801 struct context *old_context, *new_context; 807 struct context *old_context, *new_context;
802 struct type_datum *type; 808 struct type_datum *type;
803 int index; 809 int index;
804 int rc = -EINVAL; 810 int rc;
805 811
806 read_lock(&policy_rwlock); 812 read_lock(&policy_rwlock);
807 813
814 rc = -EINVAL;
808 old_context = sidtab_search(&sidtab, old_sid); 815 old_context = sidtab_search(&sidtab, old_sid);
809 if (!old_context) { 816 if (!old_context) {
810 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", 817 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
@@ -812,6 +819,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
812 goto out; 819 goto out;
813 } 820 }
814 821
822 rc = -EINVAL;
815 new_context = sidtab_search(&sidtab, new_sid); 823 new_context = sidtab_search(&sidtab, new_sid);
816 if (!new_context) { 824 if (!new_context) {
817 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", 825 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
@@ -819,28 +827,27 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
819 goto out; 827 goto out;
820 } 828 }
821 829
830 rc = 0;
822 /* type/domain unchanged */ 831 /* type/domain unchanged */
823 if (old_context->type == new_context->type) { 832 if (old_context->type == new_context->type)
824 rc = 0;
825 goto out; 833 goto out;
826 }
827 834
828 index = new_context->type; 835 index = new_context->type;
829 while (true) { 836 while (true) {
830 type = policydb.type_val_to_struct[index - 1]; 837 type = flex_array_get_ptr(policydb.type_val_to_struct_array,
838 index - 1);
831 BUG_ON(!type); 839 BUG_ON(!type);
832 840
833 /* not bounded anymore */ 841 /* not bounded anymore */
834 if (!type->bounds) { 842 rc = -EPERM;
835 rc = -EPERM; 843 if (!type->bounds)
836 break; 844 break;
837 }
838 845
839 /* @newsid is bounded by @oldsid */ 846 /* @newsid is bounded by @oldsid */
840 if (type->bounds == old_context->type) { 847 rc = 0;
841 rc = 0; 848 if (type->bounds == old_context->type)
842 break; 849 break;
843 } 850
844 index = type->bounds; 851 index = type->bounds;
845 } 852 }
846 853
@@ -1005,9 +1012,9 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
1005 } 1012 }
1006 1013
1007 /* Compute the size of the context. */ 1014 /* Compute the size of the context. */
1008 *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1; 1015 *scontext_len += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) + 1;
1009 *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1; 1016 *scontext_len += strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) + 1;
1010 *scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1; 1017 *scontext_len += strlen(sym_name(&policydb, SYM_TYPES, context->type - 1)) + 1;
1011 *scontext_len += mls_compute_context_len(context); 1018 *scontext_len += mls_compute_context_len(context);
1012 1019
1013 if (!scontext) 1020 if (!scontext)
@@ -1023,12 +1030,12 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
1023 * Copy the user name, role name and type name into the context. 1030 * Copy the user name, role name and type name into the context.
1024 */ 1031 */
1025 sprintf(scontextp, "%s:%s:%s", 1032 sprintf(scontextp, "%s:%s:%s",
1026 policydb.p_user_val_to_name[context->user - 1], 1033 sym_name(&policydb, SYM_USERS, context->user - 1),
1027 policydb.p_role_val_to_name[context->role - 1], 1034 sym_name(&policydb, SYM_ROLES, context->role - 1),
1028 policydb.p_type_val_to_name[context->type - 1]); 1035 sym_name(&policydb, SYM_TYPES, context->type - 1));
1029 scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1036 scontextp += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) +
1030 1 + strlen(policydb.p_role_val_to_name[context->role - 1]) + 1037 1 + strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) +
1031 1 + strlen(policydb.p_type_val_to_name[context->type - 1]); 1038 1 + strlen(sym_name(&policydb, SYM_TYPES, context->type - 1));
1032 1039
1033 mls_sid_to_context(context, &scontextp); 1040 mls_sid_to_context(context, &scontextp);
1034 1041
@@ -1187,16 +1194,13 @@ static int string_to_context_struct(struct policydb *pol,
1187 if (rc) 1194 if (rc)
1188 goto out; 1195 goto out;
1189 1196
1190 if ((p - scontext) < scontext_len) { 1197 rc = -EINVAL;
1191 rc = -EINVAL; 1198 if ((p - scontext) < scontext_len)
1192 goto out; 1199 goto out;
1193 }
1194 1200
1195 /* Check the validity of the new context. */ 1201 /* Check the validity of the new context. */
1196 if (!policydb_context_isvalid(pol, ctx)) { 1202 if (!policydb_context_isvalid(pol, ctx))
1197 rc = -EINVAL;
1198 goto out; 1203 goto out;
1199 }
1200 rc = 0; 1204 rc = 0;
1201out: 1205out:
1202 if (rc) 1206 if (rc)
@@ -1235,27 +1239,26 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
1235 1239
1236 if (force) { 1240 if (force) {
1237 /* Save another copy for storing in uninterpreted form */ 1241 /* Save another copy for storing in uninterpreted form */
1242 rc = -ENOMEM;
1238 str = kstrdup(scontext2, gfp_flags); 1243 str = kstrdup(scontext2, gfp_flags);
1239 if (!str) { 1244 if (!str)
1240 kfree(scontext2); 1245 goto out;
1241 return -ENOMEM;
1242 }
1243 } 1246 }
1244 1247
1245 read_lock(&policy_rwlock); 1248 read_lock(&policy_rwlock);
1246 rc = string_to_context_struct(&policydb, &sidtab, 1249 rc = string_to_context_struct(&policydb, &sidtab, scontext2,
1247 scontext2, scontext_len, 1250 scontext_len, &context, def_sid);
1248 &context, def_sid);
1249 if (rc == -EINVAL && force) { 1251 if (rc == -EINVAL && force) {
1250 context.str = str; 1252 context.str = str;
1251 context.len = scontext_len; 1253 context.len = scontext_len;
1252 str = NULL; 1254 str = NULL;
1253 } else if (rc) 1255 } else if (rc)
1254 goto out; 1256 goto out_unlock;
1255 rc = sidtab_context_to_sid(&sidtab, &context, sid); 1257 rc = sidtab_context_to_sid(&sidtab, &context, sid);
1256 context_destroy(&context); 1258 context_destroy(&context);
1257out: 1259out_unlock:
1258 read_unlock(&policy_rwlock); 1260 read_unlock(&policy_rwlock);
1261out:
1259 kfree(scontext2); 1262 kfree(scontext2);
1260 kfree(str); 1263 kfree(str);
1261 return rc; 1264 return rc;
@@ -1319,18 +1322,18 @@ static int compute_sid_handle_invalid_context(
1319 char *s = NULL, *t = NULL, *n = NULL; 1322 char *s = NULL, *t = NULL, *n = NULL;
1320 u32 slen, tlen, nlen; 1323 u32 slen, tlen, nlen;
1321 1324
1322 if (context_struct_to_string(scontext, &s, &slen) < 0) 1325 if (context_struct_to_string(scontext, &s, &slen))
1323 goto out; 1326 goto out;
1324 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 1327 if (context_struct_to_string(tcontext, &t, &tlen))
1325 goto out; 1328 goto out;
1326 if (context_struct_to_string(newcontext, &n, &nlen) < 0) 1329 if (context_struct_to_string(newcontext, &n, &nlen))
1327 goto out; 1330 goto out;
1328 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 1331 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1329 "security_compute_sid: invalid context %s" 1332 "security_compute_sid: invalid context %s"
1330 " for scontext=%s" 1333 " for scontext=%s"
1331 " tcontext=%s" 1334 " tcontext=%s"
1332 " tclass=%s", 1335 " tclass=%s",
1333 n, s, t, policydb.p_class_val_to_name[tclass-1]); 1336 n, s, t, sym_name(&policydb, SYM_CLASSES, tclass-1));
1334out: 1337out:
1335 kfree(s); 1338 kfree(s);
1336 kfree(t); 1339 kfree(t);
@@ -1569,22 +1572,17 @@ static int clone_sid(u32 sid,
1569 1572
1570static inline int convert_context_handle_invalid_context(struct context *context) 1573static inline int convert_context_handle_invalid_context(struct context *context)
1571{ 1574{
1572 int rc = 0; 1575 char *s;
1576 u32 len;
1573 1577
1574 if (selinux_enforcing) { 1578 if (selinux_enforcing)
1575 rc = -EINVAL; 1579 return -EINVAL;
1576 } else { 1580
1577 char *s; 1581 if (!context_struct_to_string(context, &s, &len)) {
1578 u32 len; 1582 printk(KERN_WARNING "SELinux: Context %s would be invalid if enforcing\n", s);
1579 1583 kfree(s);
1580 if (!context_struct_to_string(context, &s, &len)) {
1581 printk(KERN_WARNING
1582 "SELinux: Context %s would be invalid if enforcing\n",
1583 s);
1584 kfree(s);
1585 }
1586 } 1584 }
1587 return rc; 1585 return 0;
1588} 1586}
1589 1587
1590struct convert_context_args { 1588struct convert_context_args {
@@ -1621,17 +1619,17 @@ static int convert_context(u32 key,
1621 1619
1622 if (c->str) { 1620 if (c->str) {
1623 struct context ctx; 1621 struct context ctx;
1622
1623 rc = -ENOMEM;
1624 s = kstrdup(c->str, GFP_KERNEL); 1624 s = kstrdup(c->str, GFP_KERNEL);
1625 if (!s) { 1625 if (!s)
1626 rc = -ENOMEM;
1627 goto out; 1626 goto out;
1628 } 1627
1629 rc = string_to_context_struct(args->newp, NULL, s, 1628 rc = string_to_context_struct(args->newp, NULL, s,
1630 c->len, &ctx, SECSID_NULL); 1629 c->len, &ctx, SECSID_NULL);
1631 kfree(s); 1630 kfree(s);
1632 if (!rc) { 1631 if (!rc) {
1633 printk(KERN_INFO 1632 printk(KERN_INFO "SELinux: Context %s became valid (mapped).\n",
1634 "SELinux: Context %s became valid (mapped).\n",
1635 c->str); 1633 c->str);
1636 /* Replace string with mapped representation. */ 1634 /* Replace string with mapped representation. */
1637 kfree(c->str); 1635 kfree(c->str);
@@ -1643,8 +1641,7 @@ static int convert_context(u32 key,
1643 goto out; 1641 goto out;
1644 } else { 1642 } else {
1645 /* Other error condition, e.g. ENOMEM. */ 1643 /* Other error condition, e.g. ENOMEM. */
1646 printk(KERN_ERR 1644 printk(KERN_ERR "SELinux: Unable to map context %s, rc = %d.\n",
1647 "SELinux: Unable to map context %s, rc = %d.\n",
1648 c->str, -rc); 1645 c->str, -rc);
1649 goto out; 1646 goto out;
1650 } 1647 }
@@ -1654,25 +1651,26 @@ static int convert_context(u32 key,
1654 if (rc) 1651 if (rc)
1655 goto out; 1652 goto out;
1656 1653
1657 rc = -EINVAL;
1658
1659 /* Convert the user. */ 1654 /* Convert the user. */
1655 rc = -EINVAL;
1660 usrdatum = hashtab_search(args->newp->p_users.table, 1656 usrdatum = hashtab_search(args->newp->p_users.table,
1661 args->oldp->p_user_val_to_name[c->user - 1]); 1657 sym_name(args->oldp, SYM_USERS, c->user - 1));
1662 if (!usrdatum) 1658 if (!usrdatum)
1663 goto bad; 1659 goto bad;
1664 c->user = usrdatum->value; 1660 c->user = usrdatum->value;
1665 1661
1666 /* Convert the role. */ 1662 /* Convert the role. */
1663 rc = -EINVAL;
1667 role = hashtab_search(args->newp->p_roles.table, 1664 role = hashtab_search(args->newp->p_roles.table,
1668 args->oldp->p_role_val_to_name[c->role - 1]); 1665 sym_name(args->oldp, SYM_ROLES, c->role - 1));
1669 if (!role) 1666 if (!role)
1670 goto bad; 1667 goto bad;
1671 c->role = role->value; 1668 c->role = role->value;
1672 1669
1673 /* Convert the type. */ 1670 /* Convert the type. */
1671 rc = -EINVAL;
1674 typdatum = hashtab_search(args->newp->p_types.table, 1672 typdatum = hashtab_search(args->newp->p_types.table,
1675 args->oldp->p_type_val_to_name[c->type - 1]); 1673 sym_name(args->oldp, SYM_TYPES, c->type - 1));
1676 if (!typdatum) 1674 if (!typdatum)
1677 goto bad; 1675 goto bad;
1678 c->type = typdatum->value; 1676 c->type = typdatum->value;
@@ -1700,6 +1698,7 @@ static int convert_context(u32 key,
1700 oc = args->newp->ocontexts[OCON_ISID]; 1698 oc = args->newp->ocontexts[OCON_ISID];
1701 while (oc && oc->sid[0] != SECINITSID_UNLABELED) 1699 while (oc && oc->sid[0] != SECINITSID_UNLABELED)
1702 oc = oc->next; 1700 oc = oc->next;
1701 rc = -EINVAL;
1703 if (!oc) { 1702 if (!oc) {
1704 printk(KERN_ERR "SELinux: unable to look up" 1703 printk(KERN_ERR "SELinux: unable to look up"
1705 " the initial SIDs list\n"); 1704 " the initial SIDs list\n");
@@ -1719,19 +1718,20 @@ static int convert_context(u32 key,
1719 } 1718 }
1720 1719
1721 context_destroy(&oldc); 1720 context_destroy(&oldc);
1721
1722 rc = 0; 1722 rc = 0;
1723out: 1723out:
1724 return rc; 1724 return rc;
1725bad: 1725bad:
1726 /* Map old representation to string and save it. */ 1726 /* Map old representation to string and save it. */
1727 if (context_struct_to_string(&oldc, &s, &len)) 1727 rc = context_struct_to_string(&oldc, &s, &len);
1728 return -ENOMEM; 1728 if (rc)
1729 return rc;
1729 context_destroy(&oldc); 1730 context_destroy(&oldc);
1730 context_destroy(c); 1731 context_destroy(c);
1731 c->str = s; 1732 c->str = s;
1732 c->len = len; 1733 c->len = len;
1733 printk(KERN_INFO 1734 printk(KERN_INFO "SELinux: Context %s became invalid (unmapped).\n",
1734 "SELinux: Context %s became invalid (unmapped).\n",
1735 c->str); 1735 c->str);
1736 rc = 0; 1736 rc = 0;
1737 goto out; 1737 goto out;
@@ -2012,7 +2012,7 @@ int security_node_sid(u16 domain,
2012 u32 addrlen, 2012 u32 addrlen,
2013 u32 *out_sid) 2013 u32 *out_sid)
2014{ 2014{
2015 int rc = 0; 2015 int rc;
2016 struct ocontext *c; 2016 struct ocontext *c;
2017 2017
2018 read_lock(&policy_rwlock); 2018 read_lock(&policy_rwlock);
@@ -2021,10 +2021,9 @@ int security_node_sid(u16 domain,
2021 case AF_INET: { 2021 case AF_INET: {
2022 u32 addr; 2022 u32 addr;
2023 2023
2024 if (addrlen != sizeof(u32)) { 2024 rc = -EINVAL;
2025 rc = -EINVAL; 2025 if (addrlen != sizeof(u32))
2026 goto out; 2026 goto out;
2027 }
2028 2027
2029 addr = *((u32 *)addrp); 2028 addr = *((u32 *)addrp);
2030 2029
@@ -2038,10 +2037,9 @@ int security_node_sid(u16 domain,
2038 } 2037 }
2039 2038
2040 case AF_INET6: 2039 case AF_INET6:
2041 if (addrlen != sizeof(u64) * 2) { 2040 rc = -EINVAL;
2042 rc = -EINVAL; 2041 if (addrlen != sizeof(u64) * 2)
2043 goto out; 2042 goto out;
2044 }
2045 c = policydb.ocontexts[OCON_NODE6]; 2043 c = policydb.ocontexts[OCON_NODE6];
2046 while (c) { 2044 while (c) {
2047 if (match_ipv6_addrmask(addrp, c->u.node6.addr, 2045 if (match_ipv6_addrmask(addrp, c->u.node6.addr,
@@ -2052,6 +2050,7 @@ int security_node_sid(u16 domain,
2052 break; 2050 break;
2053 2051
2054 default: 2052 default:
2053 rc = 0;
2055 *out_sid = SECINITSID_NODE; 2054 *out_sid = SECINITSID_NODE;
2056 goto out; 2055 goto out;
2057 } 2056 }
@@ -2069,6 +2068,7 @@ int security_node_sid(u16 domain,
2069 *out_sid = SECINITSID_NODE; 2068 *out_sid = SECINITSID_NODE;
2070 } 2069 }
2071 2070
2071 rc = 0;
2072out: 2072out:
2073 read_unlock(&policy_rwlock); 2073 read_unlock(&policy_rwlock);
2074 return rc; 2074 return rc;
@@ -2113,24 +2113,22 @@ int security_get_user_sids(u32 fromsid,
2113 2113
2114 context_init(&usercon); 2114 context_init(&usercon);
2115 2115
2116 rc = -EINVAL;
2116 fromcon = sidtab_search(&sidtab, fromsid); 2117 fromcon = sidtab_search(&sidtab, fromsid);
2117 if (!fromcon) { 2118 if (!fromcon)
2118 rc = -EINVAL;
2119 goto out_unlock; 2119 goto out_unlock;
2120 }
2121 2120
2121 rc = -EINVAL;
2122 user = hashtab_search(policydb.p_users.table, username); 2122 user = hashtab_search(policydb.p_users.table, username);
2123 if (!user) { 2123 if (!user)
2124 rc = -EINVAL;
2125 goto out_unlock; 2124 goto out_unlock;
2126 } 2125
2127 usercon.user = user->value; 2126 usercon.user = user->value;
2128 2127
2128 rc = -ENOMEM;
2129 mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC); 2129 mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
2130 if (!mysids) { 2130 if (!mysids)
2131 rc = -ENOMEM;
2132 goto out_unlock; 2131 goto out_unlock;
2133 }
2134 2132
2135 ebitmap_for_each_positive_bit(&user->roles, rnode, i) { 2133 ebitmap_for_each_positive_bit(&user->roles, rnode, i) {
2136 role = policydb.role_val_to_struct[i]; 2134 role = policydb.role_val_to_struct[i];
@@ -2147,12 +2145,11 @@ int security_get_user_sids(u32 fromsid,
2147 if (mynel < maxnel) { 2145 if (mynel < maxnel) {
2148 mysids[mynel++] = sid; 2146 mysids[mynel++] = sid;
2149 } else { 2147 } else {
2148 rc = -ENOMEM;
2150 maxnel += SIDS_NEL; 2149 maxnel += SIDS_NEL;
2151 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC); 2150 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
2152 if (!mysids2) { 2151 if (!mysids2)
2153 rc = -ENOMEM;
2154 goto out_unlock; 2152 goto out_unlock;
2155 }
2156 memcpy(mysids2, mysids, mynel * sizeof(*mysids2)); 2153 memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
2157 kfree(mysids); 2154 kfree(mysids);
2158 mysids = mysids2; 2155 mysids = mysids2;
@@ -2160,7 +2157,7 @@ int security_get_user_sids(u32 fromsid,
2160 } 2157 }
2161 } 2158 }
2162 } 2159 }
2163 2160 rc = 0;
2164out_unlock: 2161out_unlock:
2165 read_unlock(&policy_rwlock); 2162 read_unlock(&policy_rwlock);
2166 if (rc || !mynel) { 2163 if (rc || !mynel) {
@@ -2168,9 +2165,9 @@ out_unlock:
2168 goto out; 2165 goto out;
2169 } 2166 }
2170 2167
2168 rc = -ENOMEM;
2171 mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL); 2169 mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL);
2172 if (!mysids2) { 2170 if (!mysids2) {
2173 rc = -ENOMEM;
2174 kfree(mysids); 2171 kfree(mysids);
2175 goto out; 2172 goto out;
2176 } 2173 }
@@ -2211,7 +2208,7 @@ int security_genfs_sid(const char *fstype,
2211 u16 sclass; 2208 u16 sclass;
2212 struct genfs *genfs; 2209 struct genfs *genfs;
2213 struct ocontext *c; 2210 struct ocontext *c;
2214 int rc = 0, cmp = 0; 2211 int rc, cmp = 0;
2215 2212
2216 while (path[0] == '/' && path[1] == '/') 2213 while (path[0] == '/' && path[1] == '/')
2217 path++; 2214 path++;
@@ -2219,6 +2216,7 @@ int security_genfs_sid(const char *fstype,
2219 read_lock(&policy_rwlock); 2216 read_lock(&policy_rwlock);
2220 2217
2221 sclass = unmap_class(orig_sclass); 2218 sclass = unmap_class(orig_sclass);
2219 *sid = SECINITSID_UNLABELED;
2222 2220
2223 for (genfs = policydb.genfs; genfs; genfs = genfs->next) { 2221 for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
2224 cmp = strcmp(fstype, genfs->fstype); 2222 cmp = strcmp(fstype, genfs->fstype);
@@ -2226,11 +2224,9 @@ int security_genfs_sid(const char *fstype,
2226 break; 2224 break;
2227 } 2225 }
2228 2226
2229 if (!genfs || cmp) { 2227 rc = -ENOENT;
2230 *sid = SECINITSID_UNLABELED; 2228 if (!genfs || cmp)
2231 rc = -ENOENT;
2232 goto out; 2229 goto out;
2233 }
2234 2230
2235 for (c = genfs->head; c; c = c->next) { 2231 for (c = genfs->head; c; c = c->next) {
2236 len = strlen(c->u.name); 2232 len = strlen(c->u.name);
@@ -2239,21 +2235,18 @@ int security_genfs_sid(const char *fstype,
2239 break; 2235 break;
2240 } 2236 }
2241 2237
2242 if (!c) { 2238 rc = -ENOENT;
2243 *sid = SECINITSID_UNLABELED; 2239 if (!c)
2244 rc = -ENOENT;
2245 goto out; 2240 goto out;
2246 }
2247 2241
2248 if (!c->sid[0]) { 2242 if (!c->sid[0]) {
2249 rc = sidtab_context_to_sid(&sidtab, 2243 rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]);
2250 &c->context[0],
2251 &c->sid[0]);
2252 if (rc) 2244 if (rc)
2253 goto out; 2245 goto out;
2254 } 2246 }
2255 2247
2256 *sid = c->sid[0]; 2248 *sid = c->sid[0];
2249 rc = 0;
2257out: 2250out:
2258 read_unlock(&policy_rwlock); 2251 read_unlock(&policy_rwlock);
2259 return rc; 2252 return rc;
@@ -2285,8 +2278,7 @@ int security_fs_use(
2285 if (c) { 2278 if (c) {
2286 *behavior = c->v.behavior; 2279 *behavior = c->v.behavior;
2287 if (!c->sid[0]) { 2280 if (!c->sid[0]) {
2288 rc = sidtab_context_to_sid(&sidtab, 2281 rc = sidtab_context_to_sid(&sidtab, &c->context[0],
2289 &c->context[0],
2290 &c->sid[0]); 2282 &c->sid[0]);
2291 if (rc) 2283 if (rc)
2292 goto out; 2284 goto out;
@@ -2309,34 +2301,39 @@ out:
2309 2301
2310int security_get_bools(int *len, char ***names, int **values) 2302int security_get_bools(int *len, char ***names, int **values)
2311{ 2303{
2312 int i, rc = -ENOMEM; 2304 int i, rc;
2313 2305
2314 read_lock(&policy_rwlock); 2306 read_lock(&policy_rwlock);
2315 *names = NULL; 2307 *names = NULL;
2316 *values = NULL; 2308 *values = NULL;
2317 2309
2310 rc = 0;
2318 *len = policydb.p_bools.nprim; 2311 *len = policydb.p_bools.nprim;
2319 if (!*len) { 2312 if (!*len)
2320 rc = 0;
2321 goto out; 2313 goto out;
2322 }
2323 2314
2324 *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC); 2315 rc = -ENOMEM;
2316 *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC);
2325 if (!*names) 2317 if (!*names)
2326 goto err; 2318 goto err;
2327 2319
2328 *values = kcalloc(*len, sizeof(int), GFP_ATOMIC); 2320 rc = -ENOMEM;
2321 *values = kcalloc(*len, sizeof(int), GFP_ATOMIC);
2329 if (!*values) 2322 if (!*values)
2330 goto err; 2323 goto err;
2331 2324
2332 for (i = 0; i < *len; i++) { 2325 for (i = 0; i < *len; i++) {
2333 size_t name_len; 2326 size_t name_len;
2327
2334 (*values)[i] = policydb.bool_val_to_struct[i]->state; 2328 (*values)[i] = policydb.bool_val_to_struct[i]->state;
2335 name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; 2329 name_len = strlen(sym_name(&policydb, SYM_BOOLS, i)) + 1;
2336 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); 2330
2331 rc = -ENOMEM;
2332 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC);
2337 if (!(*names)[i]) 2333 if (!(*names)[i])
2338 goto err; 2334 goto err;
2339 strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); 2335
2336 strncpy((*names)[i], sym_name(&policydb, SYM_BOOLS, i), name_len);
2340 (*names)[i][name_len - 1] = 0; 2337 (*names)[i][name_len - 1] = 0;
2341 } 2338 }
2342 rc = 0; 2339 rc = 0;
@@ -2355,24 +2352,23 @@ err:
2355 2352
2356int security_set_bools(int len, int *values) 2353int security_set_bools(int len, int *values)
2357{ 2354{
2358 int i, rc = 0; 2355 int i, rc;
2359 int lenp, seqno = 0; 2356 int lenp, seqno = 0;
2360 struct cond_node *cur; 2357 struct cond_node *cur;
2361 2358
2362 write_lock_irq(&policy_rwlock); 2359 write_lock_irq(&policy_rwlock);
2363 2360
2361 rc = -EFAULT;
2364 lenp = policydb.p_bools.nprim; 2362 lenp = policydb.p_bools.nprim;
2365 if (len != lenp) { 2363 if (len != lenp)
2366 rc = -EFAULT;
2367 goto out; 2364 goto out;
2368 }
2369 2365
2370 for (i = 0; i < len; i++) { 2366 for (i = 0; i < len; i++) {
2371 if (!!values[i] != policydb.bool_val_to_struct[i]->state) { 2367 if (!!values[i] != policydb.bool_val_to_struct[i]->state) {
2372 audit_log(current->audit_context, GFP_ATOMIC, 2368 audit_log(current->audit_context, GFP_ATOMIC,
2373 AUDIT_MAC_CONFIG_CHANGE, 2369 AUDIT_MAC_CONFIG_CHANGE,
2374 "bool=%s val=%d old_val=%d auid=%u ses=%u", 2370 "bool=%s val=%d old_val=%d auid=%u ses=%u",
2375 policydb.p_bool_val_to_name[i], 2371 sym_name(&policydb, SYM_BOOLS, i),
2376 !!values[i], 2372 !!values[i],
2377 policydb.bool_val_to_struct[i]->state, 2373 policydb.bool_val_to_struct[i]->state,
2378 audit_get_loginuid(current), 2374 audit_get_loginuid(current),
@@ -2391,7 +2387,7 @@ int security_set_bools(int len, int *values)
2391 } 2387 }
2392 2388
2393 seqno = ++latest_granting; 2389 seqno = ++latest_granting;
2394 2390 rc = 0;
2395out: 2391out:
2396 write_unlock_irq(&policy_rwlock); 2392 write_unlock_irq(&policy_rwlock);
2397 if (!rc) { 2393 if (!rc) {
@@ -2405,16 +2401,15 @@ out:
2405 2401
2406int security_get_bool_value(int bool) 2402int security_get_bool_value(int bool)
2407{ 2403{
2408 int rc = 0; 2404 int rc;
2409 int len; 2405 int len;
2410 2406
2411 read_lock(&policy_rwlock); 2407 read_lock(&policy_rwlock);
2412 2408
2409 rc = -EFAULT;
2413 len = policydb.p_bools.nprim; 2410 len = policydb.p_bools.nprim;
2414 if (bool >= len) { 2411 if (bool >= len)
2415 rc = -EFAULT;
2416 goto out; 2412 goto out;
2417 }
2418 2413
2419 rc = policydb.bool_val_to_struct[bool]->state; 2414 rc = policydb.bool_val_to_struct[bool]->state;
2420out: 2415out:
@@ -2464,8 +2459,9 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2464 struct context newcon; 2459 struct context newcon;
2465 char *s; 2460 char *s;
2466 u32 len; 2461 u32 len;
2467 int rc = 0; 2462 int rc;
2468 2463
2464 rc = 0;
2469 if (!ss_initialized || !policydb.mls_enabled) { 2465 if (!ss_initialized || !policydb.mls_enabled) {
2470 *new_sid = sid; 2466 *new_sid = sid;
2471 goto out; 2467 goto out;
@@ -2474,19 +2470,20 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2474 context_init(&newcon); 2470 context_init(&newcon);
2475 2471
2476 read_lock(&policy_rwlock); 2472 read_lock(&policy_rwlock);
2473
2474 rc = -EINVAL;
2477 context1 = sidtab_search(&sidtab, sid); 2475 context1 = sidtab_search(&sidtab, sid);
2478 if (!context1) { 2476 if (!context1) {
2479 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2477 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2480 __func__, sid); 2478 __func__, sid);
2481 rc = -EINVAL;
2482 goto out_unlock; 2479 goto out_unlock;
2483 } 2480 }
2484 2481
2482 rc = -EINVAL;
2485 context2 = sidtab_search(&sidtab, mls_sid); 2483 context2 = sidtab_search(&sidtab, mls_sid);
2486 if (!context2) { 2484 if (!context2) {
2487 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2485 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2488 __func__, mls_sid); 2486 __func__, mls_sid);
2489 rc = -EINVAL;
2490 goto out_unlock; 2487 goto out_unlock;
2491 } 2488 }
2492 2489
@@ -2500,20 +2497,17 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2500 /* Check the validity of the new context. */ 2497 /* Check the validity of the new context. */
2501 if (!policydb_context_isvalid(&policydb, &newcon)) { 2498 if (!policydb_context_isvalid(&policydb, &newcon)) {
2502 rc = convert_context_handle_invalid_context(&newcon); 2499 rc = convert_context_handle_invalid_context(&newcon);
2503 if (rc) 2500 if (rc) {
2504 goto bad; 2501 if (!context_struct_to_string(&newcon, &s, &len)) {
2502 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2503 "security_sid_mls_copy: invalid context %s", s);
2504 kfree(s);
2505 }
2506 goto out_unlock;
2507 }
2505 } 2508 }
2506 2509
2507 rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid); 2510 rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid);
2508 goto out_unlock;
2509
2510bad:
2511 if (!context_struct_to_string(&newcon, &s, &len)) {
2512 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2513 "security_sid_mls_copy: invalid context %s", s);
2514 kfree(s);
2515 }
2516
2517out_unlock: 2511out_unlock:
2518 read_unlock(&policy_rwlock); 2512 read_unlock(&policy_rwlock);
2519 context_destroy(&newcon); 2513 context_destroy(&newcon);
@@ -2549,6 +2543,8 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2549 struct context *nlbl_ctx; 2543 struct context *nlbl_ctx;
2550 struct context *xfrm_ctx; 2544 struct context *xfrm_ctx;
2551 2545
2546 *peer_sid = SECSID_NULL;
2547
2552 /* handle the common (which also happens to be the set of easy) cases 2548 /* handle the common (which also happens to be the set of easy) cases
2553 * right away, these two if statements catch everything involving a 2549 * right away, these two if statements catch everything involving a
2554 * single or absent peer SID/label */ 2550 * single or absent peer SID/label */
@@ -2567,40 +2563,37 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2567 /* we don't need to check ss_initialized here since the only way both 2563 /* we don't need to check ss_initialized here since the only way both
2568 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the 2564 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
2569 * security server was initialized and ss_initialized was true */ 2565 * security server was initialized and ss_initialized was true */
2570 if (!policydb.mls_enabled) { 2566 if (!policydb.mls_enabled)
2571 *peer_sid = SECSID_NULL;
2572 return 0; 2567 return 0;
2573 }
2574 2568
2575 read_lock(&policy_rwlock); 2569 read_lock(&policy_rwlock);
2576 2570
2571 rc = -EINVAL;
2577 nlbl_ctx = sidtab_search(&sidtab, nlbl_sid); 2572 nlbl_ctx = sidtab_search(&sidtab, nlbl_sid);
2578 if (!nlbl_ctx) { 2573 if (!nlbl_ctx) {
2579 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2574 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2580 __func__, nlbl_sid); 2575 __func__, nlbl_sid);
2581 rc = -EINVAL; 2576 goto out;
2582 goto out_slowpath;
2583 } 2577 }
2578 rc = -EINVAL;
2584 xfrm_ctx = sidtab_search(&sidtab, xfrm_sid); 2579 xfrm_ctx = sidtab_search(&sidtab, xfrm_sid);
2585 if (!xfrm_ctx) { 2580 if (!xfrm_ctx) {
2586 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2581 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2587 __func__, xfrm_sid); 2582 __func__, xfrm_sid);
2588 rc = -EINVAL; 2583 goto out;
2589 goto out_slowpath;
2590 } 2584 }
2591 rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); 2585 rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES);
2586 if (rc)
2587 goto out;
2592 2588
2593out_slowpath: 2589 /* at present NetLabel SIDs/labels really only carry MLS
2590 * information so if the MLS portion of the NetLabel SID
2591 * matches the MLS portion of the labeled XFRM SID/label
2592 * then pass along the XFRM SID as it is the most
2593 * expressive */
2594 *peer_sid = xfrm_sid;
2595out:
2594 read_unlock(&policy_rwlock); 2596 read_unlock(&policy_rwlock);
2595 if (rc == 0)
2596 /* at present NetLabel SIDs/labels really only carry MLS
2597 * information so if the MLS portion of the NetLabel SID
2598 * matches the MLS portion of the labeled XFRM SID/label
2599 * then pass along the XFRM SID as it is the most
2600 * expressive */
2601 *peer_sid = xfrm_sid;
2602 else
2603 *peer_sid = SECSID_NULL;
2604 return rc; 2597 return rc;
2605} 2598}
2606 2599
@@ -2619,10 +2612,11 @@ static int get_classes_callback(void *k, void *d, void *args)
2619 2612
2620int security_get_classes(char ***classes, int *nclasses) 2613int security_get_classes(char ***classes, int *nclasses)
2621{ 2614{
2622 int rc = -ENOMEM; 2615 int rc;
2623 2616
2624 read_lock(&policy_rwlock); 2617 read_lock(&policy_rwlock);
2625 2618
2619 rc = -ENOMEM;
2626 *nclasses = policydb.p_classes.nprim; 2620 *nclasses = policydb.p_classes.nprim;
2627 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC); 2621 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC);
2628 if (!*classes) 2622 if (!*classes)
@@ -2630,7 +2624,7 @@ int security_get_classes(char ***classes, int *nclasses)
2630 2624
2631 rc = hashtab_map(policydb.p_classes.table, get_classes_callback, 2625 rc = hashtab_map(policydb.p_classes.table, get_classes_callback,
2632 *classes); 2626 *classes);
2633 if (rc < 0) { 2627 if (rc) {
2634 int i; 2628 int i;
2635 for (i = 0; i < *nclasses; i++) 2629 for (i = 0; i < *nclasses; i++)
2636 kfree((*classes)[i]); 2630 kfree((*classes)[i]);
@@ -2657,19 +2651,20 @@ static int get_permissions_callback(void *k, void *d, void *args)
2657 2651
2658int security_get_permissions(char *class, char ***perms, int *nperms) 2652int security_get_permissions(char *class, char ***perms, int *nperms)
2659{ 2653{
2660 int rc = -ENOMEM, i; 2654 int rc, i;
2661 struct class_datum *match; 2655 struct class_datum *match;
2662 2656
2663 read_lock(&policy_rwlock); 2657 read_lock(&policy_rwlock);
2664 2658
2659 rc = -EINVAL;
2665 match = hashtab_search(policydb.p_classes.table, class); 2660 match = hashtab_search(policydb.p_classes.table, class);
2666 if (!match) { 2661 if (!match) {
2667 printk(KERN_ERR "SELinux: %s: unrecognized class %s\n", 2662 printk(KERN_ERR "SELinux: %s: unrecognized class %s\n",
2668 __func__, class); 2663 __func__, class);
2669 rc = -EINVAL;
2670 goto out; 2664 goto out;
2671 } 2665 }
2672 2666
2667 rc = -ENOMEM;
2673 *nperms = match->permissions.nprim; 2668 *nperms = match->permissions.nprim;
2674 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC); 2669 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC);
2675 if (!*perms) 2670 if (!*perms)
@@ -2678,13 +2673,13 @@ int security_get_permissions(char *class, char ***perms, int *nperms)
2678 if (match->comdatum) { 2673 if (match->comdatum) {
2679 rc = hashtab_map(match->comdatum->permissions.table, 2674 rc = hashtab_map(match->comdatum->permissions.table,
2680 get_permissions_callback, *perms); 2675 get_permissions_callback, *perms);
2681 if (rc < 0) 2676 if (rc)
2682 goto err; 2677 goto err;
2683 } 2678 }
2684 2679
2685 rc = hashtab_map(match->permissions.table, get_permissions_callback, 2680 rc = hashtab_map(match->permissions.table, get_permissions_callback,
2686 *perms); 2681 *perms);
2687 if (rc < 0) 2682 if (rc)
2688 goto err; 2683 goto err;
2689 2684
2690out: 2685out:
@@ -2796,36 +2791,39 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
2796 switch (field) { 2791 switch (field) {
2797 case AUDIT_SUBJ_USER: 2792 case AUDIT_SUBJ_USER:
2798 case AUDIT_OBJ_USER: 2793 case AUDIT_OBJ_USER:
2794 rc = -EINVAL;
2799 userdatum = hashtab_search(policydb.p_users.table, rulestr); 2795 userdatum = hashtab_search(policydb.p_users.table, rulestr);
2800 if (!userdatum) 2796 if (!userdatum)
2801 rc = -EINVAL; 2797 goto out;
2802 else 2798 tmprule->au_ctxt.user = userdatum->value;
2803 tmprule->au_ctxt.user = userdatum->value;
2804 break; 2799 break;
2805 case AUDIT_SUBJ_ROLE: 2800 case AUDIT_SUBJ_ROLE:
2806 case AUDIT_OBJ_ROLE: 2801 case AUDIT_OBJ_ROLE:
2802 rc = -EINVAL;
2807 roledatum = hashtab_search(policydb.p_roles.table, rulestr); 2803 roledatum = hashtab_search(policydb.p_roles.table, rulestr);
2808 if (!roledatum) 2804 if (!roledatum)
2809 rc = -EINVAL; 2805 goto out;
2810 else 2806 tmprule->au_ctxt.role = roledatum->value;
2811 tmprule->au_ctxt.role = roledatum->value;
2812 break; 2807 break;
2813 case AUDIT_SUBJ_TYPE: 2808 case AUDIT_SUBJ_TYPE:
2814 case AUDIT_OBJ_TYPE: 2809 case AUDIT_OBJ_TYPE:
2810 rc = -EINVAL;
2815 typedatum = hashtab_search(policydb.p_types.table, rulestr); 2811 typedatum = hashtab_search(policydb.p_types.table, rulestr);
2816 if (!typedatum) 2812 if (!typedatum)
2817 rc = -EINVAL; 2813 goto out;
2818 else 2814 tmprule->au_ctxt.type = typedatum->value;
2819 tmprule->au_ctxt.type = typedatum->value;
2820 break; 2815 break;
2821 case AUDIT_SUBJ_SEN: 2816 case AUDIT_SUBJ_SEN:
2822 case AUDIT_SUBJ_CLR: 2817 case AUDIT_SUBJ_CLR:
2823 case AUDIT_OBJ_LEV_LOW: 2818 case AUDIT_OBJ_LEV_LOW:
2824 case AUDIT_OBJ_LEV_HIGH: 2819 case AUDIT_OBJ_LEV_HIGH:
2825 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); 2820 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC);
2821 if (rc)
2822 goto out;
2826 break; 2823 break;
2827 } 2824 }
2828 2825 rc = 0;
2826out:
2829 read_unlock(&policy_rwlock); 2827 read_unlock(&policy_rwlock);
2830 2828
2831 if (rc) { 2829 if (rc) {
@@ -3050,7 +3048,7 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr,
3050int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, 3048int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3051 u32 *sid) 3049 u32 *sid)
3052{ 3050{
3053 int rc = -EIDRM; 3051 int rc;
3054 struct context *ctx; 3052 struct context *ctx;
3055 struct context ctx_new; 3053 struct context ctx_new;
3056 3054
@@ -3061,16 +3059,15 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3061 3059
3062 read_lock(&policy_rwlock); 3060 read_lock(&policy_rwlock);
3063 3061
3064 if (secattr->flags & NETLBL_SECATTR_CACHE) { 3062 if (secattr->flags & NETLBL_SECATTR_CACHE)
3065 *sid = *(u32 *)secattr->cache->data; 3063 *sid = *(u32 *)secattr->cache->data;
3066 rc = 0; 3064 else if (secattr->flags & NETLBL_SECATTR_SECID)
3067 } else if (secattr->flags & NETLBL_SECATTR_SECID) {
3068 *sid = secattr->attr.secid; 3065 *sid = secattr->attr.secid;
3069 rc = 0; 3066 else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) {
3070 } else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { 3067 rc = -EIDRM;
3071 ctx = sidtab_search(&sidtab, SECINITSID_NETMSG); 3068 ctx = sidtab_search(&sidtab, SECINITSID_NETMSG);
3072 if (ctx == NULL) 3069 if (ctx == NULL)
3073 goto netlbl_secattr_to_sid_return; 3070 goto out;
3074 3071
3075 context_init(&ctx_new); 3072 context_init(&ctx_new);
3076 ctx_new.user = ctx->user; 3073 ctx_new.user = ctx->user;
@@ -3078,34 +3075,35 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3078 ctx_new.type = ctx->type; 3075 ctx_new.type = ctx->type;
3079 mls_import_netlbl_lvl(&ctx_new, secattr); 3076 mls_import_netlbl_lvl(&ctx_new, secattr);
3080 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { 3077 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
3081 if (ebitmap_netlbl_import(&ctx_new.range.level[0].cat, 3078 rc = ebitmap_netlbl_import(&ctx_new.range.level[0].cat,
3082 secattr->attr.mls.cat) != 0) 3079 secattr->attr.mls.cat);
3083 goto netlbl_secattr_to_sid_return; 3080 if (rc)
3081 goto out;
3084 memcpy(&ctx_new.range.level[1].cat, 3082 memcpy(&ctx_new.range.level[1].cat,
3085 &ctx_new.range.level[0].cat, 3083 &ctx_new.range.level[0].cat,
3086 sizeof(ctx_new.range.level[0].cat)); 3084 sizeof(ctx_new.range.level[0].cat));
3087 } 3085 }
3088 if (mls_context_isvalid(&policydb, &ctx_new) != 1) 3086 rc = -EIDRM;
3089 goto netlbl_secattr_to_sid_return_cleanup; 3087 if (!mls_context_isvalid(&policydb, &ctx_new))
3088 goto out_free;
3090 3089
3091 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid); 3090 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid);
3092 if (rc != 0) 3091 if (rc)
3093 goto netlbl_secattr_to_sid_return_cleanup; 3092 goto out_free;
3094 3093
3095 security_netlbl_cache_add(secattr, *sid); 3094 security_netlbl_cache_add(secattr, *sid);
3096 3095
3097 ebitmap_destroy(&ctx_new.range.level[0].cat); 3096 ebitmap_destroy(&ctx_new.range.level[0].cat);
3098 } else { 3097 } else
3099 *sid = SECSID_NULL; 3098 *sid = SECSID_NULL;
3100 rc = 0;
3101 }
3102 3099
3103netlbl_secattr_to_sid_return:
3104 read_unlock(&policy_rwlock); 3100 read_unlock(&policy_rwlock);
3105 return rc; 3101 return 0;
3106netlbl_secattr_to_sid_return_cleanup: 3102out_free:
3107 ebitmap_destroy(&ctx_new.range.level[0].cat); 3103 ebitmap_destroy(&ctx_new.range.level[0].cat);
3108 goto netlbl_secattr_to_sid_return; 3104out:
3105 read_unlock(&policy_rwlock);
3106 return rc;
3109} 3107}
3110 3108
3111/** 3109/**
@@ -3127,28 +3125,23 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
3127 return 0; 3125 return 0;
3128 3126
3129 read_lock(&policy_rwlock); 3127 read_lock(&policy_rwlock);
3128
3129 rc = -ENOENT;
3130 ctx = sidtab_search(&sidtab, sid); 3130 ctx = sidtab_search(&sidtab, sid);
3131 if (ctx == NULL) { 3131 if (ctx == NULL)
3132 rc = -ENOENT; 3132 goto out;
3133 goto netlbl_sid_to_secattr_failure; 3133
3134 } 3134 rc = -ENOMEM;
3135 secattr->domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], 3135 secattr->domain = kstrdup(sym_name(&policydb, SYM_TYPES, ctx->type - 1),
3136 GFP_ATOMIC); 3136 GFP_ATOMIC);
3137 if (secattr->domain == NULL) { 3137 if (secattr->domain == NULL)
3138 rc = -ENOMEM; 3138 goto out;
3139 goto netlbl_sid_to_secattr_failure; 3139
3140 }
3141 secattr->attr.secid = sid; 3140 secattr->attr.secid = sid;
3142 secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; 3141 secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID;
3143 mls_export_netlbl_lvl(ctx, secattr); 3142 mls_export_netlbl_lvl(ctx, secattr);
3144 rc = mls_export_netlbl_cat(ctx, secattr); 3143 rc = mls_export_netlbl_cat(ctx, secattr);
3145 if (rc != 0) 3144out:
3146 goto netlbl_sid_to_secattr_failure;
3147 read_unlock(&policy_rwlock);
3148
3149 return 0;
3150
3151netlbl_sid_to_secattr_failure:
3152 read_unlock(&policy_rwlock); 3145 read_unlock(&policy_rwlock);
3153 return rc; 3146 return rc;
3154} 3147}
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index e817989764cd..5840a35155fc 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -147,6 +147,17 @@ out:
147 return rc; 147 return rc;
148} 148}
149 149
150static void sidtab_update_cache(struct sidtab *s, struct sidtab_node *n, int loc)
151{
152 BUG_ON(loc >= SIDTAB_CACHE_LEN);
153
154 while (loc > 0) {
155 s->cache[loc] = s->cache[loc - 1];
156 loc--;
157 }
158 s->cache[0] = n;
159}
160
150static inline u32 sidtab_search_context(struct sidtab *s, 161static inline u32 sidtab_search_context(struct sidtab *s,
151 struct context *context) 162 struct context *context)
152{ 163{
@@ -156,14 +167,33 @@ static inline u32 sidtab_search_context(struct sidtab *s,
156 for (i = 0; i < SIDTAB_SIZE; i++) { 167 for (i = 0; i < SIDTAB_SIZE; i++) {
157 cur = s->htable[i]; 168 cur = s->htable[i];
158 while (cur) { 169 while (cur) {
159 if (context_cmp(&cur->context, context)) 170 if (context_cmp(&cur->context, context)) {
171 sidtab_update_cache(s, cur, SIDTAB_CACHE_LEN - 1);
160 return cur->sid; 172 return cur->sid;
173 }
161 cur = cur->next; 174 cur = cur->next;
162 } 175 }
163 } 176 }
164 return 0; 177 return 0;
165} 178}
166 179
180static inline u32 sidtab_search_cache(struct sidtab *s, struct context *context)
181{
182 int i;
183 struct sidtab_node *node;
184
185 for (i = 0; i < SIDTAB_CACHE_LEN; i++) {
186 node = s->cache[i];
187 if (unlikely(!node))
188 return 0;
189 if (context_cmp(&node->context, context)) {
190 sidtab_update_cache(s, node, i);
191 return node->sid;
192 }
193 }
194 return 0;
195}
196
167int sidtab_context_to_sid(struct sidtab *s, 197int sidtab_context_to_sid(struct sidtab *s,
168 struct context *context, 198 struct context *context,
169 u32 *out_sid) 199 u32 *out_sid)
@@ -174,7 +204,9 @@ int sidtab_context_to_sid(struct sidtab *s,
174 204
175 *out_sid = SECSID_NULL; 205 *out_sid = SECSID_NULL;
176 206
177 sid = sidtab_search_context(s, context); 207 sid = sidtab_search_cache(s, context);
208 if (!sid)
209 sid = sidtab_search_context(s, context);
178 if (!sid) { 210 if (!sid) {
179 spin_lock_irqsave(&s->lock, flags); 211 spin_lock_irqsave(&s->lock, flags);
180 /* Rescan now that we hold the lock. */ 212 /* Rescan now that we hold the lock. */
@@ -259,12 +291,15 @@ void sidtab_destroy(struct sidtab *s)
259void sidtab_set(struct sidtab *dst, struct sidtab *src) 291void sidtab_set(struct sidtab *dst, struct sidtab *src)
260{ 292{
261 unsigned long flags; 293 unsigned long flags;
294 int i;
262 295
263 spin_lock_irqsave(&src->lock, flags); 296 spin_lock_irqsave(&src->lock, flags);
264 dst->htable = src->htable; 297 dst->htable = src->htable;
265 dst->nel = src->nel; 298 dst->nel = src->nel;
266 dst->next_sid = src->next_sid; 299 dst->next_sid = src->next_sid;
267 dst->shutdown = 0; 300 dst->shutdown = 0;
301 for (i = 0; i < SIDTAB_CACHE_LEN; i++)
302 dst->cache[i] = NULL;
268 spin_unlock_irqrestore(&src->lock, flags); 303 spin_unlock_irqrestore(&src->lock, flags);
269} 304}
270 305
diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h
index 64ea5b1cdea4..84dc154d9389 100644
--- a/security/selinux/ss/sidtab.h
+++ b/security/selinux/ss/sidtab.h
@@ -26,6 +26,8 @@ struct sidtab {
26 unsigned int nel; /* number of elements */ 26 unsigned int nel; /* number of elements */
27 unsigned int next_sid; /* next SID to allocate */ 27 unsigned int next_sid; /* next SID to allocate */
28 unsigned char shutdown; 28 unsigned char shutdown;
29#define SIDTAB_CACHE_LEN 3
30 struct sidtab_node *cache[SIDTAB_CACHE_LEN];
29 spinlock_t lock; 31 spinlock_t lock;
30}; 32};
31 33