aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
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.h4
-rw-r--r--security/keys/keyctl.c28
-rw-r--r--security/keys/keyring.c2
-rw-r--r--security/keys/process_keys.c5
-rw-r--r--security/security.c1
-rw-r--r--security/selinux/avc.c2
-rw-r--r--security/selinux/hooks.c33
-rw-r--r--security/selinux/include/classmap.h4
-rw-r--r--security/selinux/include/security.h2
-rw-r--r--security/selinux/netlink.c17
-rw-r--r--security/selinux/selinuxfs.c6
-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.c61
25 files changed, 171 insertions, 136 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 3dcbf86b0d31..22ff05269e3d 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -149,7 +149,7 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
149#define KEY_LOOKUP_FOR_UNLINK 0x04 149#define KEY_LOOKUP_FOR_UNLINK 0x04
150 150
151extern long join_session_keyring(const char *name); 151extern long join_session_keyring(const char *name);
152extern void key_change_session_keyring(struct task_work *twork); 152extern void key_change_session_keyring(struct callback_head *twork);
153 153
154extern struct work_struct key_gc_work; 154extern struct work_struct key_gc_work;
155extern unsigned key_gc_delay; 155extern unsigned key_gc_delay;
@@ -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 0f5b3f027299..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,
@@ -1456,7 +1456,7 @@ long keyctl_session_to_parent(void)
1456{ 1456{
1457 struct task_struct *me, *parent; 1457 struct task_struct *me, *parent;
1458 const struct cred *mycred, *pcred; 1458 const struct cred *mycred, *pcred;
1459 struct task_work *newwork, *oldwork; 1459 struct callback_head *newwork, *oldwork;
1460 key_ref_t keyring_r; 1460 key_ref_t keyring_r;
1461 struct cred *cred; 1461 struct cred *cred;
1462 int ret; 1462 int ret;
@@ -1466,19 +1466,17 @@ long keyctl_session_to_parent(void)
1466 return PTR_ERR(keyring_r); 1466 return PTR_ERR(keyring_r);
1467 1467
1468 ret = -ENOMEM; 1468 ret = -ENOMEM;
1469 newwork = kmalloc(sizeof(struct task_work), GFP_KERNEL);
1470 if (!newwork)
1471 goto error_keyring;
1472 1469
1473 /* our parent is going to need a new cred struct, a new tgcred struct 1470 /* our parent is going to need a new cred struct, a new tgcred struct
1474 * and new security data, so we allocate them here to prevent ENOMEM in 1471 * and new security data, so we allocate them here to prevent ENOMEM in
1475 * our parent */ 1472 * our parent */
1476 cred = cred_alloc_blank(); 1473 cred = cred_alloc_blank();
1477 if (!cred) 1474 if (!cred)
1478 goto error_newwork; 1475 goto error_keyring;
1476 newwork = &cred->rcu;
1479 1477
1480 cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r); 1478 cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r);
1481 init_task_work(newwork, key_change_session_keyring, cred); 1479 init_task_work(newwork, key_change_session_keyring);
1482 1480
1483 me = current; 1481 me = current;
1484 rcu_read_lock(); 1482 rcu_read_lock();
@@ -1488,6 +1486,7 @@ long keyctl_session_to_parent(void)
1488 oldwork = NULL; 1486 oldwork = NULL;
1489 parent = me->real_parent; 1487 parent = me->real_parent;
1490 1488
1489 task_lock(parent);
1491 /* the parent mustn't be init and mustn't be a kernel thread */ 1490 /* the parent mustn't be init and mustn't be a kernel thread */
1492 if (parent->pid <= 1 || !parent->mm) 1491 if (parent->pid <= 1 || !parent->mm)
1493 goto unlock; 1492 goto unlock;
@@ -1531,20 +1530,15 @@ long keyctl_session_to_parent(void)
1531 if (!ret) 1530 if (!ret)
1532 newwork = NULL; 1531 newwork = NULL;
1533unlock: 1532unlock:
1533 task_unlock(parent);
1534 write_unlock_irq(&tasklist_lock); 1534 write_unlock_irq(&tasklist_lock);
1535 rcu_read_unlock(); 1535 rcu_read_unlock();
1536 if (oldwork) { 1536 if (oldwork)
1537 put_cred(oldwork->data); 1537 put_cred(container_of(oldwork, struct cred, rcu));
1538 kfree(oldwork); 1538 if (newwork)
1539 } 1539 put_cred(cred);
1540 if (newwork) {
1541 put_cred(newwork->data);
1542 kfree(newwork);
1543 }
1544 return ret; 1540 return ret;
1545 1541
1546error_newwork:
1547 kfree(newwork);
1548error_keyring: 1542error_keyring:
1549 key_ref_put(keyring_r); 1543 key_ref_put(keyring_r);
1550 return ret; 1544 return ret;
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/keys/process_keys.c b/security/keys/process_keys.c
index 4ad54eea1ea4..54339cfd6734 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -834,12 +834,11 @@ error:
834 * Replace a process's session keyring on behalf of one of its children when 834 * Replace a process's session keyring on behalf of one of its children when
835 * the target process is about to resume userspace execution. 835 * the target process is about to resume userspace execution.
836 */ 836 */
837void key_change_session_keyring(struct task_work *twork) 837void key_change_session_keyring(struct callback_head *twork)
838{ 838{
839 const struct cred *old = current_cred(); 839 const struct cred *old = current_cred();
840 struct cred *new = twork->data; 840 struct cred *new = container_of(twork, struct cred, rcu);
841 841
842 kfree(twork);
843 if (unlikely(current->flags & PF_EXITING)) { 842 if (unlikely(current->flags & PF_EXITING)) {
844 put_cred(new); 843 put_cred(new);
845 return; 844 return;
diff --git a/security/security.c b/security/security.c
index 3efc9b12aef4..860aeb349cb3 100644
--- a/security/security.c
+++ b/security/security.c
@@ -23,6 +23,7 @@
23#include <linux/mman.h> 23#include <linux/mman.h>
24#include <linux/mount.h> 24#include <linux/mount.h>
25#include <linux/personality.h> 25#include <linux/personality.h>
26#include <linux/backing-dev.h>
26#include <net/flow.h> 27#include <net/flow.h>
27 28
28#define MAX_LSM_EVM_XATTR 2 29#define MAX_LSM_EVM_XATTR 2
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 68d82daed257..4d3fab47e643 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -274,7 +274,7 @@ static struct avc_node *avc_alloc_node(void)
274{ 274{
275 struct avc_node *node; 275 struct avc_node *node;
276 276
277 node = kmem_cache_zalloc(avc_node_cachep, GFP_ATOMIC); 277 node = kmem_cache_zalloc(avc_node_cachep, GFP_ATOMIC|__GFP_NOMEMALLOC);
278 if (!node) 278 if (!node)
279 goto out; 279 goto out;
280 280
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 372ec6502aa8..6c77f63c7591 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2129,7 +2129,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2129 int fd; 2129 int fd;
2130 2130
2131 j++; 2131 j++;
2132 i = j * __NFDBITS; 2132 i = j * BITS_PER_LONG;
2133 fdt = files_fdtable(files); 2133 fdt = files_fdtable(files);
2134 if (i >= fdt->max_fds) 2134 if (i >= fdt->max_fds)
2135 break; 2135 break;
@@ -2157,8 +2157,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2157 get_file(devnull); 2157 get_file(devnull);
2158 } else { 2158 } else {
2159 devnull = dentry_open( 2159 devnull = dentry_open(
2160 dget(selinux_null), 2160 &selinux_null,
2161 mntget(selinuxfs_mount),
2162 O_RDWR, cred); 2161 O_RDWR, cred);
2163 if (IS_ERR(devnull)) { 2162 if (IS_ERR(devnull)) {
2164 devnull = NULL; 2163 devnull = NULL;
@@ -2717,7 +2716,7 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2717 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) 2716 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
2718 return dentry_has_perm(cred, dentry, FILE__SETATTR); 2717 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2719 2718
2720 if (ia_valid & ATTR_SIZE) 2719 if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE))
2721 av |= FILE__OPEN; 2720 av |= FILE__OPEN;
2722 2721
2723 return dentry_has_perm(cred, dentry, av); 2722 return dentry_has_perm(cred, dentry, av);
@@ -2792,11 +2791,16 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2792 2791
2793 /* We strip a nul only if it is at the end, otherwise the 2792 /* We strip a nul only if it is at the end, otherwise the
2794 * context contains a nul and we should audit that */ 2793 * context contains a nul and we should audit that */
2795 str = value; 2794 if (value) {
2796 if (str[size - 1] == '\0') 2795 str = value;
2797 audit_size = size - 1; 2796 if (str[size - 1] == '\0')
2798 else 2797 audit_size = size - 1;
2799 audit_size = size; 2798 else
2799 audit_size = size;
2800 } else {
2801 str = "";
2802 audit_size = 0;
2803 }
2800 ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR); 2804 ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR);
2801 audit_log_format(ab, "op=setxattr invalid_context="); 2805 audit_log_format(ab, "op=setxattr invalid_context=");
2802 audit_log_n_untrustedstring(ab, value, audit_size); 2806 audit_log_n_untrustedstring(ab, value, audit_size);
@@ -3181,6 +3185,7 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd,
3181 case F_GETFL: 3185 case F_GETFL:
3182 case F_GETOWN: 3186 case F_GETOWN:
3183 case F_GETSIG: 3187 case F_GETSIG:
3188 case F_GETOWNER_UIDS:
3184 /* Just check FD__USE permission */ 3189 /* Just check FD__USE permission */
3185 err = file_has_perm(cred, file, 0); 3190 err = file_has_perm(cred, file, 0);
3186 break; 3191 break;
@@ -5763,21 +5768,21 @@ static struct nf_hook_ops selinux_ipv4_ops[] = {
5763 { 5768 {
5764 .hook = selinux_ipv4_postroute, 5769 .hook = selinux_ipv4_postroute,
5765 .owner = THIS_MODULE, 5770 .owner = THIS_MODULE,
5766 .pf = PF_INET, 5771 .pf = NFPROTO_IPV4,
5767 .hooknum = NF_INET_POST_ROUTING, 5772 .hooknum = NF_INET_POST_ROUTING,
5768 .priority = NF_IP_PRI_SELINUX_LAST, 5773 .priority = NF_IP_PRI_SELINUX_LAST,
5769 }, 5774 },
5770 { 5775 {
5771 .hook = selinux_ipv4_forward, 5776 .hook = selinux_ipv4_forward,
5772 .owner = THIS_MODULE, 5777 .owner = THIS_MODULE,
5773 .pf = PF_INET, 5778 .pf = NFPROTO_IPV4,
5774 .hooknum = NF_INET_FORWARD, 5779 .hooknum = NF_INET_FORWARD,
5775 .priority = NF_IP_PRI_SELINUX_FIRST, 5780 .priority = NF_IP_PRI_SELINUX_FIRST,
5776 }, 5781 },
5777 { 5782 {
5778 .hook = selinux_ipv4_output, 5783 .hook = selinux_ipv4_output,
5779 .owner = THIS_MODULE, 5784 .owner = THIS_MODULE,
5780 .pf = PF_INET, 5785 .pf = NFPROTO_IPV4,
5781 .hooknum = NF_INET_LOCAL_OUT, 5786 .hooknum = NF_INET_LOCAL_OUT,
5782 .priority = NF_IP_PRI_SELINUX_FIRST, 5787 .priority = NF_IP_PRI_SELINUX_FIRST,
5783 } 5788 }
@@ -5789,14 +5794,14 @@ static struct nf_hook_ops selinux_ipv6_ops[] = {
5789 { 5794 {
5790 .hook = selinux_ipv6_postroute, 5795 .hook = selinux_ipv6_postroute,
5791 .owner = THIS_MODULE, 5796 .owner = THIS_MODULE,
5792 .pf = PF_INET6, 5797 .pf = NFPROTO_IPV6,
5793 .hooknum = NF_INET_POST_ROUTING, 5798 .hooknum = NF_INET_POST_ROUTING,
5794 .priority = NF_IP6_PRI_SELINUX_LAST, 5799 .priority = NF_IP6_PRI_SELINUX_LAST,
5795 }, 5800 },
5796 { 5801 {
5797 .hook = selinux_ipv6_forward, 5802 .hook = selinux_ipv6_forward,
5798 .owner = THIS_MODULE, 5803 .owner = THIS_MODULE,
5799 .pf = PF_INET6, 5804 .pf = NFPROTO_IPV6,
5800 .hooknum = NF_INET_FORWARD, 5805 .hooknum = NF_INET_FORWARD,
5801 .priority = NF_IP6_PRI_SELINUX_FIRST, 5806 .priority = NF_IP6_PRI_SELINUX_FIRST,
5802 } 5807 }
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index b8c53723e09b..df2de54a958d 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -145,7 +145,9 @@ struct security_class_mapping secclass_map[] = {
145 "node_bind", "name_connect", NULL } }, 145 "node_bind", "name_connect", NULL } },
146 { "memprotect", { "mmap_zero", NULL } }, 146 { "memprotect", { "mmap_zero", NULL } },
147 { "peer", { "recv", NULL } }, 147 { "peer", { "recv", NULL } },
148 { "capability2", { "mac_override", "mac_admin", "syslog", NULL } }, 148 { "capability2",
149 { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend",
150 NULL } },
149 { "kernel_service", { "use_as_override", "create_files_as", NULL } }, 151 { "kernel_service", { "use_as_override", "create_files_as", NULL } },
150 { "tun_socket", 152 { "tun_socket",
151 { COMMON_SOCK_PERMS, NULL } }, 153 { COMMON_SOCK_PERMS, NULL } },
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index dde2005407aa..6d3885165d14 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -221,7 +221,7 @@ extern void selinux_status_update_policyload(int seqno);
221extern void selinux_complete_init(void); 221extern void selinux_complete_init(void);
222extern int selinux_disable(void); 222extern int selinux_disable(void);
223extern void exit_sel_fs(void); 223extern void exit_sel_fs(void);
224extern struct dentry *selinux_null; 224extern struct path selinux_null;
225extern struct vfsmount *selinuxfs_mount; 225extern struct vfsmount *selinuxfs_mount;
226extern void selnl_notify_setenforce(int val); 226extern void selnl_notify_setenforce(int val);
227extern void selnl_notify_policyload(u32 seqno); 227extern void selnl_notify_policyload(u32 seqno);
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/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 3ad290251288..298e695d6822 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1297,7 +1297,7 @@ out:
1297 1297
1298#define NULL_FILE_NAME "null" 1298#define NULL_FILE_NAME "null"
1299 1299
1300struct dentry *selinux_null; 1300struct path selinux_null;
1301 1301
1302static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf, 1302static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf,
1303 size_t count, loff_t *ppos) 1303 size_t count, loff_t *ppos)
@@ -1838,7 +1838,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1838 1838
1839 init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3)); 1839 init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3));
1840 d_add(dentry, inode); 1840 d_add(dentry, inode);
1841 selinux_null = dentry; 1841 selinux_null.dentry = dentry;
1842 1842
1843 dentry = sel_make_dir(sb->s_root, "avc", &sel_last_ino); 1843 dentry = sel_make_dir(sb->s_root, "avc", &sel_last_ino);
1844 if (IS_ERR(dentry)) { 1844 if (IS_ERR(dentry)) {
@@ -1912,7 +1912,7 @@ static int __init init_sel_fs(void)
1912 return err; 1912 return err;
1913 } 1913 }
1914 1914
1915 selinuxfs_mount = kern_mount(&sel_fs_type); 1915 selinux_null.mnt = selinuxfs_mount = kern_mount(&sel_fs_type);
1916 if (IS_ERR(selinuxfs_mount)) { 1916 if (IS_ERR(selinuxfs_mount)) {
1917 printk(KERN_ERR "selinuxfs: could not mount!\n"); 1917 printk(KERN_ERR "selinuxfs: could not mount!\n");
1918 err = PTR_ERR(selinuxfs_mount); 1918 err = PTR_ERR(selinuxfs_mount);
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..b1b768e4049a 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
@@ -325,11 +323,11 @@ static int smk_parse_long_rule(const char *data, struct smack_rule *rule,
325 int datalen; 323 int datalen;
326 int rc = -1; 324 int rc = -1;
327 325
328 /* 326 /* This is inefficient */
329 * This is probably inefficient, but safe.
330 */
331 datalen = strlen(data); 327 datalen = strlen(data);
332 subject = kzalloc(datalen, GFP_KERNEL); 328
329 /* Our first element can be 64 + \0 with no spaces */
330 subject = kzalloc(datalen + 1, GFP_KERNEL);
333 if (subject == NULL) 331 if (subject == NULL)
334 return -1; 332 return -1;
335 object = kzalloc(datalen, GFP_KERNEL); 333 object = kzalloc(datalen, GFP_KERNEL);
@@ -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}