aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2014-03-31 09:49:07 -0400
committerPaul Moore <pmoore@redhat.com>2014-03-31 09:49:07 -0400
commit6d32c850621b0be75777b9102b14f6268bbd9f0f (patch)
treefec325f5c1ae763f5eccb3ca1254ab9d9d164b05 /security
parenteee3094683fbc7fe6bcdaef58c1ef31f8460cdca (diff)
parent455c6fdbd219161bd09b1165f11699d6d73de11c (diff)
Merge tag 'v3.14' into next
Linux 3.14
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig2
-rw-r--r--security/capability.c3
-rw-r--r--security/device_cgroup.c7
-rw-r--r--security/integrity/ima/ima_template_lib.c18
-rw-r--r--security/keys/keyring.c6
-rw-r--r--security/security.c6
-rw-r--r--security/selinux/hooks.c13
-rw-r--r--security/selinux/include/security.h2
-rw-r--r--security/selinux/include/xfrm.h3
-rw-r--r--security/selinux/nlmsgtab.c2
-rw-r--r--security/selinux/selinuxfs.c28
-rw-r--r--security/selinux/ss/policydb.c8
-rw-r--r--security/selinux/ss/services.c22
-rw-r--r--security/selinux/xfrm.c14
-rw-r--r--security/smack/smack.h5
-rw-r--r--security/smack/smack_lsm.c145
-rw-r--r--security/smack/smackfs.c134
17 files changed, 260 insertions, 158 deletions
diff --git a/security/Kconfig b/security/Kconfig
index e9c6ac724fef..beb86b500adf 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -103,7 +103,7 @@ config INTEL_TXT
103config LSM_MMAP_MIN_ADDR 103config LSM_MMAP_MIN_ADDR
104 int "Low address space for LSM to protect from user allocation" 104 int "Low address space for LSM to protect from user allocation"
105 depends on SECURITY && SECURITY_SELINUX 105 depends on SECURITY && SECURITY_SELINUX
106 default 32768 if ARM 106 default 32768 if ARM || (ARM64 && COMPAT)
107 default 65536 107 default 65536
108 help 108 help
109 This is the portion of low virtual memory which should be protected 109 This is the portion of low virtual memory which should be protected
diff --git a/security/capability.c b/security/capability.c
index 8b4f24ae4338..21e2b9cae685 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -757,7 +757,8 @@ static void cap_skb_owned_by(struct sk_buff *skb, struct sock *sk)
757 757
758#ifdef CONFIG_SECURITY_NETWORK_XFRM 758#ifdef CONFIG_SECURITY_NETWORK_XFRM
759static int cap_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp, 759static int cap_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp,
760 struct xfrm_user_sec_ctx *sec_ctx) 760 struct xfrm_user_sec_ctx *sec_ctx,
761 gfp_t gfp)
761{ 762{
762 return 0; 763 return 0;
763} 764}
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 7c2a0a71049e..d3b6d2cd3a06 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -274,10 +274,9 @@ static void set_majmin(char *str, unsigned m)
274 sprintf(str, "%u", m); 274 sprintf(str, "%u", m);
275} 275}
276 276
277static int devcgroup_seq_read(struct cgroup_subsys_state *css, 277static int devcgroup_seq_show(struct seq_file *m, void *v)
278 struct cftype *cft, struct seq_file *m)
279{ 278{
280 struct dev_cgroup *devcgroup = css_to_devcgroup(css); 279 struct dev_cgroup *devcgroup = css_to_devcgroup(seq_css(m));
281 struct dev_exception_item *ex; 280 struct dev_exception_item *ex;
282 char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN]; 281 char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN];
283 282
@@ -679,7 +678,7 @@ static struct cftype dev_cgroup_files[] = {
679 }, 678 },
680 { 679 {
681 .name = "list", 680 .name = "list",
682 .read_seq_string = devcgroup_seq_read, 681 .seq_show = devcgroup_seq_show,
683 .private = DEVCG_LIST, 682 .private = DEVCG_LIST,
684 }, 683 },
685 { } /* terminate */ 684 { } /* terminate */
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index c38adcc910fb..1683bbf289a4 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -162,8 +162,7 @@ void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
162} 162}
163 163
164static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo, 164static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
165 struct ima_field_data *field_data, 165 struct ima_field_data *field_data)
166 bool size_limit)
167{ 166{
168 /* 167 /*
169 * digest formats: 168 * digest formats:
@@ -176,11 +175,10 @@ static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
176 enum data_formats fmt = DATA_FMT_DIGEST; 175 enum data_formats fmt = DATA_FMT_DIGEST;
177 u32 offset = 0; 176 u32 offset = 0;
178 177
179 if (!size_limit) { 178 if (hash_algo < HASH_ALGO__LAST) {
180 fmt = DATA_FMT_DIGEST_WITH_ALGO; 179 fmt = DATA_FMT_DIGEST_WITH_ALGO;
181 if (hash_algo < HASH_ALGO__LAST) 180 offset += snprintf(buffer, CRYPTO_MAX_ALG_NAME + 1, "%s",
182 offset += snprintf(buffer, CRYPTO_MAX_ALG_NAME + 1, 181 hash_algo_name[hash_algo]);
183 "%s", hash_algo_name[hash_algo]);
184 buffer[offset] = ':'; 182 buffer[offset] = ':';
185 offset += 2; 183 offset += 2;
186 } 184 }
@@ -243,8 +241,8 @@ int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
243 cur_digest = hash.hdr.digest; 241 cur_digest = hash.hdr.digest;
244 cur_digestsize = hash.hdr.length; 242 cur_digestsize = hash.hdr.length;
245out: 243out:
246 return ima_eventdigest_init_common(cur_digest, cur_digestsize, -1, 244 return ima_eventdigest_init_common(cur_digest, cur_digestsize,
247 field_data, true); 245 HASH_ALGO__LAST, field_data);
248} 246}
249 247
250/* 248/*
@@ -255,7 +253,7 @@ int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
255 struct evm_ima_xattr_data *xattr_value, 253 struct evm_ima_xattr_data *xattr_value,
256 int xattr_len, struct ima_field_data *field_data) 254 int xattr_len, struct ima_field_data *field_data)
257{ 255{
258 u8 *cur_digest = NULL, hash_algo = HASH_ALGO__LAST; 256 u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1;
259 u32 cur_digestsize = 0; 257 u32 cur_digestsize = 0;
260 258
261 /* If iint is NULL, we are recording a violation. */ 259 /* If iint is NULL, we are recording a violation. */
@@ -268,7 +266,7 @@ int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
268 hash_algo = iint->ima_hash->algo; 266 hash_algo = iint->ima_hash->algo;
269out: 267out:
270 return ima_eventdigest_init_common(cur_digest, cur_digestsize, 268 return ima_eventdigest_init_common(cur_digest, cur_digestsize,
271 hash_algo, field_data, false); 269 hash_algo, field_data);
272} 270}
273 271
274static int ima_eventname_init_common(struct integrity_iint_cache *iint, 272static int ima_eventname_init_common(struct integrity_iint_cache *iint,
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index d46cbc5e335e..2fb2576dc644 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -1000,7 +1000,11 @@ static int keyring_detect_cycle_iterator(const void *object,
1000 1000
1001 kenter("{%d}", key->serial); 1001 kenter("{%d}", key->serial);
1002 1002
1003 BUG_ON(key != ctx->match_data); 1003 /* We might get a keyring with matching index-key that is nonetheless a
1004 * different keyring. */
1005 if (key != ctx->match_data)
1006 return 0;
1007
1004 ctx->result = ERR_PTR(-EDEADLK); 1008 ctx->result = ERR_PTR(-EDEADLK);
1005 return 1; 1009 return 1;
1006} 1010}
diff --git a/security/security.c b/security/security.c
index 15b6928592ef..919cad93ac82 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1317,9 +1317,11 @@ void security_skb_owned_by(struct sk_buff *skb, struct sock *sk)
1317 1317
1318#ifdef CONFIG_SECURITY_NETWORK_XFRM 1318#ifdef CONFIG_SECURITY_NETWORK_XFRM
1319 1319
1320int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx) 1320int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
1321 struct xfrm_user_sec_ctx *sec_ctx,
1322 gfp_t gfp)
1321{ 1323{
1322 return security_ops->xfrm_policy_alloc_security(ctxp, sec_ctx); 1324 return security_ops->xfrm_policy_alloc_security(ctxp, sec_ctx, gfp);
1323} 1325}
1324EXPORT_SYMBOL(security_xfrm_policy_alloc); 1326EXPORT_SYMBOL(security_xfrm_policy_alloc);
1325 1327
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8b1656f053f8..d58946dca8c9 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -668,7 +668,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
668 if (flags[i] == SBLABEL_MNT) 668 if (flags[i] == SBLABEL_MNT)
669 continue; 669 continue;
670 rc = security_context_to_sid(mount_options[i], 670 rc = security_context_to_sid(mount_options[i],
671 strlen(mount_options[i]), &sid); 671 strlen(mount_options[i]), &sid, GFP_KERNEL);
672 if (rc) { 672 if (rc) {
673 printk(KERN_WARNING "SELinux: security_context_to_sid" 673 printk(KERN_WARNING "SELinux: security_context_to_sid"
674 "(%s) failed for (dev %s, type %s) errno=%d\n", 674 "(%s) failed for (dev %s, type %s) errno=%d\n",
@@ -2507,7 +2507,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
2507 if (flags[i] == SBLABEL_MNT) 2507 if (flags[i] == SBLABEL_MNT)
2508 continue; 2508 continue;
2509 len = strlen(mount_options[i]); 2509 len = strlen(mount_options[i]);
2510 rc = security_context_to_sid(mount_options[i], len, &sid); 2510 rc = security_context_to_sid(mount_options[i], len, &sid,
2511 GFP_KERNEL);
2511 if (rc) { 2512 if (rc) {
2512 printk(KERN_WARNING "SELinux: security_context_to_sid" 2513 printk(KERN_WARNING "SELinux: security_context_to_sid"
2513 "(%s) failed for (dev %s, type %s) errno=%d\n", 2514 "(%s) failed for (dev %s, type %s) errno=%d\n",
@@ -2911,7 +2912,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2911 if (rc) 2912 if (rc)
2912 return rc; 2913 return rc;
2913 2914
2914 rc = security_context_to_sid(value, size, &newsid); 2915 rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
2915 if (rc == -EINVAL) { 2916 if (rc == -EINVAL) {
2916 if (!capable(CAP_MAC_ADMIN)) { 2917 if (!capable(CAP_MAC_ADMIN)) {
2917 struct audit_buffer *ab; 2918 struct audit_buffer *ab;
@@ -3068,7 +3069,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
3068 if (!value || !size) 3069 if (!value || !size)
3069 return -EACCES; 3070 return -EACCES;
3070 3071
3071 rc = security_context_to_sid((void *)value, size, &newsid); 3072 rc = security_context_to_sid((void *)value, size, &newsid, GFP_KERNEL);
3072 if (rc) 3073 if (rc)
3073 return rc; 3074 return rc;
3074 3075
@@ -5543,7 +5544,7 @@ static int selinux_setprocattr(struct task_struct *p,
5543 str[size-1] = 0; 5544 str[size-1] = 0;
5544 size--; 5545 size--;
5545 } 5546 }
5546 error = security_context_to_sid(value, size, &sid); 5547 error = security_context_to_sid(value, size, &sid, GFP_KERNEL);
5547 if (error == -EINVAL && !strcmp(name, "fscreate")) { 5548 if (error == -EINVAL && !strcmp(name, "fscreate")) {
5548 if (!capable(CAP_MAC_ADMIN)) { 5549 if (!capable(CAP_MAC_ADMIN)) {
5549 struct audit_buffer *ab; 5550 struct audit_buffer *ab;
@@ -5652,7 +5653,7 @@ static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
5652 5653
5653static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) 5654static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
5654{ 5655{
5655 return security_context_to_sid(secdata, seclen, secid); 5656 return security_context_to_sid(secdata, seclen, secid, GFP_KERNEL);
5656} 5657}
5657 5658
5658static void selinux_release_secctx(char *secdata, u32 seclen) 5659static void selinux_release_secctx(char *secdata, u32 seclen)
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 8ed8daf7f1ee..ce7852cf526b 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -134,7 +134,7 @@ int security_sid_to_context(u32 sid, char **scontext,
134int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len); 134int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len);
135 135
136int security_context_to_sid(const char *scontext, u32 scontext_len, 136int security_context_to_sid(const char *scontext, u32 scontext_len,
137 u32 *out_sid); 137 u32 *out_sid, gfp_t gfp);
138 138
139int security_context_to_sid_default(const char *scontext, u32 scontext_len, 139int security_context_to_sid_default(const char *scontext, u32 scontext_len,
140 u32 *out_sid, u32 def_sid, gfp_t gfp_flags); 140 u32 *out_sid, u32 def_sid, gfp_t gfp_flags);
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 48c3cc94c168..9f0584710c85 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -10,7 +10,8 @@
10#include <net/flow.h> 10#include <net/flow.h>
11 11
12int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, 12int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
13 struct xfrm_user_sec_ctx *uctx); 13 struct xfrm_user_sec_ctx *uctx,
14 gfp_t gfp);
14int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, 15int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
15 struct xfrm_sec_ctx **new_ctxp); 16 struct xfrm_sec_ctx **new_ctxp);
16void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx); 17void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx);
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 332ac8a80cf5..2df7b900e259 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -17,6 +17,7 @@
17#include <linux/inet_diag.h> 17#include <linux/inet_diag.h>
18#include <linux/xfrm.h> 18#include <linux/xfrm.h>
19#include <linux/audit.h> 19#include <linux/audit.h>
20#include <linux/sock_diag.h>
20 21
21#include "flask.h" 22#include "flask.h"
22#include "av_permissions.h" 23#include "av_permissions.h"
@@ -78,6 +79,7 @@ static struct nlmsg_perm nlmsg_tcpdiag_perms[] =
78{ 79{
79 { TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, 80 { TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ },
80 { DCCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, 81 { DCCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ },
82 { SOCK_DIAG_BY_FAMILY, NETLINK_TCPDIAG_SOCKET__NLMSG_READ },
81}; 83};
82 84
83static struct nlmsg_perm nlmsg_xfrm_perms[] = 85static struct nlmsg_perm nlmsg_xfrm_perms[] =
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 5122affe06a8..d60c0ee66387 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -576,7 +576,7 @@ static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
576 if (length) 576 if (length)
577 goto out; 577 goto out;
578 578
579 length = security_context_to_sid(buf, size, &sid); 579 length = security_context_to_sid(buf, size, &sid, GFP_KERNEL);
580 if (length) 580 if (length)
581 goto out; 581 goto out;
582 582
@@ -731,11 +731,13 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
731 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 731 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
732 goto out; 732 goto out;
733 733
734 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 734 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid,
735 GFP_KERNEL);
735 if (length) 736 if (length)
736 goto out; 737 goto out;
737 738
738 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 739 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid,
740 GFP_KERNEL);
739 if (length) 741 if (length)
740 goto out; 742 goto out;
741 743
@@ -817,11 +819,13 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
817 objname = namebuf; 819 objname = namebuf;
818 } 820 }
819 821
820 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 822 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid,
823 GFP_KERNEL);
821 if (length) 824 if (length)
822 goto out; 825 goto out;
823 826
824 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 827 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid,
828 GFP_KERNEL);
825 if (length) 829 if (length)
826 goto out; 830 goto out;
827 831
@@ -878,11 +882,13 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
878 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 882 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
879 goto out; 883 goto out;
880 884
881 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 885 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid,
886 GFP_KERNEL);
882 if (length) 887 if (length)
883 goto out; 888 goto out;
884 889
885 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 890 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid,
891 GFP_KERNEL);
886 if (length) 892 if (length)
887 goto out; 893 goto out;
888 894
@@ -934,7 +940,7 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
934 if (sscanf(buf, "%s %s", con, user) != 2) 940 if (sscanf(buf, "%s %s", con, user) != 2)
935 goto out; 941 goto out;
936 942
937 length = security_context_to_sid(con, strlen(con) + 1, &sid); 943 length = security_context_to_sid(con, strlen(con) + 1, &sid, GFP_KERNEL);
938 if (length) 944 if (length)
939 goto out; 945 goto out;
940 946
@@ -994,11 +1000,13 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
994 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 1000 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
995 goto out; 1001 goto out;
996 1002
997 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 1003 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid,
1004 GFP_KERNEL);
998 if (length) 1005 if (length)
999 goto out; 1006 goto out;
1000 1007
1001 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 1008 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid,
1009 GFP_KERNEL);
1002 if (length) 1010 if (length)
1003 goto out; 1011 goto out;
1004 1012
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index c0f498842129..9c5cdc2caaef 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -3338,10 +3338,10 @@ static int filename_write_helper(void *key, void *data, void *ptr)
3338 if (rc) 3338 if (rc)
3339 return rc; 3339 return rc;
3340 3340
3341 buf[0] = ft->stype; 3341 buf[0] = cpu_to_le32(ft->stype);
3342 buf[1] = ft->ttype; 3342 buf[1] = cpu_to_le32(ft->ttype);
3343 buf[2] = ft->tclass; 3343 buf[2] = cpu_to_le32(ft->tclass);
3344 buf[3] = otype->otype; 3344 buf[3] = cpu_to_le32(otype->otype);
3345 3345
3346 rc = put_entry(buf, sizeof(u32), 4, fp); 3346 rc = put_entry(buf, sizeof(u32), 4, fp);
3347 if (rc) 3347 if (rc)
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index fc5a63a05a1c..4bca49414a40 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1232,6 +1232,10 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
1232 struct context context; 1232 struct context context;
1233 int rc = 0; 1233 int rc = 0;
1234 1234
1235 /* An empty security context is never valid. */
1236 if (!scontext_len)
1237 return -EINVAL;
1238
1235 if (!ss_initialized) { 1239 if (!ss_initialized) {
1236 int i; 1240 int i;
1237 1241
@@ -1285,16 +1289,18 @@ out:
1285 * @scontext: security context 1289 * @scontext: security context
1286 * @scontext_len: length in bytes 1290 * @scontext_len: length in bytes
1287 * @sid: security identifier, SID 1291 * @sid: security identifier, SID
1292 * @gfp: context for the allocation
1288 * 1293 *
1289 * Obtains a SID associated with the security context that 1294 * Obtains a SID associated with the security context that
1290 * has the string representation specified by @scontext. 1295 * has the string representation specified by @scontext.
1291 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient 1296 * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
1292 * memory is available, or 0 on success. 1297 * memory is available, or 0 on success.
1293 */ 1298 */
1294int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid) 1299int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid,
1300 gfp_t gfp)
1295{ 1301{
1296 return security_context_to_sid_core(scontext, scontext_len, 1302 return security_context_to_sid_core(scontext, scontext_len,
1297 sid, SECSID_NULL, GFP_KERNEL, 0); 1303 sid, SECSID_NULL, gfp, 0);
1298} 1304}
1299 1305
1300/** 1306/**
@@ -2948,25 +2954,21 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
2948 struct selinux_audit_rule *rule = vrule; 2954 struct selinux_audit_rule *rule = vrule;
2949 int match = 0; 2955 int match = 0;
2950 2956
2951 if (!rule) { 2957 if (unlikely(!rule)) {
2952 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 2958 WARN_ONCE(1, "selinux_audit_rule_match: missing rule\n");
2953 "selinux_audit_rule_match: missing rule\n");
2954 return -ENOENT; 2959 return -ENOENT;
2955 } 2960 }
2956 2961
2957 read_lock(&policy_rwlock); 2962 read_lock(&policy_rwlock);
2958 2963
2959 if (rule->au_seqno < latest_granting) { 2964 if (rule->au_seqno < latest_granting) {
2960 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2961 "selinux_audit_rule_match: stale rule\n");
2962 match = -ESTALE; 2965 match = -ESTALE;
2963 goto out; 2966 goto out;
2964 } 2967 }
2965 2968
2966 ctxt = sidtab_search(&sidtab, sid); 2969 ctxt = sidtab_search(&sidtab, sid);
2967 if (!ctxt) { 2970 if (unlikely(!ctxt)) {
2968 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 2971 WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n",
2969 "selinux_audit_rule_match: unrecognized SID %d\n",
2970 sid); 2972 sid);
2971 match = -ENOENT; 2973 match = -ENOENT;
2972 goto out; 2974 goto out;
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 0462cb3ff0a7..98b042630a9e 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -78,7 +78,8 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
78 * xfrm_user_sec_ctx context. 78 * xfrm_user_sec_ctx context.
79 */ 79 */
80static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, 80static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
81 struct xfrm_user_sec_ctx *uctx) 81 struct xfrm_user_sec_ctx *uctx,
82 gfp_t gfp)
82{ 83{
83 int rc; 84 int rc;
84 const struct task_security_struct *tsec = current_security(); 85 const struct task_security_struct *tsec = current_security();
@@ -94,7 +95,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
94 if (str_len >= PAGE_SIZE) 95 if (str_len >= PAGE_SIZE)
95 return -ENOMEM; 96 return -ENOMEM;
96 97
97 ctx = kmalloc(sizeof(*ctx) + str_len + 1, GFP_KERNEL); 98 ctx = kmalloc(sizeof(*ctx) + str_len + 1, gfp);
98 if (!ctx) 99 if (!ctx)
99 return -ENOMEM; 100 return -ENOMEM;
100 101
@@ -103,7 +104,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
103 ctx->ctx_len = str_len; 104 ctx->ctx_len = str_len;
104 memcpy(ctx->ctx_str, &uctx[1], str_len); 105 memcpy(ctx->ctx_str, &uctx[1], str_len);
105 ctx->ctx_str[str_len] = '\0'; 106 ctx->ctx_str[str_len] = '\0';
106 rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid); 107 rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid, gfp);
107 if (rc) 108 if (rc)
108 goto err; 109 goto err;
109 110
@@ -282,9 +283,10 @@ int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
282 * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy. 283 * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy.
283 */ 284 */
284int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, 285int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
285 struct xfrm_user_sec_ctx *uctx) 286 struct xfrm_user_sec_ctx *uctx,
287 gfp_t gfp)
286{ 288{
287 return selinux_xfrm_alloc_user(ctxp, uctx); 289 return selinux_xfrm_alloc_user(ctxp, uctx, gfp);
288} 290}
289 291
290/* 292/*
@@ -332,7 +334,7 @@ int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
332int selinux_xfrm_state_alloc(struct xfrm_state *x, 334int selinux_xfrm_state_alloc(struct xfrm_state *x,
333 struct xfrm_user_sec_ctx *uctx) 335 struct xfrm_user_sec_ctx *uctx)
334{ 336{
335 return selinux_xfrm_alloc_user(&x->security, uctx); 337 return selinux_xfrm_alloc_user(&x->security, uctx, GFP_KERNEL);
336} 338}
337 339
338/* 340/*
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 364cc64fce71..d072fd32212d 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -241,7 +241,8 @@ u32 smack_to_secid(const char *);
241extern int smack_cipso_direct; 241extern int smack_cipso_direct;
242extern int smack_cipso_mapped; 242extern int smack_cipso_mapped;
243extern struct smack_known *smack_net_ambient; 243extern struct smack_known *smack_net_ambient;
244extern char *smack_onlycap; 244extern struct smack_known *smack_onlycap;
245extern struct smack_known *smack_syslog_label;
245extern const char *smack_cipso_option; 246extern const char *smack_cipso_option;
246 247
247extern struct smack_known smack_known_floor; 248extern struct smack_known smack_known_floor;
@@ -312,7 +313,7 @@ static inline int smack_privileged(int cap)
312 313
313 if (!capable(cap)) 314 if (!capable(cap))
314 return 0; 315 return 0;
315 if (smack_onlycap == NULL || smack_onlycap == skp->smk_known) 316 if (smack_onlycap == NULL || smack_onlycap == skp)
316 return 1; 317 return 1;
317 return 0; 318 return 0;
318} 319}
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index b0be893ad44d..14f52be78c75 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -219,8 +219,6 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
219 * smack_syslog - Smack approval on syslog 219 * smack_syslog - Smack approval on syslog
220 * @type: message type 220 * @type: message type
221 * 221 *
222 * Require that the task has the floor label
223 *
224 * Returns 0 on success, error code otherwise. 222 * Returns 0 on success, error code otherwise.
225 */ 223 */
226static int smack_syslog(int typefrom_file) 224static int smack_syslog(int typefrom_file)
@@ -231,7 +229,7 @@ static int smack_syslog(int typefrom_file)
231 if (smack_privileged(CAP_MAC_OVERRIDE)) 229 if (smack_privileged(CAP_MAC_OVERRIDE))
232 return 0; 230 return 0;
233 231
234 if (skp != &smack_known_floor) 232 if (smack_syslog_label != NULL && smack_syslog_label != skp)
235 rc = -EACCES; 233 rc = -EACCES;
236 234
237 return rc; 235 return rc;
@@ -341,10 +339,12 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
341 struct inode *inode = root->d_inode; 339 struct inode *inode = root->d_inode;
342 struct superblock_smack *sp = sb->s_security; 340 struct superblock_smack *sp = sb->s_security;
343 struct inode_smack *isp; 341 struct inode_smack *isp;
342 struct smack_known *skp;
344 char *op; 343 char *op;
345 char *commap; 344 char *commap;
346 char *nsp; 345 char *nsp;
347 int transmute = 0; 346 int transmute = 0;
347 int specified = 0;
348 348
349 if (sp->smk_initialized) 349 if (sp->smk_initialized)
350 return 0; 350 return 0;
@@ -359,34 +359,56 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
359 if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) { 359 if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) {
360 op += strlen(SMK_FSHAT); 360 op += strlen(SMK_FSHAT);
361 nsp = smk_import(op, 0); 361 nsp = smk_import(op, 0);
362 if (nsp != NULL) 362 if (nsp != NULL) {
363 sp->smk_hat = nsp; 363 sp->smk_hat = nsp;
364 specified = 1;
365 }
364 } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { 366 } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) {
365 op += strlen(SMK_FSFLOOR); 367 op += strlen(SMK_FSFLOOR);
366 nsp = smk_import(op, 0); 368 nsp = smk_import(op, 0);
367 if (nsp != NULL) 369 if (nsp != NULL) {
368 sp->smk_floor = nsp; 370 sp->smk_floor = nsp;
371 specified = 1;
372 }
369 } else if (strncmp(op, SMK_FSDEFAULT, 373 } else if (strncmp(op, SMK_FSDEFAULT,
370 strlen(SMK_FSDEFAULT)) == 0) { 374 strlen(SMK_FSDEFAULT)) == 0) {
371 op += strlen(SMK_FSDEFAULT); 375 op += strlen(SMK_FSDEFAULT);
372 nsp = smk_import(op, 0); 376 nsp = smk_import(op, 0);
373 if (nsp != NULL) 377 if (nsp != NULL) {
374 sp->smk_default = nsp; 378 sp->smk_default = nsp;
379 specified = 1;
380 }
375 } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { 381 } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) {
376 op += strlen(SMK_FSROOT); 382 op += strlen(SMK_FSROOT);
377 nsp = smk_import(op, 0); 383 nsp = smk_import(op, 0);
378 if (nsp != NULL) 384 if (nsp != NULL) {
379 sp->smk_root = nsp; 385 sp->smk_root = nsp;
386 specified = 1;
387 }
380 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { 388 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) {
381 op += strlen(SMK_FSTRANS); 389 op += strlen(SMK_FSTRANS);
382 nsp = smk_import(op, 0); 390 nsp = smk_import(op, 0);
383 if (nsp != NULL) { 391 if (nsp != NULL) {
384 sp->smk_root = nsp; 392 sp->smk_root = nsp;
385 transmute = 1; 393 transmute = 1;
394 specified = 1;
386 } 395 }
387 } 396 }
388 } 397 }
389 398
399 if (!smack_privileged(CAP_MAC_ADMIN)) {
400 /*
401 * Unprivileged mounts don't get to specify Smack values.
402 */
403 if (specified)
404 return -EPERM;
405 /*
406 * Unprivileged mounts get root and default from the caller.
407 */
408 skp = smk_of_current();
409 sp->smk_root = skp->smk_known;
410 sp->smk_default = skp->smk_known;
411 }
390 /* 412 /*
391 * Initialize the root inode. 413 * Initialize the root inode.
392 */ 414 */
@@ -423,53 +445,6 @@ static int smack_sb_statfs(struct dentry *dentry)
423 return rc; 445 return rc;
424} 446}
425 447
426/**
427 * smack_sb_mount - Smack check for mounting
428 * @dev_name: unused
429 * @path: mount point
430 * @type: unused
431 * @flags: unused
432 * @data: unused
433 *
434 * Returns 0 if current can write the floor of the filesystem
435 * being mounted on, an error code otherwise.
436 */
437static int smack_sb_mount(const char *dev_name, struct path *path,
438 const char *type, unsigned long flags, void *data)
439{
440 struct superblock_smack *sbp = path->dentry->d_sb->s_security;
441 struct smk_audit_info ad;
442
443 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
444 smk_ad_setfield_u_fs_path(&ad, *path);
445
446 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
447}
448
449/**
450 * smack_sb_umount - Smack check for unmounting
451 * @mnt: file system to unmount
452 * @flags: unused
453 *
454 * Returns 0 if current can write the floor of the filesystem
455 * being unmounted, an error code otherwise.
456 */
457static int smack_sb_umount(struct vfsmount *mnt, int flags)
458{
459 struct superblock_smack *sbp;
460 struct smk_audit_info ad;
461 struct path path;
462
463 path.dentry = mnt->mnt_root;
464 path.mnt = mnt;
465
466 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
467 smk_ad_setfield_u_fs_path(&ad, path);
468
469 sbp = path.dentry->d_sb->s_security;
470 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
471}
472
473/* 448/*
474 * BPRM hooks 449 * BPRM hooks
475 */ 450 */
@@ -837,31 +812,43 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
837 const void *value, size_t size, int flags) 812 const void *value, size_t size, int flags)
838{ 813{
839 struct smk_audit_info ad; 814 struct smk_audit_info ad;
815 struct smack_known *skp;
816 int check_priv = 0;
817 int check_import = 0;
818 int check_star = 0;
840 int rc = 0; 819 int rc = 0;
841 820
821 /*
822 * Check label validity here so import won't fail in post_setxattr
823 */
842 if (strcmp(name, XATTR_NAME_SMACK) == 0 || 824 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
843 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || 825 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
844 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || 826 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
845 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || 827 check_priv = 1;
846 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { 828 check_import = 1;
847 if (!smack_privileged(CAP_MAC_ADMIN)) 829 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
848 rc = -EPERM; 830 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
849 /* 831 check_priv = 1;
850 * check label validity here so import wont fail on 832 check_import = 1;
851 * post_setxattr 833 check_star = 1;
852 */
853 if (size == 0 || size >= SMK_LONGLABEL ||
854 smk_import(value, size) == NULL)
855 rc = -EINVAL;
856 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { 834 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
857 if (!smack_privileged(CAP_MAC_ADMIN)) 835 check_priv = 1;
858 rc = -EPERM;
859 if (size != TRANS_TRUE_SIZE || 836 if (size != TRANS_TRUE_SIZE ||
860 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) 837 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
861 rc = -EINVAL; 838 rc = -EINVAL;
862 } else 839 } else
863 rc = cap_inode_setxattr(dentry, name, value, size, flags); 840 rc = cap_inode_setxattr(dentry, name, value, size, flags);
864 841
842 if (check_priv && !smack_privileged(CAP_MAC_ADMIN))
843 rc = -EPERM;
844
845 if (rc == 0 && check_import) {
846 skp = smk_import_entry(value, size);
847 if (skp == NULL || (check_star &&
848 (skp == &smack_known_star || skp == &smack_known_web)))
849 rc = -EINVAL;
850 }
851
865 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); 852 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
866 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 853 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
867 854
@@ -1364,7 +1351,7 @@ static int smack_file_receive(struct file *file)
1364 int may = 0; 1351 int may = 0;
1365 struct smk_audit_info ad; 1352 struct smk_audit_info ad;
1366 1353
1367 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1354 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1368 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1355 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1369 /* 1356 /*
1370 * This code relies on bitmasks. 1357 * This code relies on bitmasks.
@@ -2847,8 +2834,17 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2847 if (rc >= 0) 2834 if (rc >= 0)
2848 transflag = SMK_INODE_TRANSMUTE; 2835 transflag = SMK_INODE_TRANSMUTE;
2849 } 2836 }
2850 isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); 2837 /*
2851 isp->smk_mmap = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); 2838 * Don't let the exec or mmap label be "*" or "@".
2839 */
2840 skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
2841 if (skp == &smack_known_star || skp == &smack_known_web)
2842 skp = NULL;
2843 isp->smk_task = skp;
2844 skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
2845 if (skp == &smack_known_star || skp == &smack_known_web)
2846 skp = NULL;
2847 isp->smk_mmap = skp;
2852 2848
2853 dput(dp); 2849 dput(dp);
2854 break; 2850 break;
@@ -3620,9 +3616,8 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3620 struct smack_known *skp; 3616 struct smack_known *skp;
3621 char *rule = vrule; 3617 char *rule = vrule;
3622 3618
3623 if (!rule) { 3619 if (unlikely(!rule)) {
3624 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 3620 WARN_ONCE(1, "Smack: missing rule\n");
3625 "Smack: missing rule\n");
3626 return -ENOENT; 3621 return -ENOENT;
3627 } 3622 }
3628 3623
@@ -3743,8 +3738,6 @@ struct security_operations smack_ops = {
3743 .sb_copy_data = smack_sb_copy_data, 3738 .sb_copy_data = smack_sb_copy_data,
3744 .sb_kern_mount = smack_sb_kern_mount, 3739 .sb_kern_mount = smack_sb_kern_mount,
3745 .sb_statfs = smack_sb_statfs, 3740 .sb_statfs = smack_sb_statfs,
3746 .sb_mount = smack_sb_mount,
3747 .sb_umount = smack_sb_umount,
3748 3741
3749 .bprm_set_creds = smack_bprm_set_creds, 3742 .bprm_set_creds = smack_bprm_set_creds,
3750 .bprm_committing_creds = smack_bprm_committing_creds, 3743 .bprm_committing_creds = smack_bprm_committing_creds,
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 160aa08e3cd5..3198cfe1dcc6 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -52,6 +52,7 @@ enum smk_inos {
52 SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */ 52 SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */
53 SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */ 53 SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */
54 SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */ 54 SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */
55 SMK_SYSLOG = 20, /* change syslog label) */
55}; 56};
56 57
57/* 58/*
@@ -59,6 +60,7 @@ enum smk_inos {
59 */ 60 */
60static DEFINE_MUTEX(smack_cipso_lock); 61static DEFINE_MUTEX(smack_cipso_lock);
61static DEFINE_MUTEX(smack_ambient_lock); 62static DEFINE_MUTEX(smack_ambient_lock);
63static DEFINE_MUTEX(smack_syslog_lock);
62static DEFINE_MUTEX(smk_netlbladdr_lock); 64static DEFINE_MUTEX(smk_netlbladdr_lock);
63 65
64/* 66/*
@@ -90,7 +92,13 @@ int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
90 * everyone. It is expected that the hat (^) label 92 * everyone. It is expected that the hat (^) label
91 * will be used if any label is used. 93 * will be used if any label is used.
92 */ 94 */
93char *smack_onlycap; 95struct smack_known *smack_onlycap;
96
97/*
98 * If this value is set restrict syslog use to the label specified.
99 * It can be reset via smackfs/syslog
100 */
101struct smack_known *smack_syslog_label;
94 102
95/* 103/*
96 * Certain IP addresses may be designated as single label hosts. 104 * Certain IP addresses may be designated as single label hosts.
@@ -301,7 +309,8 @@ static int smk_perm_from_str(const char *string)
301 * @import: if non-zero, import labels 309 * @import: if non-zero, import labels
302 * @len: label length limit 310 * @len: label length limit
303 * 311 *
304 * Returns 0 on success, -1 on failure 312 * Returns 0 on success, -EINVAL on failure and -ENOENT when either subject
313 * or object is missing.
305 */ 314 */
306static int smk_fill_rule(const char *subject, const char *object, 315static int smk_fill_rule(const char *subject, const char *object,
307 const char *access1, const char *access2, 316 const char *access1, const char *access2,
@@ -314,28 +323,28 @@ static int smk_fill_rule(const char *subject, const char *object,
314 if (import) { 323 if (import) {
315 rule->smk_subject = smk_import_entry(subject, len); 324 rule->smk_subject = smk_import_entry(subject, len);
316 if (rule->smk_subject == NULL) 325 if (rule->smk_subject == NULL)
317 return -1; 326 return -EINVAL;
318 327
319 rule->smk_object = smk_import(object, len); 328 rule->smk_object = smk_import(object, len);
320 if (rule->smk_object == NULL) 329 if (rule->smk_object == NULL)
321 return -1; 330 return -EINVAL;
322 } else { 331 } else {
323 cp = smk_parse_smack(subject, len); 332 cp = smk_parse_smack(subject, len);
324 if (cp == NULL) 333 if (cp == NULL)
325 return -1; 334 return -EINVAL;
326 skp = smk_find_entry(cp); 335 skp = smk_find_entry(cp);
327 kfree(cp); 336 kfree(cp);
328 if (skp == NULL) 337 if (skp == NULL)
329 return -1; 338 return -ENOENT;
330 rule->smk_subject = skp; 339 rule->smk_subject = skp;
331 340
332 cp = smk_parse_smack(object, len); 341 cp = smk_parse_smack(object, len);
333 if (cp == NULL) 342 if (cp == NULL)
334 return -1; 343 return -EINVAL;
335 skp = smk_find_entry(cp); 344 skp = smk_find_entry(cp);
336 kfree(cp); 345 kfree(cp);
337 if (skp == NULL) 346 if (skp == NULL)
338 return -1; 347 return -ENOENT;
339 rule->smk_object = skp->smk_known; 348 rule->smk_object = skp->smk_known;
340 } 349 }
341 350
@@ -381,6 +390,7 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule,
381{ 390{
382 ssize_t cnt = 0; 391 ssize_t cnt = 0;
383 char *tok[4]; 392 char *tok[4];
393 int rc;
384 int i; 394 int i;
385 395
386 /* 396 /*
@@ -405,10 +415,8 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule,
405 while (i < 4) 415 while (i < 4)
406 tok[i++] = NULL; 416 tok[i++] = NULL;
407 417
408 if (smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0)) 418 rc = smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0);
409 return -1; 419 return rc == 0 ? cnt : rc;
410
411 return cnt;
412} 420}
413 421
414#define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */ 422#define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */
@@ -1603,7 +1611,7 @@ static const struct file_operations smk_ambient_ops = {
1603}; 1611};
1604 1612
1605/** 1613/**
1606 * smk_read_onlycap - read() for /smack/onlycap 1614 * smk_read_onlycap - read() for smackfs/onlycap
1607 * @filp: file pointer, not actually used 1615 * @filp: file pointer, not actually used
1608 * @buf: where to put the result 1616 * @buf: where to put the result
1609 * @cn: maximum to send along 1617 * @cn: maximum to send along
@@ -1622,7 +1630,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
1622 return 0; 1630 return 0;
1623 1631
1624 if (smack_onlycap != NULL) 1632 if (smack_onlycap != NULL)
1625 smack = smack_onlycap; 1633 smack = smack_onlycap->smk_known;
1626 1634
1627 asize = strlen(smack) + 1; 1635 asize = strlen(smack) + 1;
1628 1636
@@ -1633,7 +1641,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
1633} 1641}
1634 1642
1635/** 1643/**
1636 * smk_write_onlycap - write() for /smack/onlycap 1644 * smk_write_onlycap - write() for smackfs/onlycap
1637 * @file: file pointer, not actually used 1645 * @file: file pointer, not actually used
1638 * @buf: where to get the data from 1646 * @buf: where to get the data from
1639 * @count: bytes sent 1647 * @count: bytes sent
@@ -1656,7 +1664,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1656 * explicitly for clarity. The smk_access() implementation 1664 * explicitly for clarity. The smk_access() implementation
1657 * would use smk_access(smack_onlycap, MAY_WRITE) 1665 * would use smk_access(smack_onlycap, MAY_WRITE)
1658 */ 1666 */
1659 if (smack_onlycap != NULL && smack_onlycap != skp->smk_known) 1667 if (smack_onlycap != NULL && smack_onlycap != skp)
1660 return -EPERM; 1668 return -EPERM;
1661 1669
1662 data = kzalloc(count, GFP_KERNEL); 1670 data = kzalloc(count, GFP_KERNEL);
@@ -1676,7 +1684,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1676 if (copy_from_user(data, buf, count) != 0) 1684 if (copy_from_user(data, buf, count) != 0)
1677 rc = -EFAULT; 1685 rc = -EFAULT;
1678 else 1686 else
1679 smack_onlycap = smk_import(data, count); 1687 smack_onlycap = smk_import_entry(data, count);
1680 1688
1681 kfree(data); 1689 kfree(data);
1682 return rc; 1690 return rc;
@@ -1856,11 +1864,12 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
1856 res = smk_parse_long_rule(data, &rule, 0, 3); 1864 res = smk_parse_long_rule(data, &rule, 0, 3);
1857 } 1865 }
1858 1866
1859 if (res < 0) 1867 if (res >= 0)
1868 res = smk_access(rule.smk_subject, rule.smk_object,
1869 rule.smk_access1, NULL);
1870 else if (res != -ENOENT)
1860 return -EINVAL; 1871 return -EINVAL;
1861 1872
1862 res = smk_access(rule.smk_subject, rule.smk_object,
1863 rule.smk_access1, NULL);
1864 data[0] = res == 0 ? '1' : '0'; 1873 data[0] = res == 0 ? '1' : '0';
1865 data[1] = '\0'; 1874 data[1] = '\0';
1866 1875
@@ -2143,7 +2152,7 @@ static ssize_t smk_write_change_rule(struct file *file, const char __user *buf,
2143 /* 2152 /*
2144 * Must have privilege. 2153 * Must have privilege.
2145 */ 2154 */
2146 if (!capable(CAP_MAC_ADMIN)) 2155 if (!smack_privileged(CAP_MAC_ADMIN))
2147 return -EPERM; 2156 return -EPERM;
2148 2157
2149 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, 2158 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
@@ -2158,12 +2167,89 @@ static const struct file_operations smk_change_rule_ops = {
2158}; 2167};
2159 2168
2160/** 2169/**
2161 * smk_fill_super - fill the /smackfs superblock 2170 * smk_read_syslog - read() for smackfs/syslog
2171 * @filp: file pointer, not actually used
2172 * @buf: where to put the result
2173 * @cn: maximum to send along
2174 * @ppos: where to start
2175 *
2176 * Returns number of bytes read or error code, as appropriate
2177 */
2178static ssize_t smk_read_syslog(struct file *filp, char __user *buf,
2179 size_t cn, loff_t *ppos)
2180{
2181 struct smack_known *skp;
2182 ssize_t rc = -EINVAL;
2183 int asize;
2184
2185 if (*ppos != 0)
2186 return 0;
2187
2188 if (smack_syslog_label == NULL)
2189 skp = &smack_known_star;
2190 else
2191 skp = smack_syslog_label;
2192
2193 asize = strlen(skp->smk_known) + 1;
2194
2195 if (cn >= asize)
2196 rc = simple_read_from_buffer(buf, cn, ppos, skp->smk_known,
2197 asize);
2198
2199 return rc;
2200}
2201
2202/**
2203 * smk_write_syslog - write() for smackfs/syslog
2204 * @file: file pointer, not actually used
2205 * @buf: where to get the data from
2206 * @count: bytes sent
2207 * @ppos: where to start
2208 *
2209 * Returns number of bytes written or error code, as appropriate
2210 */
2211static ssize_t smk_write_syslog(struct file *file, const char __user *buf,
2212 size_t count, loff_t *ppos)
2213{
2214 char *data;
2215 struct smack_known *skp;
2216 int rc = count;
2217
2218 if (!smack_privileged(CAP_MAC_ADMIN))
2219 return -EPERM;
2220
2221 data = kzalloc(count, GFP_KERNEL);
2222 if (data == NULL)
2223 return -ENOMEM;
2224
2225 if (copy_from_user(data, buf, count) != 0)
2226 rc = -EFAULT;
2227 else {
2228 skp = smk_import_entry(data, count);
2229 if (skp == NULL)
2230 rc = -EINVAL;
2231 else
2232 smack_syslog_label = smk_import_entry(data, count);
2233 }
2234
2235 kfree(data);
2236 return rc;
2237}
2238
2239static const struct file_operations smk_syslog_ops = {
2240 .read = smk_read_syslog,
2241 .write = smk_write_syslog,
2242 .llseek = default_llseek,
2243};
2244
2245
2246/**
2247 * smk_fill_super - fill the smackfs superblock
2162 * @sb: the empty superblock 2248 * @sb: the empty superblock
2163 * @data: unused 2249 * @data: unused
2164 * @silent: unused 2250 * @silent: unused
2165 * 2251 *
2166 * Fill in the well known entries for /smack 2252 * Fill in the well known entries for the smack filesystem
2167 * 2253 *
2168 * Returns 0 on success, an error code on failure 2254 * Returns 0 on success, an error code on failure
2169 */ 2255 */
@@ -2208,6 +2294,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
2208 S_IRUGO|S_IWUSR}, 2294 S_IRUGO|S_IWUSR},
2209 [SMK_CHANGE_RULE] = { 2295 [SMK_CHANGE_RULE] = {
2210 "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR}, 2296 "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR},
2297 [SMK_SYSLOG] = {
2298 "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
2211 /* last one */ 2299 /* last one */
2212 {""} 2300 {""}
2213 }; 2301 };