aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2012-07-25 08:33:45 -0400
committerArnd Bergmann <arnd@arndb.de>2012-07-25 08:35:04 -0400
commit8cef081c71dd4e16a01a1e63cedab21eef8b5735 (patch)
treeb5b0fb5ab09dc60dee5fc8fd8e980359abbd1b1e /security
parent3d55c29fb24286f350f04021bef2dd799e25dd20 (diff)
parent9161c3b796a2841a9a7be3d9c9dd121269ce90e8 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux into fixes
The merge of the 'clk-for-linus' branch caused an automated merge failure. Pull that in here so we can fix the problem. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'security')
-rw-r--r--security/integrity/ima/Kconfig3
-rw-r--r--security/integrity/ima/Makefile3
-rw-r--r--security/integrity/ima/ima.h9
-rw-r--r--security/integrity/ima/ima_api.c4
-rw-r--r--security/integrity/ima/ima_audit.c3
-rw-r--r--security/integrity/ima/ima_fs.c11
-rw-r--r--security/integrity/ima/ima_init.c5
-rw-r--r--security/integrity/ima/ima_main.c50
-rw-r--r--security/integrity/ima/ima_policy.c2
-rw-r--r--security/keys/compat.c4
-rw-r--r--security/keys/internal.h2
-rw-r--r--security/keys/keyctl.c2
-rw-r--r--security/keys/keyring.c2
-rw-r--r--security/selinux/hooks.c10
-rw-r--r--security/selinux/netlink.c17
-rw-r--r--security/smack/smack.h14
-rw-r--r--security/smack/smack_access.c9
-rw-r--r--security/smack/smack_lsm.c25
-rw-r--r--security/smack/smackfs.c53
19 files changed, 131 insertions, 97 deletions
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 35664fe6daa1..b9c1219924f1 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -38,8 +38,9 @@ config IMA_MEASURE_PCR_IDX
38 measurement list. If unsure, use the default 10. 38 measurement list. If unsure, use the default 10.
39 39
40config IMA_AUDIT 40config IMA_AUDIT
41 bool 41 bool "Enables auditing support"
42 depends on IMA 42 depends on IMA
43 depends on AUDIT
43 default y 44 default y
44 help 45 help
45 This option adds a kernel parameter 'ima_audit', which 46 This option adds a kernel parameter 'ima_audit', which
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 5690c021de8f..5f740f6971e1 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -6,4 +6,5 @@
6obj-$(CONFIG_IMA) += ima.o 6obj-$(CONFIG_IMA) += ima.o
7 7
8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ 8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
9 ima_policy.o ima_audit.o 9 ima_policy.o
10ima-$(CONFIG_IMA_AUDIT) += ima_audit.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 3ccf7acac6df..e7c99fd0d223 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -61,10 +61,19 @@ struct ima_queue_entry {
61}; 61};
62extern struct list_head ima_measurements; /* list of all measurements */ 62extern struct list_head ima_measurements; /* list of all measurements */
63 63
64#ifdef CONFIG_IMA_AUDIT
64/* declarations */ 65/* declarations */
65void integrity_audit_msg(int audit_msgno, struct inode *inode, 66void integrity_audit_msg(int audit_msgno, struct inode *inode,
66 const unsigned char *fname, const char *op, 67 const unsigned char *fname, const char *op,
67 const char *cause, int result, int info); 68 const char *cause, int result, int info);
69#else
70static inline void integrity_audit_msg(int audit_msgno, struct inode *inode,
71 const unsigned char *fname,
72 const char *op, const char *cause,
73 int result, int info)
74{
75}
76#endif
68 77
69/* Internal IMA function definitions */ 78/* Internal IMA function definitions */
70int ima_init(void); 79int ima_init(void);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 88a2788b981d..032ff03ad907 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -175,7 +175,9 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
175 } 175 }
176 memset(&entry->template, 0, sizeof(entry->template)); 176 memset(&entry->template, 0, sizeof(entry->template));
177 memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE); 177 memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE);
178 strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX); 178 strcpy(entry->template.file_name,
179 (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ?
180 file->f_dentry->d_name.name : filename);
179 181
180 result = ima_store_template(entry, violation, inode); 182 result = ima_store_template(entry, violation, inode);
181 if (!result || result == -EEXIST) 183 if (!result || result == -EEXIST)
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c
index 21e96bf188df..7a57f6769e9c 100644
--- a/security/integrity/ima/ima_audit.c
+++ b/security/integrity/ima/ima_audit.c
@@ -17,8 +17,6 @@
17 17
18static int ima_audit; 18static int ima_audit;
19 19
20#ifdef CONFIG_IMA_AUDIT
21
22/* ima_audit_setup - enable informational auditing messages */ 20/* ima_audit_setup - enable informational auditing messages */
23static int __init ima_audit_setup(char *str) 21static int __init ima_audit_setup(char *str)
24{ 22{
@@ -29,7 +27,6 @@ static int __init ima_audit_setup(char *str)
29 return 1; 27 return 1;
30} 28}
31__setup("ima_audit=", ima_audit_setup); 29__setup("ima_audit=", ima_audit_setup);
32#endif
33 30
34void integrity_audit_msg(int audit_msgno, struct inode *inode, 31void integrity_audit_msg(int audit_msgno, struct inode *inode,
35 const unsigned char *fname, const char *op, 32 const unsigned char *fname, const char *op,
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index e1aa2b482dd2..38477c9c3415 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -367,20 +367,11 @@ int __init ima_fs_init(void)
367 367
368 return 0; 368 return 0;
369out: 369out:
370 securityfs_remove(runtime_measurements_count);
371 securityfs_remove(ascii_runtime_measurements);
372 securityfs_remove(binary_runtime_measurements);
373 securityfs_remove(ima_dir);
374 securityfs_remove(ima_policy);
375 return -1;
376}
377
378void __exit ima_fs_cleanup(void)
379{
380 securityfs_remove(violations); 370 securityfs_remove(violations);
381 securityfs_remove(runtime_measurements_count); 371 securityfs_remove(runtime_measurements_count);
382 securityfs_remove(ascii_runtime_measurements); 372 securityfs_remove(ascii_runtime_measurements);
383 securityfs_remove(binary_runtime_measurements); 373 securityfs_remove(binary_runtime_measurements);
384 securityfs_remove(ima_dir); 374 securityfs_remove(ima_dir);
385 securityfs_remove(ima_policy); 375 securityfs_remove(ima_policy);
376 return -1;
386} 377}
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 17f1f060306f..b5dfd534f13d 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -90,8 +90,3 @@ int __init ima_init(void)
90 90
91 return ima_fs_init(); 91 return ima_fs_init();
92} 92}
93
94void __exit ima_cleanup(void)
95{
96 ima_fs_cleanup();
97}
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index b17be79b9cf2..be8294915cf7 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -54,6 +54,7 @@ static void ima_rdwr_violation_check(struct file *file)
54 fmode_t mode = file->f_mode; 54 fmode_t mode = file->f_mode;
55 int rc; 55 int rc;
56 bool send_tomtou = false, send_writers = false; 56 bool send_tomtou = false, send_writers = false;
57 unsigned char *pathname = NULL, *pathbuf = NULL;
57 58
58 if (!S_ISREG(inode->i_mode) || !ima_initialized) 59 if (!S_ISREG(inode->i_mode) || !ima_initialized)
59 return; 60 return;
@@ -75,12 +76,27 @@ static void ima_rdwr_violation_check(struct file *file)
75out: 76out:
76 mutex_unlock(&inode->i_mutex); 77 mutex_unlock(&inode->i_mutex);
77 78
79 if (!send_tomtou && !send_writers)
80 return;
81
82 /* We will allow 11 spaces for ' (deleted)' to be appended */
83 pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL);
84 if (pathbuf) {
85 pathname = d_path(&file->f_path, pathbuf, PATH_MAX + 11);
86 if (IS_ERR(pathname))
87 pathname = NULL;
88 else if (strlen(pathname) > IMA_EVENT_NAME_LEN_MAX)
89 pathname = NULL;
90 }
78 if (send_tomtou) 91 if (send_tomtou)
79 ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", 92 ima_add_violation(inode,
80 "ToMToU"); 93 !pathname ? dentry->d_name.name : pathname,
94 "invalid_pcr", "ToMToU");
81 if (send_writers) 95 if (send_writers)
82 ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", 96 ima_add_violation(inode,
83 "open_writers"); 97 !pathname ? dentry->d_name.name : pathname,
98 "invalid_pcr", "open_writers");
99 kfree(pathbuf);
84} 100}
85 101
86static void ima_check_last_writer(struct integrity_iint_cache *iint, 102static void ima_check_last_writer(struct integrity_iint_cache *iint,
@@ -123,6 +139,7 @@ static int process_measurement(struct file *file, const unsigned char *filename,
123{ 139{
124 struct inode *inode = file->f_dentry->d_inode; 140 struct inode *inode = file->f_dentry->d_inode;
125 struct integrity_iint_cache *iint; 141 struct integrity_iint_cache *iint;
142 unsigned char *pathname = NULL, *pathbuf = NULL;
126 int rc = 0; 143 int rc = 0;
127 144
128 if (!ima_initialized || !S_ISREG(inode->i_mode)) 145 if (!ima_initialized || !S_ISREG(inode->i_mode))
@@ -147,8 +164,21 @@ retry:
147 goto out; 164 goto out;
148 165
149 rc = ima_collect_measurement(iint, file); 166 rc = ima_collect_measurement(iint, file);
150 if (!rc) 167 if (rc != 0)
151 ima_store_measurement(iint, file, filename); 168 goto out;
169
170 if (function != BPRM_CHECK) {
171 /* We will allow 11 spaces for ' (deleted)' to be appended */
172 pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL);
173 if (pathbuf) {
174 pathname =
175 d_path(&file->f_path, pathbuf, PATH_MAX + 11);
176 if (IS_ERR(pathname))
177 pathname = NULL;
178 }
179 }
180 ima_store_measurement(iint, file, !pathname ? filename : pathname);
181 kfree(pathbuf);
152out: 182out:
153 mutex_unlock(&iint->mutex); 183 mutex_unlock(&iint->mutex);
154 return rc; 184 return rc;
@@ -228,15 +258,11 @@ static int __init init_ima(void)
228 int error; 258 int error;
229 259
230 error = ima_init(); 260 error = ima_init();
231 ima_initialized = 1; 261 if (!error)
262 ima_initialized = 1;
232 return error; 263 return error;
233} 264}
234 265
235static void __exit cleanup_ima(void)
236{
237 ima_cleanup();
238}
239
240late_initcall(init_ima); /* Start IMA after the TPM is available */ 266late_initcall(init_ima); /* Start IMA after the TPM is available */
241 267
242MODULE_DESCRIPTION("Integrity Measurement Architecture"); 268MODULE_DESCRIPTION("Integrity Measurement Architecture");
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index d8edff209bf3..1a9583008aae 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -63,6 +63,8 @@ static struct ima_measure_rule_entry default_rules[] = {
63 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, 63 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
64 {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, 64 {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
65 {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC}, 65 {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
66 {.action = DONT_MEASURE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC},
67 {.action = DONT_MEASURE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC},
66 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, 68 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
67 {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC}, 69 {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
68 {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, 70 {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC,
diff --git a/security/keys/compat.c b/security/keys/compat.c
index c92d42b021aa..1c261763f479 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -24,7 +24,7 @@
24 * 24 *
25 * If successful, 0 will be returned. 25 * If successful, 0 will be returned.
26 */ 26 */
27long compat_keyctl_instantiate_key_iov( 27static long compat_keyctl_instantiate_key_iov(
28 key_serial_t id, 28 key_serial_t id,
29 const struct compat_iovec __user *_payload_iov, 29 const struct compat_iovec __user *_payload_iov,
30 unsigned ioc, 30 unsigned ioc,
@@ -33,7 +33,7 @@ long compat_keyctl_instantiate_key_iov(
33 struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; 33 struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
34 long ret; 34 long ret;
35 35
36 if (_payload_iov == 0 || ioc == 0) 36 if (!_payload_iov || !ioc)
37 goto no_payload; 37 goto no_payload;
38 38
39 ret = compat_rw_copy_check_uvector(WRITE, _payload_iov, ioc, 39 ret = compat_rw_copy_check_uvector(WRITE, _payload_iov, ioc,
diff --git a/security/keys/internal.h b/security/keys/internal.h
index c246ba5d43ab..22ff05269e3d 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -242,7 +242,7 @@ extern long keyctl_instantiate_key_iov(key_serial_t,
242extern long keyctl_invalidate_key(key_serial_t); 242extern long keyctl_invalidate_key(key_serial_t);
243 243
244extern long keyctl_instantiate_key_common(key_serial_t, 244extern long keyctl_instantiate_key_common(key_serial_t,
245 const struct iovec __user *, 245 const struct iovec *,
246 unsigned, size_t, key_serial_t); 246 unsigned, size_t, key_serial_t);
247 247
248/* 248/*
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index f1b59ae39d7e..3364fbf46807 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1106,7 +1106,7 @@ long keyctl_instantiate_key_iov(key_serial_t id,
1106 struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; 1106 struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
1107 long ret; 1107 long ret;
1108 1108
1109 if (_payload_iov == 0 || ioc == 0) 1109 if (!_payload_iov || !ioc)
1110 goto no_payload; 1110 goto no_payload;
1111 1111
1112 ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc, 1112 ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc,
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 7445875f6818..81e7852d281d 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -751,6 +751,7 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
751int __key_link_begin(struct key *keyring, const struct key_type *type, 751int __key_link_begin(struct key *keyring, const struct key_type *type,
752 const char *description, unsigned long *_prealloc) 752 const char *description, unsigned long *_prealloc)
753 __acquires(&keyring->sem) 753 __acquires(&keyring->sem)
754 __acquires(&keyring_serialise_link_sem)
754{ 755{
755 struct keyring_list *klist, *nklist; 756 struct keyring_list *klist, *nklist;
756 unsigned long prealloc; 757 unsigned long prealloc;
@@ -960,6 +961,7 @@ void __key_link(struct key *keyring, struct key *key,
960void __key_link_end(struct key *keyring, struct key_type *type, 961void __key_link_end(struct key *keyring, struct key_type *type,
961 unsigned long prealloc) 962 unsigned long prealloc)
962 __releases(&keyring->sem) 963 __releases(&keyring->sem)
964 __releases(&keyring_serialise_link_sem)
963{ 965{
964 BUG_ON(type == NULL); 966 BUG_ON(type == NULL);
965 BUG_ON(type->name == NULL); 967 BUG_ON(type->name == NULL);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9292a8971e66..689fe2d22165 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5762,21 +5762,21 @@ static struct nf_hook_ops selinux_ipv4_ops[] = {
5762 { 5762 {
5763 .hook = selinux_ipv4_postroute, 5763 .hook = selinux_ipv4_postroute,
5764 .owner = THIS_MODULE, 5764 .owner = THIS_MODULE,
5765 .pf = PF_INET, 5765 .pf = NFPROTO_IPV4,
5766 .hooknum = NF_INET_POST_ROUTING, 5766 .hooknum = NF_INET_POST_ROUTING,
5767 .priority = NF_IP_PRI_SELINUX_LAST, 5767 .priority = NF_IP_PRI_SELINUX_LAST,
5768 }, 5768 },
5769 { 5769 {
5770 .hook = selinux_ipv4_forward, 5770 .hook = selinux_ipv4_forward,
5771 .owner = THIS_MODULE, 5771 .owner = THIS_MODULE,
5772 .pf = PF_INET, 5772 .pf = NFPROTO_IPV4,
5773 .hooknum = NF_INET_FORWARD, 5773 .hooknum = NF_INET_FORWARD,
5774 .priority = NF_IP_PRI_SELINUX_FIRST, 5774 .priority = NF_IP_PRI_SELINUX_FIRST,
5775 }, 5775 },
5776 { 5776 {
5777 .hook = selinux_ipv4_output, 5777 .hook = selinux_ipv4_output,
5778 .owner = THIS_MODULE, 5778 .owner = THIS_MODULE,
5779 .pf = PF_INET, 5779 .pf = NFPROTO_IPV4,
5780 .hooknum = NF_INET_LOCAL_OUT, 5780 .hooknum = NF_INET_LOCAL_OUT,
5781 .priority = NF_IP_PRI_SELINUX_FIRST, 5781 .priority = NF_IP_PRI_SELINUX_FIRST,
5782 } 5782 }
@@ -5788,14 +5788,14 @@ static struct nf_hook_ops selinux_ipv6_ops[] = {
5788 { 5788 {
5789 .hook = selinux_ipv6_postroute, 5789 .hook = selinux_ipv6_postroute,
5790 .owner = THIS_MODULE, 5790 .owner = THIS_MODULE,
5791 .pf = PF_INET6, 5791 .pf = NFPROTO_IPV6,
5792 .hooknum = NF_INET_POST_ROUTING, 5792 .hooknum = NF_INET_POST_ROUTING,
5793 .priority = NF_IP6_PRI_SELINUX_LAST, 5793 .priority = NF_IP6_PRI_SELINUX_LAST,
5794 }, 5794 },
5795 { 5795 {
5796 .hook = selinux_ipv6_forward, 5796 .hook = selinux_ipv6_forward,
5797 .owner = THIS_MODULE, 5797 .owner = THIS_MODULE,
5798 .pf = PF_INET6, 5798 .pf = NFPROTO_IPV6,
5799 .hooknum = NF_INET_FORWARD, 5799 .hooknum = NF_INET_FORWARD,
5800 .priority = NF_IP6_PRI_SELINUX_FIRST, 5800 .priority = NF_IP6_PRI_SELINUX_FIRST,
5801 } 5801 }
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c
index 161e01a6c7ef..8a77725423e0 100644
--- a/security/selinux/netlink.c
+++ b/security/selinux/netlink.c
@@ -19,6 +19,7 @@
19#include <linux/netlink.h> 19#include <linux/netlink.h>
20#include <linux/selinux_netlink.h> 20#include <linux/selinux_netlink.h>
21#include <net/net_namespace.h> 21#include <net/net_namespace.h>
22#include <net/netlink.h>
22 23
23#include "security.h" 24#include "security.h"
24 25
@@ -47,7 +48,7 @@ static void selnl_add_payload(struct nlmsghdr *nlh, int len, int msgtype, void *
47{ 48{
48 switch (msgtype) { 49 switch (msgtype) {
49 case SELNL_MSG_SETENFORCE: { 50 case SELNL_MSG_SETENFORCE: {
50 struct selnl_msg_setenforce *msg = NLMSG_DATA(nlh); 51 struct selnl_msg_setenforce *msg = nlmsg_data(nlh);
51 52
52 memset(msg, 0, len); 53 memset(msg, 0, len);
53 msg->val = *((int *)data); 54 msg->val = *((int *)data);
@@ -55,7 +56,7 @@ static void selnl_add_payload(struct nlmsghdr *nlh, int len, int msgtype, void *
55 } 56 }
56 57
57 case SELNL_MSG_POLICYLOAD: { 58 case SELNL_MSG_POLICYLOAD: {
58 struct selnl_msg_policyload *msg = NLMSG_DATA(nlh); 59 struct selnl_msg_policyload *msg = nlmsg_data(nlh);
59 60
60 memset(msg, 0, len); 61 memset(msg, 0, len);
61 msg->seqno = *((u32 *)data); 62 msg->seqno = *((u32 *)data);
@@ -81,7 +82,9 @@ static void selnl_notify(int msgtype, void *data)
81 goto oom; 82 goto oom;
82 83
83 tmp = skb->tail; 84 tmp = skb->tail;
84 nlh = NLMSG_PUT(skb, 0, 0, msgtype, len); 85 nlh = nlmsg_put(skb, 0, 0, msgtype, len, 0);
86 if (!nlh)
87 goto out_kfree_skb;
85 selnl_add_payload(nlh, len, msgtype, data); 88 selnl_add_payload(nlh, len, msgtype, data);
86 nlh->nlmsg_len = skb->tail - tmp; 89 nlh->nlmsg_len = skb->tail - tmp;
87 NETLINK_CB(skb).dst_group = SELNLGRP_AVC; 90 NETLINK_CB(skb).dst_group = SELNLGRP_AVC;
@@ -89,7 +92,7 @@ static void selnl_notify(int msgtype, void *data)
89out: 92out:
90 return; 93 return;
91 94
92nlmsg_failure: 95out_kfree_skb:
93 kfree_skb(skb); 96 kfree_skb(skb);
94oom: 97oom:
95 printk(KERN_ERR "SELinux: OOM in %s\n", __func__); 98 printk(KERN_ERR "SELinux: OOM in %s\n", __func__);
@@ -108,8 +111,12 @@ void selnl_notify_policyload(u32 seqno)
108 111
109static int __init selnl_init(void) 112static int __init selnl_init(void)
110{ 113{
114 struct netlink_kernel_cfg cfg = {
115 .groups = SELNLGRP_MAX,
116 };
117
111 selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX, 118 selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX,
112 SELNLGRP_MAX, NULL, NULL, THIS_MODULE); 119 THIS_MODULE, &cfg);
113 if (selnl == NULL) 120 if (selnl == NULL)
114 panic("SELinux: Cannot create netlink socket."); 121 panic("SELinux: Cannot create netlink socket.");
115 netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV); 122 netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV);
diff --git a/security/smack/smack.h b/security/smack/smack.h
index cc361b8f3d13..99b36124f712 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -43,7 +43,6 @@ struct superblock_smack {
43 char *smk_hat; 43 char *smk_hat;
44 char *smk_default; 44 char *smk_default;
45 int smk_initialized; 45 int smk_initialized;
46 spinlock_t smk_sblock; /* for initialization */
47}; 46};
48 47
49struct socket_smack { 48struct socket_smack {
@@ -284,6 +283,19 @@ static inline char *smk_of_current(void)
284} 283}
285 284
286/* 285/*
286 * Is the task privileged and allowed to be privileged
287 * by the onlycap rule.
288 */
289static inline int smack_privileged(int cap)
290{
291 if (!capable(cap))
292 return 0;
293 if (smack_onlycap == NULL || smack_onlycap == smk_of_current())
294 return 1;
295 return 0;
296}
297
298/*
287 * logging functions 299 * logging functions
288 */ 300 */
289#define SMACK_AUDIT_DENIED 0x1 301#define SMACK_AUDIT_DENIED 0x1
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 9f3705e92712..db14689a21e0 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -220,14 +220,9 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
220 } 220 }
221 221
222 /* 222 /*
223 * Return if a specific label has been designated as the 223 * Allow for priviliged to override policy.
224 * only one that gets privilege and current does not
225 * have that label.
226 */ 224 */
227 if (smack_onlycap != NULL && smack_onlycap != sp) 225 if (rc != 0 && smack_privileged(CAP_MAC_OVERRIDE))
228 goto out_audit;
229
230 if (capable(CAP_MAC_OVERRIDE))
231 rc = 0; 226 rc = 0;
232 227
233out_audit: 228out_audit:
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index ee0bb5735f35..8221514cc997 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -217,7 +217,7 @@ static int smack_syslog(int typefrom_file)
217 int rc = 0; 217 int rc = 0;
218 char *sp = smk_of_current(); 218 char *sp = smk_of_current();
219 219
220 if (capable(CAP_MAC_OVERRIDE)) 220 if (smack_privileged(CAP_MAC_OVERRIDE))
221 return 0; 221 return 0;
222 222
223 if (sp != smack_known_floor.smk_known) 223 if (sp != smack_known_floor.smk_known)
@@ -251,7 +251,6 @@ static int smack_sb_alloc_security(struct super_block *sb)
251 sbsp->smk_floor = smack_known_floor.smk_known; 251 sbsp->smk_floor = smack_known_floor.smk_known;
252 sbsp->smk_hat = smack_known_hat.smk_known; 252 sbsp->smk_hat = smack_known_hat.smk_known;
253 sbsp->smk_initialized = 0; 253 sbsp->smk_initialized = 0;
254 spin_lock_init(&sbsp->smk_sblock);
255 254
256 sb->s_security = sbsp; 255 sb->s_security = sbsp;
257 256
@@ -332,13 +331,10 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
332 char *commap; 331 char *commap;
333 char *nsp; 332 char *nsp;
334 333
335 spin_lock(&sp->smk_sblock); 334 if (sp->smk_initialized != 0)
336 if (sp->smk_initialized != 0) {
337 spin_unlock(&sp->smk_sblock);
338 return 0; 335 return 0;
339 } 336
340 sp->smk_initialized = 1; 337 sp->smk_initialized = 1;
341 spin_unlock(&sp->smk_sblock);
342 338
343 for (op = data; op != NULL; op = commap) { 339 for (op = data; op != NULL; op = commap) {
344 commap = strchr(op, ','); 340 commap = strchr(op, ',');
@@ -825,7 +821,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
825 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || 821 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
826 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || 822 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
827 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { 823 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
828 if (!capable(CAP_MAC_ADMIN)) 824 if (!smack_privileged(CAP_MAC_ADMIN))
829 rc = -EPERM; 825 rc = -EPERM;
830 /* 826 /*
831 * check label validity here so import wont fail on 827 * check label validity here so import wont fail on
@@ -835,7 +831,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
835 smk_import(value, size) == NULL) 831 smk_import(value, size) == NULL)
836 rc = -EINVAL; 832 rc = -EINVAL;
837 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { 833 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
838 if (!capable(CAP_MAC_ADMIN)) 834 if (!smack_privileged(CAP_MAC_ADMIN))
839 rc = -EPERM; 835 rc = -EPERM;
840 if (size != TRANS_TRUE_SIZE || 836 if (size != TRANS_TRUE_SIZE ||
841 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) 837 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
@@ -931,7 +927,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
931 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || 927 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
932 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || 928 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
933 strcmp(name, XATTR_NAME_SMACKMMAP)) { 929 strcmp(name, XATTR_NAME_SMACKMMAP)) {
934 if (!capable(CAP_MAC_ADMIN)) 930 if (!smack_privileged(CAP_MAC_ADMIN))
935 rc = -EPERM; 931 rc = -EPERM;
936 } else 932 } else
937 rc = cap_inode_removexattr(dentry, name); 933 rc = cap_inode_removexattr(dentry, name);
@@ -1720,7 +1716,8 @@ static int smack_task_wait(struct task_struct *p)
1720 * state into account in the decision as well as 1716 * state into account in the decision as well as
1721 * the smack value. 1717 * the smack value.
1722 */ 1718 */
1723 if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE)) 1719 if (smack_privileged(CAP_MAC_OVERRIDE) ||
1720 has_capability(p, CAP_MAC_OVERRIDE))
1724 rc = 0; 1721 rc = 0;
1725 /* we log only if we didn't get overriden */ 1722 /* we log only if we didn't get overriden */
1726 out_log: 1723 out_log:
@@ -2721,7 +2718,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2721 if (p != current) 2718 if (p != current)
2722 return -EPERM; 2719 return -EPERM;
2723 2720
2724 if (!capable(CAP_MAC_ADMIN)) 2721 if (!smack_privileged(CAP_MAC_ADMIN))
2725 return -EPERM; 2722 return -EPERM;
2726 2723
2727 if (value == NULL || size == 0 || size >= SMK_LONGLABEL) 2724 if (value == NULL || size == 0 || size >= SMK_LONGLABEL)
@@ -2784,7 +2781,7 @@ static int smack_unix_stream_connect(struct sock *sock,
2784 smk_ad_setfield_u_net_sk(&ad, other); 2781 smk_ad_setfield_u_net_sk(&ad, other);
2785#endif 2782#endif
2786 2783
2787 if (!capable(CAP_MAC_OVERRIDE)) 2784 if (!smack_privileged(CAP_MAC_OVERRIDE))
2788 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 2785 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2789 2786
2790 /* 2787 /*
@@ -2820,7 +2817,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2820 smk_ad_setfield_u_net_sk(&ad, other->sk); 2817 smk_ad_setfield_u_net_sk(&ad, other->sk);
2821#endif 2818#endif
2822 2819
2823 if (!capable(CAP_MAC_OVERRIDE)) 2820 if (!smack_privileged(CAP_MAC_OVERRIDE))
2824 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 2821 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2825 2822
2826 return rc; 2823 return rc;
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 1810c9a4ed48..d31e6d957c21 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -215,28 +215,27 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list,
215 * @access: access string 215 * @access: access string
216 * @rule: Smack rule 216 * @rule: Smack rule
217 * @import: if non-zero, import labels 217 * @import: if non-zero, import labels
218 * @len: label length limit
218 * 219 *
219 * Returns 0 on success, -1 on failure 220 * Returns 0 on success, -1 on failure
220 */ 221 */
221static int smk_fill_rule(const char *subject, const char *object, 222static int smk_fill_rule(const char *subject, const char *object,
222 const char *access, struct smack_rule *rule, 223 const char *access, struct smack_rule *rule,
223 int import) 224 int import, int len)
224{ 225{
225 int rc = -1;
226 int done;
227 const char *cp; 226 const char *cp;
228 struct smack_known *skp; 227 struct smack_known *skp;
229 228
230 if (import) { 229 if (import) {
231 rule->smk_subject = smk_import(subject, 0); 230 rule->smk_subject = smk_import(subject, len);
232 if (rule->smk_subject == NULL) 231 if (rule->smk_subject == NULL)
233 return -1; 232 return -1;
234 233
235 rule->smk_object = smk_import(object, 0); 234 rule->smk_object = smk_import(object, len);
236 if (rule->smk_object == NULL) 235 if (rule->smk_object == NULL)
237 return -1; 236 return -1;
238 } else { 237 } else {
239 cp = smk_parse_smack(subject, 0); 238 cp = smk_parse_smack(subject, len);
240 if (cp == NULL) 239 if (cp == NULL)
241 return -1; 240 return -1;
242 skp = smk_find_entry(cp); 241 skp = smk_find_entry(cp);
@@ -245,7 +244,7 @@ static int smk_fill_rule(const char *subject, const char *object,
245 return -1; 244 return -1;
246 rule->smk_subject = skp->smk_known; 245 rule->smk_subject = skp->smk_known;
247 246
248 cp = smk_parse_smack(object, 0); 247 cp = smk_parse_smack(object, len);
249 if (cp == NULL) 248 if (cp == NULL)
250 return -1; 249 return -1;
251 skp = smk_find_entry(cp); 250 skp = smk_find_entry(cp);
@@ -257,7 +256,7 @@ static int smk_fill_rule(const char *subject, const char *object,
257 256
258 rule->smk_access = 0; 257 rule->smk_access = 0;
259 258
260 for (cp = access, done = 0; *cp && !done; cp++) { 259 for (cp = access; *cp != '\0'; cp++) {
261 switch (*cp) { 260 switch (*cp) {
262 case '-': 261 case '-':
263 break; 262 break;
@@ -282,13 +281,11 @@ static int smk_fill_rule(const char *subject, const char *object,
282 rule->smk_access |= MAY_TRANSMUTE; 281 rule->smk_access |= MAY_TRANSMUTE;
283 break; 282 break;
284 default: 283 default:
285 done = 1; 284 return 0;
286 break;
287 } 285 }
288 } 286 }
289 rc = 0;
290 287
291 return rc; 288 return 0;
292} 289}
293 290
294/** 291/**
@@ -304,7 +301,8 @@ static int smk_parse_rule(const char *data, struct smack_rule *rule, int import)
304 int rc; 301 int rc;
305 302
306 rc = smk_fill_rule(data, data + SMK_LABELLEN, 303 rc = smk_fill_rule(data, data + SMK_LABELLEN,
307 data + SMK_LABELLEN + SMK_LABELLEN, rule, import); 304 data + SMK_LABELLEN + SMK_LABELLEN, rule, import,
305 SMK_LABELLEN);
308 return rc; 306 return rc;
309} 307}
310 308
@@ -340,7 +338,7 @@ static int smk_parse_long_rule(const char *data, struct smack_rule *rule,
340 goto free_out_o; 338 goto free_out_o;
341 339
342 if (sscanf(data, "%s %s %s", subject, object, access) == 3) 340 if (sscanf(data, "%s %s %s", subject, object, access) == 3)
343 rc = smk_fill_rule(subject, object, access, rule, import); 341 rc = smk_fill_rule(subject, object, access, rule, import, 0);
344 342
345 kfree(access); 343 kfree(access);
346free_out_o: 344free_out_o:
@@ -520,6 +518,9 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
520 if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) 518 if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max)
521 return; 519 return;
522 520
521 if (srp->smk_access == 0)
522 return;
523
523 seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); 524 seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object);
524 525
525 seq_putc(s, ' '); 526 seq_putc(s, ' ');
@@ -534,8 +535,6 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
534 seq_putc(s, 'a'); 535 seq_putc(s, 'a');
535 if (srp->smk_access & MAY_TRANSMUTE) 536 if (srp->smk_access & MAY_TRANSMUTE)
536 seq_putc(s, 't'); 537 seq_putc(s, 't');
537 if (srp->smk_access == 0)
538 seq_putc(s, '-');
539 538
540 seq_putc(s, '\n'); 539 seq_putc(s, '\n');
541} 540}
@@ -595,13 +594,12 @@ static int smk_open_load(struct inode *inode, struct file *file)
595static ssize_t smk_write_load(struct file *file, const char __user *buf, 594static ssize_t smk_write_load(struct file *file, const char __user *buf,
596 size_t count, loff_t *ppos) 595 size_t count, loff_t *ppos)
597{ 596{
598
599 /* 597 /*
600 * Must have privilege. 598 * Must have privilege.
601 * No partial writes. 599 * No partial writes.
602 * Enough data must be present. 600 * Enough data must be present.
603 */ 601 */
604 if (!capable(CAP_MAC_ADMIN)) 602 if (!smack_privileged(CAP_MAC_ADMIN))
605 return -EPERM; 603 return -EPERM;
606 604
607 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, 605 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
@@ -787,7 +785,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
787 * No partial writes. 785 * No partial writes.
788 * Enough data must be present. 786 * Enough data must be present.
789 */ 787 */
790 if (!capable(CAP_MAC_ADMIN)) 788 if (!smack_privileged(CAP_MAC_ADMIN))
791 return -EPERM; 789 return -EPERM;
792 if (*ppos != 0) 790 if (*ppos != 0)
793 return -EINVAL; 791 return -EINVAL;
@@ -1090,7 +1088,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1090 * "<addr/mask, as a.b.c.d/e><space><label>" 1088 * "<addr/mask, as a.b.c.d/e><space><label>"
1091 * "<addr, as a.b.c.d><space><label>" 1089 * "<addr, as a.b.c.d><space><label>"
1092 */ 1090 */
1093 if (!capable(CAP_MAC_ADMIN)) 1091 if (!smack_privileged(CAP_MAC_ADMIN))
1094 return -EPERM; 1092 return -EPERM;
1095 if (*ppos != 0) 1093 if (*ppos != 0)
1096 return -EINVAL; 1094 return -EINVAL;
@@ -1267,7 +1265,7 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf,
1267 char temp[80]; 1265 char temp[80];
1268 int i; 1266 int i;
1269 1267
1270 if (!capable(CAP_MAC_ADMIN)) 1268 if (!smack_privileged(CAP_MAC_ADMIN))
1271 return -EPERM; 1269 return -EPERM;
1272 1270
1273 if (count >= sizeof(temp) || count == 0) 1271 if (count >= sizeof(temp) || count == 0)
@@ -1334,7 +1332,7 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf,
1334 char temp[80]; 1332 char temp[80];
1335 int i; 1333 int i;
1336 1334
1337 if (!capable(CAP_MAC_ADMIN)) 1335 if (!smack_privileged(CAP_MAC_ADMIN))
1338 return -EPERM; 1336 return -EPERM;
1339 1337
1340 if (count >= sizeof(temp) || count == 0) 1338 if (count >= sizeof(temp) || count == 0)
@@ -1412,7 +1410,7 @@ static ssize_t smk_write_mapped(struct file *file, const char __user *buf,
1412 char temp[80]; 1410 char temp[80];
1413 int i; 1411 int i;
1414 1412
1415 if (!capable(CAP_MAC_ADMIN)) 1413 if (!smack_privileged(CAP_MAC_ADMIN))
1416 return -EPERM; 1414 return -EPERM;
1417 1415
1418 if (count >= sizeof(temp) || count == 0) 1416 if (count >= sizeof(temp) || count == 0)
@@ -1503,7 +1501,7 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1503 char *data; 1501 char *data;
1504 int rc = count; 1502 int rc = count;
1505 1503
1506 if (!capable(CAP_MAC_ADMIN)) 1504 if (!smack_privileged(CAP_MAC_ADMIN))
1507 return -EPERM; 1505 return -EPERM;
1508 1506
1509 data = kzalloc(count + 1, GFP_KERNEL); 1507 data = kzalloc(count + 1, GFP_KERNEL);
@@ -1586,7 +1584,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1586 char *sp = smk_of_task(current->cred->security); 1584 char *sp = smk_of_task(current->cred->security);
1587 int rc = count; 1585 int rc = count;
1588 1586
1589 if (!capable(CAP_MAC_ADMIN)) 1587 if (!smack_privileged(CAP_MAC_ADMIN))
1590 return -EPERM; 1588 return -EPERM;
1591 1589
1592 /* 1590 /*
@@ -1664,7 +1662,7 @@ static ssize_t smk_write_logging(struct file *file, const char __user *buf,
1664 char temp[32]; 1662 char temp[32];
1665 int i; 1663 int i;
1666 1664
1667 if (!capable(CAP_MAC_ADMIN)) 1665 if (!smack_privileged(CAP_MAC_ADMIN))
1668 return -EPERM; 1666 return -EPERM;
1669 1667
1670 if (count >= sizeof(temp) || count == 0) 1668 if (count >= sizeof(temp) || count == 0)
@@ -1885,7 +1883,7 @@ static ssize_t smk_write_load2(struct file *file, const char __user *buf,
1885 /* 1883 /*
1886 * Must have privilege. 1884 * Must have privilege.
1887 */ 1885 */
1888 if (!capable(CAP_MAC_ADMIN)) 1886 if (!smack_privileged(CAP_MAC_ADMIN))
1889 return -EPERM; 1887 return -EPERM;
1890 1888
1891 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, 1889 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
@@ -2051,7 +2049,6 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
2051 } 2049 }
2052 2050
2053 root_inode = sb->s_root->d_inode; 2051 root_inode = sb->s_root->d_inode;
2054 root_inode->i_security = new_inode_smack(smack_known_floor.smk_known);
2055 2052
2056 return 0; 2053 return 0;
2057} 2054}