summaryrefslogtreecommitdiffstats
path: root/security/selinux/selinuxfs.c
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2018-03-01 18:48:02 -0500
committerPaul Moore <paul@paul-moore.com>2018-03-01 18:48:02 -0500
commitaa8e712cee93d520e96a2ca8e3a20f807c937e3f (patch)
tree5e2bdce92022ebb334bfa68b6a731b71ef86974d /security/selinux/selinuxfs.c
parent2572f5b4245abf2b4e5a86cabf65a50efda09aac (diff)
selinux: wrap global selinux state
Define a selinux state structure (struct selinux_state) for global SELinux state and pass it explicitly to all security server functions. The public portion of the structure contains state that is used throughout the SELinux code, such as the enforcing mode. The structure also contains a pointer to a selinux_ss structure whose definition is private to the security server and contains security server specific state such as the policy database and SID table. This change should have no effect on SELinux behavior or APIs (userspace or LSM). It merely wraps SELinux state and passes it explicitly as needed. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> [PM: minor fixups needed due to collisions with the SCTP patches] Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'security/selinux/selinuxfs.c')
-rw-r--r--security/selinux/selinuxfs.c145
1 files changed, 82 insertions, 63 deletions
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 00eed842c491..98492755adbf 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -41,17 +41,6 @@
41#include "objsec.h" 41#include "objsec.h"
42#include "conditional.h" 42#include "conditional.h"
43 43
44unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
45
46static int __init checkreqprot_setup(char *str)
47{
48 unsigned long checkreqprot;
49 if (!kstrtoul(str, 0, &checkreqprot))
50 selinux_checkreqprot = checkreqprot ? 1 : 0;
51 return 1;
52}
53__setup("checkreqprot=", checkreqprot_setup);
54
55static DEFINE_MUTEX(sel_mutex); 44static DEFINE_MUTEX(sel_mutex);
56 45
57/* global data for booleans */ 46/* global data for booleans */
@@ -108,7 +97,8 @@ static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
108 char tmpbuf[TMPBUFLEN]; 97 char tmpbuf[TMPBUFLEN];
109 ssize_t length; 98 ssize_t length;
110 99
111 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_enforcing); 100 length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
101 is_enforcing(&selinux_state));
112 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 102 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
113} 103}
114 104
@@ -119,7 +109,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
119{ 109{
120 char *page = NULL; 110 char *page = NULL;
121 ssize_t length; 111 ssize_t length;
122 int new_value; 112 int old_value, new_value;
123 113
124 if (count >= PAGE_SIZE) 114 if (count >= PAGE_SIZE)
125 return -ENOMEM; 115 return -ENOMEM;
@@ -138,7 +128,9 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
138 128
139 new_value = !!new_value; 129 new_value = !!new_value;
140 130
141 if (new_value != selinux_enforcing) { 131 old_value = is_enforcing(&selinux_state);
132
133 if (new_value != old_value) {
142 length = avc_has_perm(current_sid(), SECINITSID_SECURITY, 134 length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
143 SECCLASS_SECURITY, SECURITY__SETENFORCE, 135 SECCLASS_SECURITY, SECURITY__SETENFORCE,
144 NULL); 136 NULL);
@@ -146,15 +138,16 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
146 goto out; 138 goto out;
147 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, 139 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
148 "enforcing=%d old_enforcing=%d auid=%u ses=%u", 140 "enforcing=%d old_enforcing=%d auid=%u ses=%u",
149 new_value, selinux_enforcing, 141 new_value, old_value,
150 from_kuid(&init_user_ns, audit_get_loginuid(current)), 142 from_kuid(&init_user_ns, audit_get_loginuid(current)),
151 audit_get_sessionid(current)); 143 audit_get_sessionid(current));
152 selinux_enforcing = new_value; 144 set_enforcing(&selinux_state, new_value);
153 if (selinux_enforcing) 145 if (new_value)
154 avc_ss_reset(0); 146 avc_ss_reset(0);
155 selnl_notify_setenforce(selinux_enforcing); 147 selnl_notify_setenforce(new_value);
156 selinux_status_update_setenforce(selinux_enforcing); 148 selinux_status_update_setenforce(&selinux_state,
157 if (!selinux_enforcing) 149 new_value);
150 if (!new_value)
158 call_lsm_notifier(LSM_POLICY_CHANGE, NULL); 151 call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
159 } 152 }
160 length = count; 153 length = count;
@@ -179,7 +172,8 @@ static ssize_t sel_read_handle_unknown(struct file *filp, char __user *buf,
179 ssize_t length; 172 ssize_t length;
180 ino_t ino = file_inode(filp)->i_ino; 173 ino_t ino = file_inode(filp)->i_ino;
181 int handle_unknown = (ino == SEL_REJECT_UNKNOWN) ? 174 int handle_unknown = (ino == SEL_REJECT_UNKNOWN) ?
182 security_get_reject_unknown() : !security_get_allow_unknown(); 175 security_get_reject_unknown(&selinux_state) :
176 !security_get_allow_unknown(&selinux_state);
183 177
184 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", handle_unknown); 178 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", handle_unknown);
185 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 179 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
@@ -192,7 +186,7 @@ static const struct file_operations sel_handle_unknown_ops = {
192 186
193static int sel_open_handle_status(struct inode *inode, struct file *filp) 187static int sel_open_handle_status(struct inode *inode, struct file *filp)
194{ 188{
195 struct page *status = selinux_kernel_status_page(); 189 struct page *status = selinux_kernel_status_page(&selinux_state);
196 190
197 if (!status) 191 if (!status)
198 return -ENOMEM; 192 return -ENOMEM;
@@ -268,7 +262,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
268 goto out; 262 goto out;
269 263
270 if (new_value) { 264 if (new_value) {
271 length = selinux_disable(); 265 length = selinux_disable(&selinux_state);
272 if (length) 266 if (length)
273 goto out; 267 goto out;
274 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, 268 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
@@ -322,7 +316,7 @@ static ssize_t sel_read_mls(struct file *filp, char __user *buf,
322 ssize_t length; 316 ssize_t length;
323 317
324 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", 318 length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
325 security_mls_enabled()); 319 security_mls_enabled(&selinux_state));
326 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 320 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
327} 321}
328 322
@@ -359,13 +353,13 @@ static int sel_open_policy(struct inode *inode, struct file *filp)
359 if (!plm) 353 if (!plm)
360 goto err; 354 goto err;
361 355
362 if (i_size_read(inode) != security_policydb_len()) { 356 if (i_size_read(inode) != security_policydb_len(&selinux_state)) {
363 inode_lock(inode); 357 inode_lock(inode);
364 i_size_write(inode, security_policydb_len()); 358 i_size_write(inode, security_policydb_len(&selinux_state));
365 inode_unlock(inode); 359 inode_unlock(inode);
366 } 360 }
367 361
368 rc = security_read_policy(&plm->data, &plm->len); 362 rc = security_read_policy(&selinux_state, &plm->data, &plm->len);
369 if (rc) 363 if (rc)
370 goto err; 364 goto err;
371 365
@@ -500,7 +494,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
500 if (copy_from_user(data, buf, count) != 0) 494 if (copy_from_user(data, buf, count) != 0)
501 goto out; 495 goto out;
502 496
503 length = security_load_policy(data, count); 497 length = security_load_policy(&selinux_state, data, count);
504 if (length) { 498 if (length) {
505 pr_warn_ratelimited("SELinux: failed to load policy\n"); 499 pr_warn_ratelimited("SELinux: failed to load policy\n");
506 goto out; 500 goto out;
@@ -553,11 +547,12 @@ static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
553 if (length) 547 if (length)
554 goto out; 548 goto out;
555 549
556 length = security_context_to_sid(buf, size, &sid, GFP_KERNEL); 550 length = security_context_to_sid(&selinux_state, buf, size,
551 &sid, GFP_KERNEL);
557 if (length) 552 if (length)
558 goto out; 553 goto out;
559 554
560 length = security_sid_to_context(sid, &canon, &len); 555 length = security_sid_to_context(&selinux_state, sid, &canon, &len);
561 if (length) 556 if (length)
562 goto out; 557 goto out;
563 558
@@ -581,7 +576,7 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
581 char tmpbuf[TMPBUFLEN]; 576 char tmpbuf[TMPBUFLEN];
582 ssize_t length; 577 ssize_t length;
583 578
584 length = scnprintf(tmpbuf, TMPBUFLEN, "%u", selinux_checkreqprot); 579 length = scnprintf(tmpbuf, TMPBUFLEN, "%u", selinux_state.checkreqprot);
585 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 580 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
586} 581}
587 582
@@ -613,7 +608,7 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
613 if (sscanf(page, "%u", &new_value) != 1) 608 if (sscanf(page, "%u", &new_value) != 1)
614 goto out; 609 goto out;
615 610
616 selinux_checkreqprot = new_value ? 1 : 0; 611 selinux_state.checkreqprot = new_value ? 1 : 0;
617 length = count; 612 length = count;
618out: 613out:
619 kfree(page); 614 kfree(page);
@@ -673,19 +668,23 @@ static ssize_t sel_write_validatetrans(struct file *file,
673 if (sscanf(req, "%s %s %hu %s", oldcon, newcon, &tclass, taskcon) != 4) 668 if (sscanf(req, "%s %s %hu %s", oldcon, newcon, &tclass, taskcon) != 4)
674 goto out; 669 goto out;
675 670
676 rc = security_context_str_to_sid(oldcon, &osid, GFP_KERNEL); 671 rc = security_context_str_to_sid(&selinux_state, oldcon, &osid,
672 GFP_KERNEL);
677 if (rc) 673 if (rc)
678 goto out; 674 goto out;
679 675
680 rc = security_context_str_to_sid(newcon, &nsid, GFP_KERNEL); 676 rc = security_context_str_to_sid(&selinux_state, newcon, &nsid,
677 GFP_KERNEL);
681 if (rc) 678 if (rc)
682 goto out; 679 goto out;
683 680
684 rc = security_context_str_to_sid(taskcon, &tsid, GFP_KERNEL); 681 rc = security_context_str_to_sid(&selinux_state, taskcon, &tsid,
682 GFP_KERNEL);
685 if (rc) 683 if (rc)
686 goto out; 684 goto out;
687 685
688 rc = security_validate_transition_user(osid, nsid, tsid, tclass); 686 rc = security_validate_transition_user(&selinux_state, osid, nsid,
687 tsid, tclass);
689 if (!rc) 688 if (!rc)
690 rc = count; 689 rc = count;
691out: 690out:
@@ -780,15 +779,17 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
780 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 779 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
781 goto out; 780 goto out;
782 781
783 length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL); 782 length = security_context_str_to_sid(&selinux_state, scon, &ssid,
783 GFP_KERNEL);
784 if (length) 784 if (length)
785 goto out; 785 goto out;
786 786
787 length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL); 787 length = security_context_str_to_sid(&selinux_state, tcon, &tsid,
788 GFP_KERNEL);
788 if (length) 789 if (length)
789 goto out; 790 goto out;
790 791
791 security_compute_av_user(ssid, tsid, tclass, &avd); 792 security_compute_av_user(&selinux_state, ssid, tsid, tclass, &avd);
792 793
793 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, 794 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
794 "%x %x %x %x %u %x", 795 "%x %x %x %x %u %x",
@@ -868,20 +869,23 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
868 objname = namebuf; 869 objname = namebuf;
869 } 870 }
870 871
871 length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL); 872 length = security_context_str_to_sid(&selinux_state, scon, &ssid,
873 GFP_KERNEL);
872 if (length) 874 if (length)
873 goto out; 875 goto out;
874 876
875 length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL); 877 length = security_context_str_to_sid(&selinux_state, tcon, &tsid,
878 GFP_KERNEL);
876 if (length) 879 if (length)
877 goto out; 880 goto out;
878 881
879 length = security_transition_sid_user(ssid, tsid, tclass, 882 length = security_transition_sid_user(&selinux_state, ssid, tsid,
880 objname, &newsid); 883 tclass, objname, &newsid);
881 if (length) 884 if (length)
882 goto out; 885 goto out;
883 886
884 length = security_sid_to_context(newsid, &newcon, &len); 887 length = security_sid_to_context(&selinux_state, newsid, &newcon,
888 &len);
885 if (length) 889 if (length)
886 goto out; 890 goto out;
887 891
@@ -931,19 +935,23 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
931 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 935 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
932 goto out; 936 goto out;
933 937
934 length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL); 938 length = security_context_str_to_sid(&selinux_state, scon, &ssid,
939 GFP_KERNEL);
935 if (length) 940 if (length)
936 goto out; 941 goto out;
937 942
938 length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL); 943 length = security_context_str_to_sid(&selinux_state, tcon, &tsid,
944 GFP_KERNEL);
939 if (length) 945 if (length)
940 goto out; 946 goto out;
941 947
942 length = security_change_sid(ssid, tsid, tclass, &newsid); 948 length = security_change_sid(&selinux_state, ssid, tsid, tclass,
949 &newsid);
943 if (length) 950 if (length)
944 goto out; 951 goto out;
945 952
946 length = security_sid_to_context(newsid, &newcon, &len); 953 length = security_sid_to_context(&selinux_state, newsid, &newcon,
954 &len);
947 if (length) 955 if (length)
948 goto out; 956 goto out;
949 957
@@ -989,18 +997,21 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
989 if (sscanf(buf, "%s %s", con, user) != 2) 997 if (sscanf(buf, "%s %s", con, user) != 2)
990 goto out; 998 goto out;
991 999
992 length = security_context_str_to_sid(con, &sid, GFP_KERNEL); 1000 length = security_context_str_to_sid(&selinux_state, con, &sid,
1001 GFP_KERNEL);
993 if (length) 1002 if (length)
994 goto out; 1003 goto out;
995 1004
996 length = security_get_user_sids(sid, user, &sids, &nsids); 1005 length = security_get_user_sids(&selinux_state, sid, user, &sids,
1006 &nsids);
997 if (length) 1007 if (length)
998 goto out; 1008 goto out;
999 1009
1000 length = sprintf(buf, "%u", nsids) + 1; 1010 length = sprintf(buf, "%u", nsids) + 1;
1001 ptr = buf + length; 1011 ptr = buf + length;
1002 for (i = 0; i < nsids; i++) { 1012 for (i = 0; i < nsids; i++) {
1003 rc = security_sid_to_context(sids[i], &newcon, &len); 1013 rc = security_sid_to_context(&selinux_state, sids[i],
1014 &newcon, &len);
1004 if (rc) { 1015 if (rc) {
1005 length = rc; 1016 length = rc;
1006 goto out; 1017 goto out;
@@ -1051,19 +1062,23 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
1051 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 1062 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
1052 goto out; 1063 goto out;
1053 1064
1054 length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL); 1065 length = security_context_str_to_sid(&selinux_state, scon, &ssid,
1066 GFP_KERNEL);
1055 if (length) 1067 if (length)
1056 goto out; 1068 goto out;
1057 1069
1058 length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL); 1070 length = security_context_str_to_sid(&selinux_state, tcon, &tsid,
1071 GFP_KERNEL);
1059 if (length) 1072 if (length)
1060 goto out; 1073 goto out;
1061 1074
1062 length = security_member_sid(ssid, tsid, tclass, &newsid); 1075 length = security_member_sid(&selinux_state, ssid, tsid, tclass,
1076 &newsid);
1063 if (length) 1077 if (length)
1064 goto out; 1078 goto out;
1065 1079
1066 length = security_sid_to_context(newsid, &newcon, &len); 1080 length = security_sid_to_context(&selinux_state, newsid, &newcon,
1081 &len);
1067 if (length) 1082 if (length)
1068 goto out; 1083 goto out;
1069 1084
@@ -1115,7 +1130,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
1115 if (!page) 1130 if (!page)
1116 goto out; 1131 goto out;
1117 1132
1118 cur_enforcing = security_get_bool_value(index); 1133 cur_enforcing = security_get_bool_value(&selinux_state, index);
1119 if (cur_enforcing < 0) { 1134 if (cur_enforcing < 0) {
1120 ret = cur_enforcing; 1135 ret = cur_enforcing;
1121 goto out; 1136 goto out;
@@ -1226,7 +1241,8 @@ static ssize_t sel_commit_bools_write(struct file *filep,
1226 1241
1227 length = 0; 1242 length = 0;
1228 if (new_value && bool_pending_values) 1243 if (new_value && bool_pending_values)
1229 length = security_set_bools(bool_num, bool_pending_values); 1244 length = security_set_bools(&selinux_state, bool_num,
1245 bool_pending_values);
1230 1246
1231 if (!length) 1247 if (!length)
1232 length = count; 1248 length = count;
@@ -1279,7 +1295,7 @@ static int sel_make_bools(void)
1279 if (!page) 1295 if (!page)
1280 goto out; 1296 goto out;
1281 1297
1282 ret = security_get_bools(&num, &names, &values); 1298 ret = security_get_bools(&selinux_state, &num, &names, &values);
1283 if (ret) 1299 if (ret)
1284 goto out; 1300 goto out;
1285 1301
@@ -1300,7 +1316,8 @@ static int sel_make_bools(void)
1300 goto out; 1316 goto out;
1301 1317
1302 isec = (struct inode_security_struct *)inode->i_security; 1318 isec = (struct inode_security_struct *)inode->i_security;
1303 ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid); 1319 ret = security_genfs_sid(&selinux_state, "selinuxfs", page,
1320 SECCLASS_FILE, &sid);
1304 if (ret) { 1321 if (ret) {
1305 pr_warn_ratelimited("SELinux: no sid found, defaulting to security isid for %s\n", 1322 pr_warn_ratelimited("SELinux: no sid found, defaulting to security isid for %s\n",
1306 page); 1323 page);
@@ -1524,7 +1541,7 @@ static ssize_t sel_read_initcon(struct file *file, char __user *buf,
1524 ssize_t ret; 1541 ssize_t ret;
1525 1542
1526 sid = file_inode(file)->i_ino&SEL_INO_MASK; 1543 sid = file_inode(file)->i_ino&SEL_INO_MASK;
1527 ret = security_sid_to_context(sid, &con, &len); 1544 ret = security_sid_to_context(&selinux_state, sid, &con, &len);
1528 if (ret) 1545 if (ret)
1529 return ret; 1546 return ret;
1530 1547
@@ -1617,7 +1634,8 @@ static ssize_t sel_read_policycap(struct file *file, char __user *buf,
1617 ssize_t length; 1634 ssize_t length;
1618 unsigned long i_ino = file_inode(file)->i_ino; 1635 unsigned long i_ino = file_inode(file)->i_ino;
1619 1636
1620 value = security_policycap_supported(i_ino & SEL_INO_MASK); 1637 value = security_policycap_supported(&selinux_state,
1638 i_ino & SEL_INO_MASK);
1621 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value); 1639 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);
1622 1640
1623 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 1641 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
@@ -1634,7 +1652,8 @@ static int sel_make_perm_files(char *objclass, int classvalue,
1634 int i, rc, nperms; 1652 int i, rc, nperms;
1635 char **perms; 1653 char **perms;
1636 1654
1637 rc = security_get_permissions(objclass, &perms, &nperms); 1655 rc = security_get_permissions(&selinux_state, objclass, &perms,
1656 &nperms);
1638 if (rc) 1657 if (rc)
1639 return rc; 1658 return rc;
1640 1659
@@ -1701,7 +1720,7 @@ static int sel_make_classes(void)
1701 /* delete any existing entries */ 1720 /* delete any existing entries */
1702 sel_remove_entries(class_dir); 1721 sel_remove_entries(class_dir);
1703 1722
1704 rc = security_get_classes(&classes, &nclasses); 1723 rc = security_get_classes(&selinux_state, &classes, &nclasses);
1705 if (rc) 1724 if (rc)
1706 return rc; 1725 return rc;
1707 1726