aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 17:04:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 17:04:58 -0400
commitf39d420f672f99ad9a0fe7deb951a0030d4f0d9e (patch)
tree450e229a4305362f72cc5461aab8af4f2f5d023e
parentfe489bf4505ae26d3c6d6a1f1d3064c2a9c5cd85 (diff)
parent572e5b018ba68d634f30aef71cf04d85c884aa05 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris: "In this update, Smack learns to love IPv6 and to mount a filesystem with a transmutable hierarchy (i.e. security labels are inherited from parent directory upon creation rather than creating process). The rest of the changes are maintenance" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (37 commits) tpm/tpm_i2c_infineon: Remove unused header file tpm: tpm_i2c_infinion: Don't modify i2c_client->driver evm: audit integrity metadata failures integrity: move integrity_audit_msg() evm: calculate HMAC after initializing posix acl on tmpfs maintainers: add Dmitry Kasatkin Smack: Fix the bug smackcipso can't set CIPSO correctly Smack: Fix possible NULL pointer dereference at smk_netlbl_mls() Smack: Add smkfstransmute mount option Smack: Improve access check performance Smack: Local IPv6 port based controls tpm: fix regression caused by section type conflict of tpm_dev_release() in ppc builds maintainers: Remove Kent from maintainers tpm: move TPM_DIGEST_SIZE defintion tpm_tis: missing platform_driver_unregister() on error in init_tis() security: clarify cap_inode_getsecctx description apparmor: no need to delay vfree() apparmor: fix fully qualified name parsing apparmor: fix setprocattr arg processing for onexec apparmor: localize getting the security context to a few macros ...
-rw-r--r--Documentation/kernel-parameters.txt10
-rw-r--r--MAINTAINERS7
-rw-r--r--drivers/char/tpm/tpm.c2
-rw-r--r--drivers/char/tpm/tpm.h2
-rw-r--r--drivers/char/tpm/tpm_i2c_infineon.c4
-rw-r--r--drivers/char/tpm/tpm_tis.c17
-rw-r--r--include/linux/security.h3
-rw-r--r--include/linux/tpm.h2
-rw-r--r--mm/shmem.c16
-rw-r--r--security/apparmor/audit.c2
-rw-r--r--security/apparmor/context.c44
-rw-r--r--security/apparmor/domain.c26
-rw-r--r--security/apparmor/include/apparmor.h12
-rw-r--r--security/apparmor/include/context.h61
-rw-r--r--security/apparmor/include/file.h14
-rw-r--r--security/apparmor/include/match.h21
-rw-r--r--security/apparmor/include/policy.h16
-rw-r--r--security/apparmor/include/procattr.h1
-rw-r--r--security/apparmor/include/sid.h4
-rw-r--r--security/apparmor/ipc.c13
-rw-r--r--security/apparmor/lib.c44
-rw-r--r--security/apparmor/lsm.c69
-rw-r--r--security/apparmor/match.c23
-rw-r--r--security/apparmor/path.c2
-rw-r--r--security/apparmor/policy.c181
-rw-r--r--security/apparmor/policy_unpack.c4
-rw-r--r--security/apparmor/procattr.c6
-rw-r--r--security/apparmor/resource.c15
-rw-r--r--security/integrity/Kconfig15
-rw-r--r--security/integrity/Makefile1
-rw-r--r--security/integrity/evm/evm_main.c15
-rw-r--r--security/integrity/ima/Kconfig12
-rw-r--r--security/integrity/ima/Makefile1
-rw-r--r--security/integrity/ima/ima.h14
-rw-r--r--security/integrity/integrity.h14
-rw-r--r--security/integrity/integrity_audit.c (renamed from security/integrity/ima/ima_audit.c)12
-rw-r--r--security/smack/smack.h110
-rw-r--r--security/smack/smack_access.c43
-rw-r--r--security/smack/smack_lsm.c684
-rw-r--r--security/smack/smackfs.c53
40 files changed, 985 insertions, 610 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 7310b08bee5e..3c80382a84dd 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1129,11 +1129,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1129 The builtin appraise policy appraises all files 1129 The builtin appraise policy appraises all files
1130 owned by uid=0. 1130 owned by uid=0.
1131 1131
1132 ima_audit= [IMA]
1133 Format: { "0" | "1" }
1134 0 -- integrity auditing messages. (Default)
1135 1 -- enable informational integrity auditing messages.
1136
1137 ima_hash= [IMA] 1132 ima_hash= [IMA]
1138 Format: { "sha1" | "md5" } 1133 Format: { "sha1" | "md5" }
1139 default: "sha1" 1134 default: "sha1"
@@ -1160,6 +1155,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1160 1155
1161 int_pln_enable [x86] Enable power limit notification interrupt 1156 int_pln_enable [x86] Enable power limit notification interrupt
1162 1157
1158 integrity_audit=[IMA]
1159 Format: { "0" | "1" }
1160 0 -- basic integrity auditing messages. (Default)
1161 1 -- additional integrity auditing messages.
1162
1163 intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option 1163 intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option
1164 on 1164 on
1165 Enable intel iommu driver. 1165 Enable intel iommu driver.
diff --git a/MAINTAINERS b/MAINTAINERS
index 60c68fbee64a..85c1402e8a12 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4001,7 +4001,8 @@ S: Maintained
4001F: arch/ia64/ 4001F: arch/ia64/
4002 4002
4003IBM Power in-Nest Crypto Acceleration 4003IBM Power in-Nest Crypto Acceleration
4004M: Kent Yoder <key@linux.vnet.ibm.com> 4004M: Marcelo Henrique Cerri <mhcerri@linux.vnet.ibm.com>
4005M: Fionnuala Gunter <fin@linux.vnet.ibm.com>
4005L: linux-crypto@vger.kernel.org 4006L: linux-crypto@vger.kernel.org
4006S: Supported 4007S: Supported
4007F: drivers/crypto/nx/ 4008F: drivers/crypto/nx/
@@ -4130,6 +4131,7 @@ F: drivers/ipack/
4130 4131
4131INTEGRITY MEASUREMENT ARCHITECTURE (IMA) 4132INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
4132M: Mimi Zohar <zohar@us.ibm.com> 4133M: Mimi Zohar <zohar@us.ibm.com>
4134M: Dmitry Kasatkin <d.kasatkin@samsung.com>
4133S: Supported 4135S: Supported
4134F: security/integrity/ima/ 4136F: security/integrity/ima/
4135 4137
@@ -8282,7 +8284,8 @@ S: Odd fixes
8282F: drivers/media/usb/tm6000/ 8284F: drivers/media/usb/tm6000/
8283 8285
8284TPM DEVICE DRIVER 8286TPM DEVICE DRIVER
8285M: Kent Yoder <key@linux.vnet.ibm.com> 8287M: Leonidas Da Silva Barbosa <leosilva@linux.vnet.ibm.com>
8288M: Ashley Lai <ashley@ashleylai.com>
8286M: Rajiv Andrade <mail@srajiv.net> 8289M: Rajiv Andrade <mail@srajiv.net>
8287W: http://tpmdd.sourceforge.net 8290W: http://tpmdd.sourceforge.net
8288M: Marcel Selhorst <tpmdd@selhorst.net> 8291M: Marcel Selhorst <tpmdd@selhorst.net>
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 7c3b3dcbfbc8..e3c974a6c522 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -1472,7 +1472,7 @@ EXPORT_SYMBOL_GPL(tpm_dev_vendor_release);
1472 * Once all references to platform device are down to 0, 1472 * Once all references to platform device are down to 0,
1473 * release all allocated structures. 1473 * release all allocated structures.
1474 */ 1474 */
1475static void tpm_dev_release(struct device *dev) 1475void tpm_dev_release(struct device *dev)
1476{ 1476{
1477 struct tpm_chip *chip = dev_get_drvdata(dev); 1477 struct tpm_chip *chip = dev_get_drvdata(dev);
1478 1478
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 0770d1d79366..a7bfc176ed43 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -272,7 +272,6 @@ typedef union {
272 struct tpm_output_header out; 272 struct tpm_output_header out;
273} tpm_cmd_header; 273} tpm_cmd_header;
274 274
275#define TPM_DIGEST_SIZE 20
276struct tpm_pcrread_out { 275struct tpm_pcrread_out {
277 u8 pcr_result[TPM_DIGEST_SIZE]; 276 u8 pcr_result[TPM_DIGEST_SIZE];
278} __packed; 277} __packed;
@@ -333,6 +332,7 @@ extern struct tpm_chip* tpm_register_hardware(struct device *,
333 const struct tpm_vendor_specific *); 332 const struct tpm_vendor_specific *);
334extern int tpm_open(struct inode *, struct file *); 333extern int tpm_open(struct inode *, struct file *);
335extern int tpm_release(struct inode *, struct file *); 334extern int tpm_release(struct inode *, struct file *);
335extern void tpm_dev_release(struct device *dev);
336extern void tpm_dev_vendor_release(struct tpm_chip *); 336extern void tpm_dev_vendor_release(struct tpm_chip *);
337extern ssize_t tpm_write(struct file *, const char __user *, size_t, 337extern ssize_t tpm_write(struct file *, const char __user *, size_t,
338 loff_t *); 338 loff_t *);
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
index 37d5dcc10ea7..b8735de8ce95 100644
--- a/drivers/char/tpm/tpm_i2c_infineon.c
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -24,7 +24,6 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/wait.h> 27#include <linux/wait.h>
29#include "tpm.h" 28#include "tpm.h"
30 29
@@ -74,7 +73,6 @@ struct tpm_inf_dev {
74}; 73};
75 74
76static struct tpm_inf_dev tpm_dev; 75static struct tpm_inf_dev tpm_dev;
77static struct i2c_driver tpm_tis_i2c_driver;
78 76
79/* 77/*
80 * iic_tpm_read() - read from TPM register 78 * iic_tpm_read() - read from TPM register
@@ -744,11 +742,9 @@ static int tpm_tis_i2c_probe(struct i2c_client *client,
744 return -ENODEV; 742 return -ENODEV;
745 } 743 }
746 744
747 client->driver = &tpm_tis_i2c_driver;
748 tpm_dev.client = client; 745 tpm_dev.client = client;
749 rc = tpm_tis_i2c_init(&client->dev); 746 rc = tpm_tis_i2c_init(&client->dev);
750 if (rc != 0) { 747 if (rc != 0) {
751 client->driver = NULL;
752 tpm_dev.client = NULL; 748 tpm_dev.client = NULL;
753 rc = -ENODEV; 749 rc = -ENODEV;
754 } 750 }
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 8a41b6be23a0..4519cb332987 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -884,12 +884,19 @@ static int __init init_tis(void)
884 rc = platform_driver_register(&tis_drv); 884 rc = platform_driver_register(&tis_drv);
885 if (rc < 0) 885 if (rc < 0)
886 return rc; 886 return rc;
887 if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0))) 887 pdev = platform_device_register_simple("tpm_tis", -1, NULL, 0);
888 return PTR_ERR(pdev); 888 if (IS_ERR(pdev)) {
889 if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) { 889 rc = PTR_ERR(pdev);
890 platform_device_unregister(pdev); 890 goto err_dev;
891 platform_driver_unregister(&tis_drv);
892 } 891 }
892 rc = tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0);
893 if (rc)
894 goto err_init;
895 return 0;
896err_init:
897 platform_device_unregister(pdev);
898err_dev:
899 platform_driver_unregister(&tis_drv);
893 return rc; 900 return rc;
894} 901}
895 902
diff --git a/include/linux/security.h b/include/linux/security.h
index 4686491852a7..40560f41e3d5 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1392,7 +1392,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
1392 * @ctxlen contains the length of @ctx. 1392 * @ctxlen contains the length of @ctx.
1393 * 1393 *
1394 * @inode_getsecctx: 1394 * @inode_getsecctx:
1395 * Returns a string containing all relevant security context information 1395 * On success, returns 0 and fills out @ctx and @ctxlen with the security
1396 * context for the given @inode.
1396 * 1397 *
1397 * @inode we wish to get the security context of. 1398 * @inode we wish to get the security context of.
1398 * @ctx is a pointer in which to place the allocated security context. 1399 * @ctx is a pointer in which to place the allocated security context.
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index fcb627ff8d3e..9a9051bb1a03 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -22,6 +22,8 @@
22#ifndef __LINUX_TPM_H__ 22#ifndef __LINUX_TPM_H__
23#define __LINUX_TPM_H__ 23#define __LINUX_TPM_H__
24 24
25#define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */
26
25/* 27/*
26 * Chip num is this value or a valid tpm idx 28 * Chip num is this value or a valid tpm idx
27 */ 29 */
diff --git a/mm/shmem.c b/mm/shmem.c
index 118dfa4952f4..a87990cf9f94 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1936,6 +1936,13 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
1936 1936
1937 inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE); 1937 inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
1938 if (inode) { 1938 if (inode) {
1939#ifdef CONFIG_TMPFS_POSIX_ACL
1940 error = generic_acl_init(inode, dir);
1941 if (error) {
1942 iput(inode);
1943 return error;
1944 }
1945#endif
1939 error = security_inode_init_security(inode, dir, 1946 error = security_inode_init_security(inode, dir,
1940 &dentry->d_name, 1947 &dentry->d_name,
1941 shmem_initxattrs, NULL); 1948 shmem_initxattrs, NULL);
@@ -1945,15 +1952,8 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
1945 return error; 1952 return error;
1946 } 1953 }
1947 } 1954 }
1948#ifdef CONFIG_TMPFS_POSIX_ACL 1955
1949 error = generic_acl_init(inode, dir);
1950 if (error) {
1951 iput(inode);
1952 return error;
1953 }
1954#else
1955 error = 0; 1956 error = 0;
1956#endif
1957 dir->i_size += BOGO_DIRENT_SIZE; 1957 dir->i_size += BOGO_DIRENT_SIZE;
1958 dir->i_ctime = dir->i_mtime = CURRENT_TIME; 1958 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
1959 d_instantiate(dentry, inode); 1959 d_instantiate(dentry, inode);
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 3ae28db5a64f..031d2d9dd695 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -88,7 +88,7 @@ static const char *const aa_audit_type[] = {
88 "HINT", 88 "HINT",
89 "STATUS", 89 "STATUS",
90 "ERROR", 90 "ERROR",
91 "KILLED" 91 "KILLED",
92 "AUTO" 92 "AUTO"
93}; 93};
94 94
diff --git a/security/apparmor/context.c b/security/apparmor/context.c
index 8a9b5027c813..d5af1d15f26d 100644
--- a/security/apparmor/context.c
+++ b/security/apparmor/context.c
@@ -69,6 +69,23 @@ void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old)
69} 69}
70 70
71/** 71/**
72 * aa_get_task_profile - Get another task's profile
73 * @task: task to query (NOT NULL)
74 *
75 * Returns: counted reference to @task's profile
76 */
77struct aa_profile *aa_get_task_profile(struct task_struct *task)
78{
79 struct aa_profile *p;
80
81 rcu_read_lock();
82 p = aa_get_profile(__aa_task_profile(task));
83 rcu_read_unlock();
84
85 return p;
86}
87
88/**
72 * aa_replace_current_profile - replace the current tasks profiles 89 * aa_replace_current_profile - replace the current tasks profiles
73 * @profile: new profile (NOT NULL) 90 * @profile: new profile (NOT NULL)
74 * 91 *
@@ -76,7 +93,7 @@ void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old)
76 */ 93 */
77int aa_replace_current_profile(struct aa_profile *profile) 94int aa_replace_current_profile(struct aa_profile *profile)
78{ 95{
79 struct aa_task_cxt *cxt = current_cred()->security; 96 struct aa_task_cxt *cxt = current_cxt();
80 struct cred *new; 97 struct cred *new;
81 BUG_ON(!profile); 98 BUG_ON(!profile);
82 99
@@ -87,17 +104,13 @@ int aa_replace_current_profile(struct aa_profile *profile)
87 if (!new) 104 if (!new)
88 return -ENOMEM; 105 return -ENOMEM;
89 106
90 cxt = new->security; 107 cxt = cred_cxt(new);
91 if (unconfined(profile) || (cxt->profile->ns != profile->ns)) { 108 if (unconfined(profile) || (cxt->profile->ns != profile->ns))
92 /* if switching to unconfined or a different profile namespace 109 /* if switching to unconfined or a different profile namespace
93 * clear out context state 110 * clear out context state
94 */ 111 */
95 aa_put_profile(cxt->previous); 112 aa_clear_task_cxt_trans(cxt);
96 aa_put_profile(cxt->onexec); 113
97 cxt->previous = NULL;
98 cxt->onexec = NULL;
99 cxt->token = 0;
100 }
101 /* be careful switching cxt->profile, when racing replacement it 114 /* be careful switching cxt->profile, when racing replacement it
102 * is possible that cxt->profile->replacedby is the reference keeping 115 * is possible that cxt->profile->replacedby is the reference keeping
103 * @profile valid, so make sure to get its reference before dropping 116 * @profile valid, so make sure to get its reference before dropping
@@ -123,7 +136,7 @@ int aa_set_current_onexec(struct aa_profile *profile)
123 if (!new) 136 if (!new)
124 return -ENOMEM; 137 return -ENOMEM;
125 138
126 cxt = new->security; 139 cxt = cred_cxt(new);
127 aa_get_profile(profile); 140 aa_get_profile(profile);
128 aa_put_profile(cxt->onexec); 141 aa_put_profile(cxt->onexec);
129 cxt->onexec = profile; 142 cxt->onexec = profile;
@@ -150,7 +163,7 @@ int aa_set_current_hat(struct aa_profile *profile, u64 token)
150 return -ENOMEM; 163 return -ENOMEM;
151 BUG_ON(!profile); 164 BUG_ON(!profile);
152 165
153 cxt = new->security; 166 cxt = cred_cxt(new);
154 if (!cxt->previous) { 167 if (!cxt->previous) {
155 /* transfer refcount */ 168 /* transfer refcount */
156 cxt->previous = cxt->profile; 169 cxt->previous = cxt->profile;
@@ -187,7 +200,7 @@ int aa_restore_previous_profile(u64 token)
187 if (!new) 200 if (!new)
188 return -ENOMEM; 201 return -ENOMEM;
189 202
190 cxt = new->security; 203 cxt = cred_cxt(new);
191 if (cxt->token != token) { 204 if (cxt->token != token) {
192 abort_creds(new); 205 abort_creds(new);
193 return -EACCES; 206 return -EACCES;
@@ -205,11 +218,10 @@ int aa_restore_previous_profile(u64 token)
205 aa_get_profile(cxt->profile); 218 aa_get_profile(cxt->profile);
206 aa_put_profile(cxt->previous); 219 aa_put_profile(cxt->previous);
207 } 220 }
208 /* clear exec && prev information when restoring to previous context */ 221 /* ref has been transfered so avoid putting ref in clear_task_cxt */
209 cxt->previous = NULL; 222 cxt->previous = NULL;
210 cxt->token = 0; 223 /* clear exec && prev information when restoring to previous context */
211 aa_put_profile(cxt->onexec); 224 aa_clear_task_cxt_trans(cxt);
212 cxt->onexec = NULL;
213 225
214 commit_creds(new); 226 commit_creds(new);
215 return 0; 227 return 0;
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 859abdaac1ea..01b7bd669a88 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -62,17 +62,14 @@ static int may_change_ptraced_domain(struct task_struct *task,
62 struct aa_profile *to_profile) 62 struct aa_profile *to_profile)
63{ 63{
64 struct task_struct *tracer; 64 struct task_struct *tracer;
65 const struct cred *cred = NULL;
66 struct aa_profile *tracerp = NULL; 65 struct aa_profile *tracerp = NULL;
67 int error = 0; 66 int error = 0;
68 67
69 rcu_read_lock(); 68 rcu_read_lock();
70 tracer = ptrace_parent(task); 69 tracer = ptrace_parent(task);
71 if (tracer) { 70 if (tracer)
72 /* released below */ 71 /* released below */
73 cred = get_task_cred(tracer); 72 tracerp = aa_get_task_profile(tracer);
74 tracerp = aa_cred_profile(cred);
75 }
76 73
77 /* not ptraced */ 74 /* not ptraced */
78 if (!tracer || unconfined(tracerp)) 75 if (!tracer || unconfined(tracerp))
@@ -82,8 +79,7 @@ static int may_change_ptraced_domain(struct task_struct *task,
82 79
83out: 80out:
84 rcu_read_unlock(); 81 rcu_read_unlock();
85 if (cred) 82 aa_put_profile(tracerp);
86 put_cred(cred);
87 83
88 return error; 84 return error;
89} 85}
@@ -360,7 +356,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
360 if (bprm->cred_prepared) 356 if (bprm->cred_prepared)
361 return 0; 357 return 0;
362 358
363 cxt = bprm->cred->security; 359 cxt = cred_cxt(bprm->cred);
364 BUG_ON(!cxt); 360 BUG_ON(!cxt);
365 361
366 profile = aa_get_profile(aa_newest_version(cxt->profile)); 362 profile = aa_get_profile(aa_newest_version(cxt->profile));
@@ -443,6 +439,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
443 } else { 439 } else {
444 error = -ENOENT; 440 error = -ENOENT;
445 info = "profile not found"; 441 info = "profile not found";
442 /* remove MAY_EXEC to audit as failure */
443 perms.allow &= ~MAY_EXEC;
446 } 444 }
447 } 445 }
448 } else if (COMPLAIN_MODE(profile)) { 446 } else if (COMPLAIN_MODE(profile)) {
@@ -514,11 +512,7 @@ x_clear:
514 cxt->profile = new_profile; 512 cxt->profile = new_profile;
515 513
516 /* clear out all temporary/transitional state from the context */ 514 /* clear out all temporary/transitional state from the context */
517 aa_put_profile(cxt->previous); 515 aa_clear_task_cxt_trans(cxt);
518 aa_put_profile(cxt->onexec);
519 cxt->previous = NULL;
520 cxt->onexec = NULL;
521 cxt->token = 0;
522 516
523audit: 517audit:
524 error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC, 518 error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC,
@@ -557,7 +551,7 @@ int apparmor_bprm_secureexec(struct linux_binprm *bprm)
557void apparmor_bprm_committing_creds(struct linux_binprm *bprm) 551void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
558{ 552{
559 struct aa_profile *profile = __aa_current_profile(); 553 struct aa_profile *profile = __aa_current_profile();
560 struct aa_task_cxt *new_cxt = bprm->cred->security; 554 struct aa_task_cxt *new_cxt = cred_cxt(bprm->cred);
561 555
562 /* bail out if unconfined or not changing profile */ 556 /* bail out if unconfined or not changing profile */
563 if ((new_cxt->profile == profile) || 557 if ((new_cxt->profile == profile) ||
@@ -634,7 +628,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
634 628
635 /* released below */ 629 /* released below */
636 cred = get_current_cred(); 630 cred = get_current_cred();
637 cxt = cred->security; 631 cxt = cred_cxt(cred);
638 profile = aa_cred_profile(cred); 632 profile = aa_cred_profile(cred);
639 previous_profile = cxt->previous; 633 previous_profile = cxt->previous;
640 634
@@ -750,7 +744,6 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
750 bool permtest) 744 bool permtest)
751{ 745{
752 const struct cred *cred; 746 const struct cred *cred;
753 struct aa_task_cxt *cxt;
754 struct aa_profile *profile, *target = NULL; 747 struct aa_profile *profile, *target = NULL;
755 struct aa_namespace *ns = NULL; 748 struct aa_namespace *ns = NULL;
756 struct file_perms perms = {}; 749 struct file_perms perms = {};
@@ -770,7 +763,6 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
770 } 763 }
771 764
772 cred = get_current_cred(); 765 cred = get_current_cred();
773 cxt = cred->security;
774 profile = aa_cred_profile(cred); 766 profile = aa_cred_profile(cred);
775 767
776 /* 768 /*
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
index 40aedd9f73ea..1ba2ca56a6ef 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -15,6 +15,7 @@
15#ifndef __APPARMOR_H 15#ifndef __APPARMOR_H
16#define __APPARMOR_H 16#define __APPARMOR_H
17 17
18#include <linux/slab.h>
18#include <linux/fs.h> 19#include <linux/fs.h>
19 20
20#include "match.h" 21#include "match.h"
@@ -64,9 +65,18 @@ extern int apparmor_initialized __initdata;
64/* fn's in lib */ 65/* fn's in lib */
65char *aa_split_fqname(char *args, char **ns_name); 66char *aa_split_fqname(char *args, char **ns_name);
66void aa_info_message(const char *str); 67void aa_info_message(const char *str);
67void *kvmalloc(size_t size); 68void *__aa_kvmalloc(size_t size, gfp_t flags);
68void kvfree(void *buffer); 69void kvfree(void *buffer);
69 70
71static inline void *kvmalloc(size_t size)
72{
73 return __aa_kvmalloc(size, 0);
74}
75
76static inline void *kvzalloc(size_t size)
77{
78 return __aa_kvmalloc(size, __GFP_ZERO);
79}
70 80
71/** 81/**
72 * aa_strneq - compare null terminated @str to a non null terminated substring 82 * aa_strneq - compare null terminated @str to a non null terminated substring
diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h
index a9cbee4d9e48..d44ba5802e3d 100644
--- a/security/apparmor/include/context.h
+++ b/security/apparmor/include/context.h
@@ -21,6 +21,9 @@
21 21
22#include "policy.h" 22#include "policy.h"
23 23
24#define cred_cxt(X) (X)->security
25#define current_cxt() cred_cxt(current_cred())
26
24/* struct aa_file_cxt - the AppArmor context the file was opened in 27/* struct aa_file_cxt - the AppArmor context the file was opened in
25 * @perms: the permission the file was opened with 28 * @perms: the permission the file was opened with
26 * 29 *
@@ -80,23 +83,8 @@ int aa_replace_current_profile(struct aa_profile *profile);
80int aa_set_current_onexec(struct aa_profile *profile); 83int aa_set_current_onexec(struct aa_profile *profile);
81int aa_set_current_hat(struct aa_profile *profile, u64 token); 84int aa_set_current_hat(struct aa_profile *profile, u64 token);
82int aa_restore_previous_profile(u64 cookie); 85int aa_restore_previous_profile(u64 cookie);
86struct aa_profile *aa_get_task_profile(struct task_struct *task);
83 87
84/**
85 * __aa_task_is_confined - determine if @task has any confinement
86 * @task: task to check confinement of (NOT NULL)
87 *
88 * If @task != current needs to be called in RCU safe critical section
89 */
90static inline bool __aa_task_is_confined(struct task_struct *task)
91{
92 struct aa_task_cxt *cxt = __task_cred(task)->security;
93
94 BUG_ON(!cxt || !cxt->profile);
95 if (unconfined(aa_newest_version(cxt->profile)))
96 return 0;
97
98 return 1;
99}
100 88
101/** 89/**
102 * aa_cred_profile - obtain cred's profiles 90 * aa_cred_profile - obtain cred's profiles
@@ -108,12 +96,36 @@ static inline bool __aa_task_is_confined(struct task_struct *task)
108 */ 96 */
109static inline struct aa_profile *aa_cred_profile(const struct cred *cred) 97static inline struct aa_profile *aa_cred_profile(const struct cred *cred)
110{ 98{
111 struct aa_task_cxt *cxt = cred->security; 99 struct aa_task_cxt *cxt = cred_cxt(cred);
112 BUG_ON(!cxt || !cxt->profile); 100 BUG_ON(!cxt || !cxt->profile);
113 return aa_newest_version(cxt->profile); 101 return aa_newest_version(cxt->profile);
114} 102}
115 103
116/** 104/**
105 * __aa_task_profile - retrieve another task's profile
106 * @task: task to query (NOT NULL)
107 *
108 * Returns: @task's profile without incrementing its ref count
109 *
110 * If @task != current needs to be called in RCU safe critical section
111 */
112static inline struct aa_profile *__aa_task_profile(struct task_struct *task)
113{
114 return aa_cred_profile(__task_cred(task));
115}
116
117/**
118 * __aa_task_is_confined - determine if @task has any confinement
119 * @task: task to check confinement of (NOT NULL)
120 *
121 * If @task != current needs to be called in RCU safe critical section
122 */
123static inline bool __aa_task_is_confined(struct task_struct *task)
124{
125 return !unconfined(__aa_task_profile(task));
126}
127
128/**
117 * __aa_current_profile - find the current tasks confining profile 129 * __aa_current_profile - find the current tasks confining profile
118 * 130 *
119 * Returns: up to date confining profile or the ns unconfined profile (NOT NULL) 131 * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
@@ -136,7 +148,7 @@ static inline struct aa_profile *__aa_current_profile(void)
136 */ 148 */
137static inline struct aa_profile *aa_current_profile(void) 149static inline struct aa_profile *aa_current_profile(void)
138{ 150{
139 const struct aa_task_cxt *cxt = current_cred()->security; 151 const struct aa_task_cxt *cxt = current_cxt();
140 struct aa_profile *profile; 152 struct aa_profile *profile;
141 BUG_ON(!cxt || !cxt->profile); 153 BUG_ON(!cxt || !cxt->profile);
142 154
@@ -151,4 +163,17 @@ static inline struct aa_profile *aa_current_profile(void)
151 return profile; 163 return profile;
152} 164}
153 165
166/**
167 * aa_clear_task_cxt_trans - clear transition tracking info from the cxt
168 * @cxt: task context to clear (NOT NULL)
169 */
170static inline void aa_clear_task_cxt_trans(struct aa_task_cxt *cxt)
171{
172 aa_put_profile(cxt->previous);
173 aa_put_profile(cxt->onexec);
174 cxt->previous = NULL;
175 cxt->onexec = NULL;
176 cxt->token = 0;
177}
178
154#endif /* __AA_CONTEXT_H */ 179#endif /* __AA_CONTEXT_H */
diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
index 967b2deda376..2c922b86bd44 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -186,11 +186,6 @@ static inline void aa_free_file_rules(struct aa_file_rules *rules)
186 aa_free_domain_entries(&rules->trans); 186 aa_free_domain_entries(&rules->trans);
187} 187}
188 188
189#define ACC_FMODE(x) (("\000\004\002\006"[(x)&O_ACCMODE]) | (((x) << 1) & 0x40))
190
191/* from namei.c */
192#define MAP_OPEN_FLAGS(x) ((((x) + 1) & O_ACCMODE) ? (x) + 1 : (x))
193
194/** 189/**
195 * aa_map_file_perms - map file flags to AppArmor permissions 190 * aa_map_file_perms - map file flags to AppArmor permissions
196 * @file: open file to map flags to AppArmor permissions 191 * @file: open file to map flags to AppArmor permissions
@@ -199,8 +194,13 @@ static inline void aa_free_file_rules(struct aa_file_rules *rules)
199 */ 194 */
200static inline u32 aa_map_file_to_perms(struct file *file) 195static inline u32 aa_map_file_to_perms(struct file *file)
201{ 196{
202 int flags = MAP_OPEN_FLAGS(file->f_flags); 197 int flags = file->f_flags;
203 u32 perms = ACC_FMODE(file->f_mode); 198 u32 perms = 0;
199
200 if (file->f_mode & FMODE_WRITE)
201 perms |= MAY_WRITE;
202 if (file->f_mode & FMODE_READ)
203 perms |= MAY_READ;
204 204
205 if ((flags & O_APPEND) && (perms & MAY_WRITE)) 205 if ((flags & O_APPEND) && (perms & MAY_WRITE))
206 perms = (perms & ~MAY_WRITE) | MAY_APPEND; 206 perms = (perms & ~MAY_WRITE) | MAY_APPEND;
diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
index 775843e7f984..001c43aa0406 100644
--- a/security/apparmor/include/match.h
+++ b/security/apparmor/include/match.h
@@ -4,7 +4,7 @@
4 * This file contains AppArmor policy dfa matching engine definitions. 4 * This file contains AppArmor policy dfa matching engine definitions.
5 * 5 *
6 * Copyright (C) 1998-2008 Novell/SUSE 6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2010 Canonical Ltd. 7 * Copyright 2009-2012 Canonical Ltd.
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as 10 * modify it under the terms of the GNU General Public License as
@@ -16,25 +16,30 @@
16#define __AA_MATCH_H 16#define __AA_MATCH_H
17 17
18#include <linux/kref.h> 18#include <linux/kref.h>
19#include <linux/workqueue.h>
20 19
21#define DFA_NOMATCH 0 20#define DFA_NOMATCH 0
22#define DFA_START 1 21#define DFA_START 1
23 22
24#define DFA_VALID_PERM_MASK 0xffffffff
25#define DFA_VALID_PERM2_MASK 0xffffffff
26 23
27/** 24/**
28 * The format used for transition tables is based on the GNU flex table 25 * The format used for transition tables is based on the GNU flex table
29 * file format (--tables-file option; see Table File Format in the flex 26 * file format (--tables-file option; see Table File Format in the flex
30 * info pages and the flex sources for documentation). The magic number 27 * info pages and the flex sources for documentation). The magic number
31 * used in the header is 0x1B5E783D instead of 0xF13C57B1 though, because 28 * used in the header is 0x1B5E783D instead of 0xF13C57B1 though, because
32 * the YY_ID_CHK (check) and YY_ID_DEF (default) tables are used 29 * new tables have been defined and others YY_ID_CHK (check) and YY_ID_DEF
33 * slightly differently (see the apparmor-parser package). 30 * (default) tables are used slightly differently (see the apparmor-parser
31 * package).
32 *
33 *
34 * The data in the packed dfa is stored in network byte order, and the tables
35 * are arranged for flexibility. We convert the table data to host native
36 * byte order.
37 *
38 * The dfa begins with a table set header, and is followed by the actual
39 * tables.
34 */ 40 */
35 41
36#define YYTH_MAGIC 0x1B5E783D 42#define YYTH_MAGIC 0x1B5E783D
37#define YYTH_DEF_RECURSE 0x1 /* DEF Table is recursive */
38 43
39struct table_set_header { 44struct table_set_header {
40 u32 th_magic; /* YYTH_MAGIC */ 45 u32 th_magic; /* YYTH_MAGIC */
@@ -63,7 +68,7 @@ struct table_set_header {
63#define YYTD_DATA32 4 68#define YYTD_DATA32 4
64#define YYTD_DATA64 8 69#define YYTD_DATA64 8
65 70
66/* Each ACCEPT2 table gets 6 dedicated flags, YYTD_DATAX define the 71/* ACCEPT & ACCEPT2 tables gets 6 dedicated flags, YYTD_DATAX define the
67 * first flags 72 * first flags
68 */ 73 */
69#define ACCEPT1_FLAGS(X) ((X) & 0x3f) 74#define ACCEPT1_FLAGS(X) ((X) & 0x3f)
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index bda4569fdd83..b25491a3046a 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -32,13 +32,13 @@
32extern const char *const profile_mode_names[]; 32extern const char *const profile_mode_names[];
33#define APPARMOR_NAMES_MAX_INDEX 3 33#define APPARMOR_NAMES_MAX_INDEX 3
34 34
35#define COMPLAIN_MODE(_profile) \ 35#define PROFILE_MODE(_profile, _mode) \
36 ((aa_g_profile_mode == APPARMOR_COMPLAIN) || \ 36 ((aa_g_profile_mode == (_mode)) || \
37 ((_profile)->mode == APPARMOR_COMPLAIN)) 37 ((_profile)->mode == (_mode)))
38 38
39#define KILL_MODE(_profile) \ 39#define COMPLAIN_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_COMPLAIN)
40 ((aa_g_profile_mode == APPARMOR_KILL) || \ 40
41 ((_profile)->mode == APPARMOR_KILL)) 41#define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL)
42 42
43#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT) 43#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT)
44 44
@@ -105,6 +105,7 @@ struct aa_ns_acct {
105 * @acct: accounting for the namespace 105 * @acct: accounting for the namespace
106 * @unconfined: special unconfined profile for the namespace 106 * @unconfined: special unconfined profile for the namespace
107 * @sub_ns: list of namespaces under the current namespace. 107 * @sub_ns: list of namespaces under the current namespace.
108 * @uniq_null: uniq value used for null learning profiles
108 * 109 *
109 * An aa_namespace defines the set profiles that are searched to determine 110 * An aa_namespace defines the set profiles that are searched to determine
110 * which profile to attach to a task. Profiles can not be shared between 111 * which profile to attach to a task. Profiles can not be shared between
@@ -127,6 +128,7 @@ struct aa_namespace {
127 struct aa_ns_acct acct; 128 struct aa_ns_acct acct;
128 struct aa_profile *unconfined; 129 struct aa_profile *unconfined;
129 struct list_head sub_ns; 130 struct list_head sub_ns;
131 atomic_t uniq_null;
130}; 132};
131 133
132/* struct aa_policydb - match engine for a policy 134/* struct aa_policydb - match engine for a policy
@@ -148,7 +150,6 @@ struct aa_policydb {
148 * @rename: optional profile name that this profile renamed 150 * @rename: optional profile name that this profile renamed
149 * @xmatch: optional extended matching for unconfined executables names 151 * @xmatch: optional extended matching for unconfined executables names
150 * @xmatch_len: xmatch prefix len, used to determine xmatch priority 152 * @xmatch_len: xmatch prefix len, used to determine xmatch priority
151 * @sid: the unique security id number of this profile
152 * @audit: the auditing mode of the profile 153 * @audit: the auditing mode of the profile
153 * @mode: the enforcement mode of the profile 154 * @mode: the enforcement mode of the profile
154 * @flags: flags controlling profile behavior 155 * @flags: flags controlling profile behavior
@@ -184,7 +185,6 @@ struct aa_profile {
184 185
185 struct aa_dfa *xmatch; 186 struct aa_dfa *xmatch;
186 int xmatch_len; 187 int xmatch_len;
187 u32 sid;
188 enum audit_mode audit; 188 enum audit_mode audit;
189 enum profile_mode mode; 189 enum profile_mode mode;
190 u32 flags; 190 u32 flags;
diff --git a/security/apparmor/include/procattr.h b/security/apparmor/include/procattr.h
index 544aa6b766a4..6bd5f33d9533 100644
--- a/security/apparmor/include/procattr.h
+++ b/security/apparmor/include/procattr.h
@@ -21,6 +21,5 @@
21int aa_getprocattr(struct aa_profile *profile, char **string); 21int aa_getprocattr(struct aa_profile *profile, char **string);
22int aa_setprocattr_changehat(char *args, size_t size, int test); 22int aa_setprocattr_changehat(char *args, size_t size, int test);
23int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test); 23int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test);
24int aa_setprocattr_permipc(char *fqname);
25 24
26#endif /* __AA_PROCATTR_H */ 25#endif /* __AA_PROCATTR_H */
diff --git a/security/apparmor/include/sid.h b/security/apparmor/include/sid.h
index 020db35c3010..513ca0e48965 100644
--- a/security/apparmor/include/sid.h
+++ b/security/apparmor/include/sid.h
@@ -16,7 +16,9 @@
16 16
17#include <linux/types.h> 17#include <linux/types.h>
18 18
19struct aa_profile; 19/* sid value that will not be allocated */
20#define AA_SID_INVALID 0
21#define AA_SID_ALLOC AA_SID_INVALID
20 22
21u32 aa_alloc_sid(void); 23u32 aa_alloc_sid(void);
22void aa_free_sid(u32 sid); 24void aa_free_sid(u32 sid);
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
index cf1071b14232..c51d2266587e 100644
--- a/security/apparmor/ipc.c
+++ b/security/apparmor/ipc.c
@@ -95,23 +95,18 @@ int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
95 * - tracer profile has CAP_SYS_PTRACE 95 * - tracer profile has CAP_SYS_PTRACE
96 */ 96 */
97 97
98 struct aa_profile *tracer_p; 98 struct aa_profile *tracer_p = aa_get_task_profile(tracer);
99 /* cred released below */
100 const struct cred *cred = get_task_cred(tracer);
101 int error = 0; 99 int error = 0;
102 tracer_p = aa_cred_profile(cred);
103 100
104 if (!unconfined(tracer_p)) { 101 if (!unconfined(tracer_p)) {
105 /* lcred released below */ 102 struct aa_profile *tracee_p = aa_get_task_profile(tracee);
106 const struct cred *lcred = get_task_cred(tracee);
107 struct aa_profile *tracee_p = aa_cred_profile(lcred);
108 103
109 error = aa_may_ptrace(tracer, tracer_p, tracee_p, mode); 104 error = aa_may_ptrace(tracer, tracer_p, tracee_p, mode);
110 error = aa_audit_ptrace(tracer_p, tracee_p, error); 105 error = aa_audit_ptrace(tracer_p, tracee_p, error);
111 106
112 put_cred(lcred); 107 aa_put_profile(tracee_p);
113 } 108 }
114 put_cred(cred); 109 aa_put_profile(tracer_p);
115 110
116 return error; 111 return error;
117} 112}
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index 7430298116d6..fcfe0233574c 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -45,8 +45,10 @@ char *aa_split_fqname(char *fqname, char **ns_name)
45 *ns_name = skip_spaces(&name[1]); 45 *ns_name = skip_spaces(&name[1]);
46 if (split) { 46 if (split) {
47 /* overwrite ':' with \0 */ 47 /* overwrite ':' with \0 */
48 *split = 0; 48 *split++ = 0;
49 name = skip_spaces(split + 1); 49 if (strncmp(split, "//", 2) == 0)
50 split += 2;
51 name = skip_spaces(split);
50 } else 52 } else
51 /* a ns name without a following profile is allowed */ 53 /* a ns name without a following profile is allowed */
52 name = NULL; 54 name = NULL;
@@ -75,15 +77,16 @@ void aa_info_message(const char *str)
75} 77}
76 78
77/** 79/**
78 * kvmalloc - do allocation preferring kmalloc but falling back to vmalloc 80 * __aa_kvmalloc - do allocation preferring kmalloc but falling back to vmalloc
79 * @size: size of allocation 81 * @size: how many bytes of memory are required
82 * @flags: the type of memory to allocate (see kmalloc).
80 * 83 *
81 * Return: allocated buffer or NULL if failed 84 * Return: allocated buffer or NULL if failed
82 * 85 *
83 * It is possible that policy being loaded from the user is larger than 86 * It is possible that policy being loaded from the user is larger than
84 * what can be allocated by kmalloc, in those cases fall back to vmalloc. 87 * what can be allocated by kmalloc, in those cases fall back to vmalloc.
85 */ 88 */
86void *kvmalloc(size_t size) 89void *__aa_kvmalloc(size_t size, gfp_t flags)
87{ 90{
88 void *buffer = NULL; 91 void *buffer = NULL;
89 92
@@ -92,32 +95,22 @@ void *kvmalloc(size_t size)
92 95
93 /* do not attempt kmalloc if we need more than 16 pages at once */ 96 /* do not attempt kmalloc if we need more than 16 pages at once */
94 if (size <= (16*PAGE_SIZE)) 97 if (size <= (16*PAGE_SIZE))
95 buffer = kmalloc(size, GFP_NOIO | __GFP_NOWARN); 98 buffer = kmalloc(size, flags | GFP_NOIO | __GFP_NOWARN);
96 if (!buffer) { 99 if (!buffer) {
97 /* see kvfree for why size must be at least work_struct size 100 /* see kvfree for why size must be at least work_struct size
98 * when allocated via vmalloc 101 * when allocated via vmalloc
99 */ 102 */
100 if (size < sizeof(struct work_struct)) 103 if (size < sizeof(struct work_struct))
101 size = sizeof(struct work_struct); 104 size = sizeof(struct work_struct);
102 buffer = vmalloc(size); 105 if (flags & __GFP_ZERO)
106 buffer = vzalloc(size);
107 else
108 buffer = vmalloc(size);
103 } 109 }
104 return buffer; 110 return buffer;
105} 111}
106 112
107/** 113/**
108 * do_vfree - workqueue routine for freeing vmalloced memory
109 * @work: data to be freed
110 *
111 * The work_struct is overlaid to the data being freed, as at the point
112 * the work is scheduled the data is no longer valid, be its freeing
113 * needs to be delayed until safe.
114 */
115static void do_vfree(struct work_struct *work)
116{
117 vfree(work);
118}
119
120/**
121 * kvfree - free an allocation do by kvmalloc 114 * kvfree - free an allocation do by kvmalloc
122 * @buffer: buffer to free (MAYBE_NULL) 115 * @buffer: buffer to free (MAYBE_NULL)
123 * 116 *
@@ -125,13 +118,8 @@ static void do_vfree(struct work_struct *work)
125 */ 118 */
126void kvfree(void *buffer) 119void kvfree(void *buffer)
127{ 120{
128 if (is_vmalloc_addr(buffer)) { 121 if (is_vmalloc_addr(buffer))
129 /* Data is no longer valid so just use the allocated space 122 vfree(buffer);
130 * as the work_struct 123 else
131 */
132 struct work_struct *work = (struct work_struct *) buffer;
133 INIT_WORK(work, do_vfree);
134 schedule_work(work);
135 } else
136 kfree(buffer); 124 kfree(buffer);
137} 125}
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index b21830eced41..2e2a0dd4a73f 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -48,8 +48,8 @@ int apparmor_initialized __initdata;
48 */ 48 */
49static void apparmor_cred_free(struct cred *cred) 49static void apparmor_cred_free(struct cred *cred)
50{ 50{
51 aa_free_task_context(cred->security); 51 aa_free_task_context(cred_cxt(cred));
52 cred->security = NULL; 52 cred_cxt(cred) = NULL;
53} 53}
54 54
55/* 55/*
@@ -62,7 +62,7 @@ static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp)
62 if (!cxt) 62 if (!cxt)
63 return -ENOMEM; 63 return -ENOMEM;
64 64
65 cred->security = cxt; 65 cred_cxt(cred) = cxt;
66 return 0; 66 return 0;
67} 67}
68 68
@@ -77,8 +77,8 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
77 if (!cxt) 77 if (!cxt)
78 return -ENOMEM; 78 return -ENOMEM;
79 79
80 aa_dup_task_context(cxt, old->security); 80 aa_dup_task_context(cxt, cred_cxt(old));
81 new->security = cxt; 81 cred_cxt(new) = cxt;
82 return 0; 82 return 0;
83} 83}
84 84
@@ -87,8 +87,8 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
87 */ 87 */
88static void apparmor_cred_transfer(struct cred *new, const struct cred *old) 88static void apparmor_cred_transfer(struct cred *new, const struct cred *old)
89{ 89{
90 const struct aa_task_cxt *old_cxt = old->security; 90 const struct aa_task_cxt *old_cxt = cred_cxt(old);
91 struct aa_task_cxt *new_cxt = new->security; 91 struct aa_task_cxt *new_cxt = cred_cxt(new);
92 92
93 aa_dup_task_context(new_cxt, old_cxt); 93 aa_dup_task_context(new_cxt, old_cxt);
94} 94}
@@ -469,7 +469,6 @@ static int apparmor_file_lock(struct file *file, unsigned int cmd)
469static int common_mmap(int op, struct file *file, unsigned long prot, 469static int common_mmap(int op, struct file *file, unsigned long prot,
470 unsigned long flags) 470 unsigned long flags)
471{ 471{
472 struct dentry *dentry;
473 int mask = 0; 472 int mask = 0;
474 473
475 if (!file || !file->f_security) 474 if (!file || !file->f_security)
@@ -486,7 +485,6 @@ static int common_mmap(int op, struct file *file, unsigned long prot,
486 if (prot & PROT_EXEC) 485 if (prot & PROT_EXEC)
487 mask |= AA_EXEC_MMAP; 486 mask |= AA_EXEC_MMAP;
488 487
489 dentry = file->f_path.dentry;
490 return common_file_perm(op, file, mask); 488 return common_file_perm(op, file, mask);
491} 489}
492 490
@@ -507,11 +505,9 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,
507 char **value) 505 char **value)
508{ 506{
509 int error = -ENOENT; 507 int error = -ENOENT;
510 struct aa_profile *profile;
511 /* released below */ 508 /* released below */
512 const struct cred *cred = get_task_cred(task); 509 const struct cred *cred = get_task_cred(task);
513 struct aa_task_cxt *cxt = cred->security; 510 struct aa_task_cxt *cxt = cred_cxt(cred);
514 profile = aa_cred_profile(cred);
515 511
516 if (strcmp(name, "current") == 0) 512 if (strcmp(name, "current") == 0)
517 error = aa_getprocattr(aa_newest_version(cxt->profile), 513 error = aa_getprocattr(aa_newest_version(cxt->profile),
@@ -533,6 +529,8 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,
533static int apparmor_setprocattr(struct task_struct *task, char *name, 529static int apparmor_setprocattr(struct task_struct *task, char *name,
534 void *value, size_t size) 530 void *value, size_t size)
535{ 531{
532 struct common_audit_data sa;
533 struct apparmor_audit_data aad = {0,};
536 char *command, *args = value; 534 char *command, *args = value;
537 size_t arg_size; 535 size_t arg_size;
538 int error; 536 int error;
@@ -576,30 +574,31 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
576 } else if (strcmp(command, "permprofile") == 0) { 574 } else if (strcmp(command, "permprofile") == 0) {
577 error = aa_setprocattr_changeprofile(args, !AA_ONEXEC, 575 error = aa_setprocattr_changeprofile(args, !AA_ONEXEC,
578 AA_DO_TEST); 576 AA_DO_TEST);
579 } else if (strcmp(command, "permipc") == 0) { 577 } else
580 error = aa_setprocattr_permipc(args); 578 goto fail;
581 } else {
582 struct common_audit_data sa;
583 struct apparmor_audit_data aad = {0,};
584 sa.type = LSM_AUDIT_DATA_NONE;
585 sa.aad = &aad;
586 aad.op = OP_SETPROCATTR;
587 aad.info = name;
588 aad.error = -EINVAL;
589 return aa_audit(AUDIT_APPARMOR_DENIED,
590 __aa_current_profile(), GFP_KERNEL,
591 &sa, NULL);
592 }
593 } else if (strcmp(name, "exec") == 0) { 579 } else if (strcmp(name, "exec") == 0) {
594 error = aa_setprocattr_changeprofile(args, AA_ONEXEC, 580 if (strcmp(command, "exec") == 0)
595 !AA_DO_TEST); 581 error = aa_setprocattr_changeprofile(args, AA_ONEXEC,
596 } else { 582 !AA_DO_TEST);
583 else
584 goto fail;
585 } else
597 /* only support the "current" and "exec" process attributes */ 586 /* only support the "current" and "exec" process attributes */
598 return -EINVAL; 587 return -EINVAL;
599 } 588
600 if (!error) 589 if (!error)
601 error = size; 590 error = size;
602 return error; 591 return error;
592
593fail:
594 sa.type = LSM_AUDIT_DATA_NONE;
595 sa.aad = &aad;
596 aad.profile = aa_current_profile();
597 aad.op = OP_SETPROCATTR;
598 aad.info = name;
599 aad.error = -EINVAL;
600 aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
601 return -EINVAL;
603} 602}
604 603
605static int apparmor_task_setrlimit(struct task_struct *task, 604static int apparmor_task_setrlimit(struct task_struct *task,
@@ -886,7 +885,7 @@ static int __init set_init_cxt(void)
886 return -ENOMEM; 885 return -ENOMEM;
887 886
888 cxt->profile = aa_get_profile(root_ns->unconfined); 887 cxt->profile = aa_get_profile(root_ns->unconfined);
889 cred->security = cxt; 888 cred_cxt(cred) = cxt;
890 889
891 return 0; 890 return 0;
892} 891}
@@ -915,8 +914,11 @@ static int __init apparmor_init(void)
915 914
916 error = register_security(&apparmor_ops); 915 error = register_security(&apparmor_ops);
917 if (error) { 916 if (error) {
917 struct cred *cred = (struct cred *)current->real_cred;
918 aa_free_task_context(cred_cxt(cred));
919 cred_cxt(cred) = NULL;
918 AA_ERROR("Unable to register AppArmor\n"); 920 AA_ERROR("Unable to register AppArmor\n");
919 goto set_init_cxt_out; 921 goto register_security_out;
920 } 922 }
921 923
922 /* Report that AppArmor successfully initialized */ 924 /* Report that AppArmor successfully initialized */
@@ -930,9 +932,6 @@ static int __init apparmor_init(void)
930 932
931 return error; 933 return error;
932 934
933set_init_cxt_out:
934 aa_free_task_context(current->real_cred->security);
935
936register_security_out: 935register_security_out:
937 aa_free_root_ns(); 936 aa_free_root_ns();
938 937
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index 90971a8c3789..727eb4200d5c 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -4,7 +4,7 @@
4 * This file contains AppArmor dfa based regular expression matching engine 4 * This file contains AppArmor dfa based regular expression matching engine
5 * 5 *
6 * Copyright (C) 1998-2008 Novell/SUSE 6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2010 Canonical Ltd. 7 * Copyright 2009-2012 Canonical Ltd.
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as 10 * modify it under the terms of the GNU General Public License as
@@ -23,6 +23,8 @@
23#include "include/apparmor.h" 23#include "include/apparmor.h"
24#include "include/match.h" 24#include "include/match.h"
25 25
26#define base_idx(X) ((X) & 0xffffff)
27
26/** 28/**
27 * unpack_table - unpack a dfa table (one of accept, default, base, next check) 29 * unpack_table - unpack a dfa table (one of accept, default, base, next check)
28 * @blob: data to unpack (NOT NULL) 30 * @blob: data to unpack (NOT NULL)
@@ -30,7 +32,7 @@
30 * 32 *
31 * Returns: pointer to table else NULL on failure 33 * Returns: pointer to table else NULL on failure
32 * 34 *
33 * NOTE: must be freed by kvfree (not kmalloc) 35 * NOTE: must be freed by kvfree (not kfree)
34 */ 36 */
35static struct table_header *unpack_table(char *blob, size_t bsize) 37static struct table_header *unpack_table(char *blob, size_t bsize)
36{ 38{
@@ -57,7 +59,7 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
57 if (bsize < tsize) 59 if (bsize < tsize)
58 goto out; 60 goto out;
59 61
60 table = kvmalloc(tsize); 62 table = kvzalloc(tsize);
61 if (table) { 63 if (table) {
62 *table = th; 64 *table = th;
63 if (th.td_flags == YYTD_DATA8) 65 if (th.td_flags == YYTD_DATA8)
@@ -137,8 +139,7 @@ static int verify_dfa(struct aa_dfa *dfa, int flags)
137 for (i = 0; i < state_count; i++) { 139 for (i = 0; i < state_count; i++) {
138 if (DEFAULT_TABLE(dfa)[i] >= state_count) 140 if (DEFAULT_TABLE(dfa)[i] >= state_count)
139 goto out; 141 goto out;
140 /* TODO: do check that DEF state recursion terminates */ 142 if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) {
141 if (BASE_TABLE(dfa)[i] + 255 >= trans_count) {
142 printk(KERN_ERR "AppArmor DFA next/check upper " 143 printk(KERN_ERR "AppArmor DFA next/check upper "
143 "bounds error\n"); 144 "bounds error\n");
144 goto out; 145 goto out;
@@ -314,7 +315,7 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
314 u8 *equiv = EQUIV_TABLE(dfa); 315 u8 *equiv = EQUIV_TABLE(dfa);
315 /* default is direct to next state */ 316 /* default is direct to next state */
316 for (; len; len--) { 317 for (; len; len--) {
317 pos = base[state] + equiv[(u8) *str++]; 318 pos = base_idx(base[state]) + equiv[(u8) *str++];
318 if (check[pos] == state) 319 if (check[pos] == state)
319 state = next[pos]; 320 state = next[pos];
320 else 321 else
@@ -323,7 +324,7 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
323 } else { 324 } else {
324 /* default is direct to next state */ 325 /* default is direct to next state */
325 for (; len; len--) { 326 for (; len; len--) {
326 pos = base[state] + (u8) *str++; 327 pos = base_idx(base[state]) + (u8) *str++;
327 if (check[pos] == state) 328 if (check[pos] == state)
328 state = next[pos]; 329 state = next[pos];
329 else 330 else
@@ -364,7 +365,7 @@ unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
364 u8 *equiv = EQUIV_TABLE(dfa); 365 u8 *equiv = EQUIV_TABLE(dfa);
365 /* default is direct to next state */ 366 /* default is direct to next state */
366 while (*str) { 367 while (*str) {
367 pos = base[state] + equiv[(u8) *str++]; 368 pos = base_idx(base[state]) + equiv[(u8) *str++];
368 if (check[pos] == state) 369 if (check[pos] == state)
369 state = next[pos]; 370 state = next[pos];
370 else 371 else
@@ -373,7 +374,7 @@ unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
373 } else { 374 } else {
374 /* default is direct to next state */ 375 /* default is direct to next state */
375 while (*str) { 376 while (*str) {
376 pos = base[state] + (u8) *str++; 377 pos = base_idx(base[state]) + (u8) *str++;
377 if (check[pos] == state) 378 if (check[pos] == state)
378 state = next[pos]; 379 state = next[pos];
379 else 380 else
@@ -409,14 +410,14 @@ unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
409 u8 *equiv = EQUIV_TABLE(dfa); 410 u8 *equiv = EQUIV_TABLE(dfa);
410 /* default is direct to next state */ 411 /* default is direct to next state */
411 412
412 pos = base[state] + equiv[(u8) c]; 413 pos = base_idx(base[state]) + equiv[(u8) c];
413 if (check[pos] == state) 414 if (check[pos] == state)
414 state = next[pos]; 415 state = next[pos];
415 else 416 else
416 state = def[state]; 417 state = def[state];
417 } else { 418 } else {
418 /* default is direct to next state */ 419 /* default is direct to next state */
419 pos = base[state] + (u8) c; 420 pos = base_idx(base[state]) + (u8) c;
420 if (check[pos] == state) 421 if (check[pos] == state)
421 state = next[pos]; 422 state = next[pos];
422 else 423 else
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index e91ffee80162..35b394a75d76 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -174,7 +174,7 @@ static int get_name_to_buffer(struct path *path, int flags, char *buffer,
174 if (info && error) { 174 if (info && error) {
175 if (error == -ENOENT) 175 if (error == -ENOENT)
176 *info = "Failed name lookup - deleted entry"; 176 *info = "Failed name lookup - deleted entry";
177 else if (error == -ESTALE) 177 else if (error == -EACCES)
178 *info = "Failed name lookup - disconnected path"; 178 *info = "Failed name lookup - disconnected path";
179 else if (error == -ENAMETOOLONG) 179 else if (error == -ENAMETOOLONG)
180 *info = "Failed name lookup - name too long"; 180 *info = "Failed name lookup - name too long";
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 813200384d97..0f345c4dee5f 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -87,7 +87,6 @@
87#include "include/policy.h" 87#include "include/policy.h"
88#include "include/policy_unpack.h" 88#include "include/policy_unpack.h"
89#include "include/resource.h" 89#include "include/resource.h"
90#include "include/sid.h"
91 90
92 91
93/* root profile namespace */ 92/* root profile namespace */
@@ -292,7 +291,6 @@ static struct aa_namespace *alloc_namespace(const char *prefix,
292 if (!ns->unconfined) 291 if (!ns->unconfined)
293 goto fail_unconfined; 292 goto fail_unconfined;
294 293
295 ns->unconfined->sid = aa_alloc_sid();
296 ns->unconfined->flags = PFLAG_UNCONFINED | PFLAG_IX_ON_NAME_ERROR | 294 ns->unconfined->flags = PFLAG_UNCONFINED | PFLAG_IX_ON_NAME_ERROR |
297 PFLAG_IMMUTABLE; 295 PFLAG_IMMUTABLE;
298 296
@@ -303,6 +301,8 @@ static struct aa_namespace *alloc_namespace(const char *prefix,
303 */ 301 */
304 ns->unconfined->ns = aa_get_namespace(ns); 302 ns->unconfined->ns = aa_get_namespace(ns);
305 303
304 atomic_set(&ns->uniq_null, 0);
305
306 return ns; 306 return ns;
307 307
308fail_unconfined: 308fail_unconfined:
@@ -497,7 +497,6 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
497 /* released when @new is freed */ 497 /* released when @new is freed */
498 new->parent = aa_get_profile(old->parent); 498 new->parent = aa_get_profile(old->parent);
499 new->ns = aa_get_namespace(old->ns); 499 new->ns = aa_get_namespace(old->ns);
500 new->sid = old->sid;
501 __list_add_profile(&policy->profiles, new); 500 __list_add_profile(&policy->profiles, new);
502 /* inherit children */ 501 /* inherit children */
503 list_for_each_entry_safe(child, tmp, &old->base.profiles, base.list) { 502 list_for_each_entry_safe(child, tmp, &old->base.profiles, base.list) {
@@ -636,83 +635,6 @@ void __init aa_free_root_ns(void)
636} 635}
637 636
638/** 637/**
639 * aa_alloc_profile - allocate, initialize and return a new profile
640 * @hname: name of the profile (NOT NULL)
641 *
642 * Returns: refcount profile or NULL on failure
643 */
644struct aa_profile *aa_alloc_profile(const char *hname)
645{
646 struct aa_profile *profile;
647
648 /* freed by free_profile - usually through aa_put_profile */
649 profile = kzalloc(sizeof(*profile), GFP_KERNEL);
650 if (!profile)
651 return NULL;
652
653 if (!policy_init(&profile->base, NULL, hname)) {
654 kzfree(profile);
655 return NULL;
656 }
657
658 /* refcount released by caller */
659 return profile;
660}
661
662/**
663 * aa_new_null_profile - create a new null-X learning profile
664 * @parent: profile that caused this profile to be created (NOT NULL)
665 * @hat: true if the null- learning profile is a hat
666 *
667 * Create a null- complain mode profile used in learning mode. The name of
668 * the profile is unique and follows the format of parent//null-sid.
669 *
670 * null profiles are added to the profile list but the list does not
671 * hold a count on them so that they are automatically released when
672 * not in use.
673 *
674 * Returns: new refcounted profile else NULL on failure
675 */
676struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat)
677{
678 struct aa_profile *profile = NULL;
679 char *name;
680 u32 sid = aa_alloc_sid();
681
682 /* freed below */
683 name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, GFP_KERNEL);
684 if (!name)
685 goto fail;
686 sprintf(name, "%s//null-%x", parent->base.hname, sid);
687
688 profile = aa_alloc_profile(name);
689 kfree(name);
690 if (!profile)
691 goto fail;
692
693 profile->sid = sid;
694 profile->mode = APPARMOR_COMPLAIN;
695 profile->flags = PFLAG_NULL;
696 if (hat)
697 profile->flags |= PFLAG_HAT;
698
699 /* released on free_profile */
700 profile->parent = aa_get_profile(parent);
701 profile->ns = aa_get_namespace(parent->ns);
702
703 write_lock(&profile->ns->lock);
704 __list_add_profile(&parent->base.profiles, profile);
705 write_unlock(&profile->ns->lock);
706
707 /* refcount released by caller */
708 return profile;
709
710fail:
711 aa_free_sid(sid);
712 return NULL;
713}
714
715/**
716 * free_profile - free a profile 638 * free_profile - free a profile
717 * @profile: the profile to free (MAYBE NULL) 639 * @profile: the profile to free (MAYBE NULL)
718 * 640 *
@@ -749,7 +671,6 @@ static void free_profile(struct aa_profile *profile)
749 aa_free_cap_rules(&profile->caps); 671 aa_free_cap_rules(&profile->caps);
750 aa_free_rlimit_rules(&profile->rlimits); 672 aa_free_rlimit_rules(&profile->rlimits);
751 673
752 aa_free_sid(profile->sid);
753 aa_put_dfa(profile->xmatch); 674 aa_put_dfa(profile->xmatch);
754 aa_put_dfa(profile->policy.dfa); 675 aa_put_dfa(profile->policy.dfa);
755 676
@@ -790,6 +711,81 @@ void aa_free_profile_kref(struct kref *kref)
790 free_profile(p); 711 free_profile(p);
791} 712}
792 713
714/**
715 * aa_alloc_profile - allocate, initialize and return a new profile
716 * @hname: name of the profile (NOT NULL)
717 *
718 * Returns: refcount profile or NULL on failure
719 */
720struct aa_profile *aa_alloc_profile(const char *hname)
721{
722 struct aa_profile *profile;
723
724 /* freed by free_profile - usually through aa_put_profile */
725 profile = kzalloc(sizeof(*profile), GFP_KERNEL);
726 if (!profile)
727 return NULL;
728
729 if (!policy_init(&profile->base, NULL, hname)) {
730 kzfree(profile);
731 return NULL;
732 }
733
734 /* refcount released by caller */
735 return profile;
736}
737
738/**
739 * aa_new_null_profile - create a new null-X learning profile
740 * @parent: profile that caused this profile to be created (NOT NULL)
741 * @hat: true if the null- learning profile is a hat
742 *
743 * Create a null- complain mode profile used in learning mode. The name of
744 * the profile is unique and follows the format of parent//null-<uniq>.
745 *
746 * null profiles are added to the profile list but the list does not
747 * hold a count on them so that they are automatically released when
748 * not in use.
749 *
750 * Returns: new refcounted profile else NULL on failure
751 */
752struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat)
753{
754 struct aa_profile *profile = NULL;
755 char *name;
756 int uniq = atomic_inc_return(&parent->ns->uniq_null);
757
758 /* freed below */
759 name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, GFP_KERNEL);
760 if (!name)
761 goto fail;
762 sprintf(name, "%s//null-%x", parent->base.hname, uniq);
763
764 profile = aa_alloc_profile(name);
765 kfree(name);
766 if (!profile)
767 goto fail;
768
769 profile->mode = APPARMOR_COMPLAIN;
770 profile->flags = PFLAG_NULL;
771 if (hat)
772 profile->flags |= PFLAG_HAT;
773
774 /* released on free_profile */
775 profile->parent = aa_get_profile(parent);
776 profile->ns = aa_get_namespace(parent->ns);
777
778 write_lock(&profile->ns->lock);
779 __list_add_profile(&parent->base.profiles, profile);
780 write_unlock(&profile->ns->lock);
781
782 /* refcount released by caller */
783 return profile;
784
785fail:
786 return NULL;
787}
788
793/* TODO: profile accounting - setup in remove */ 789/* TODO: profile accounting - setup in remove */
794 790
795/** 791/**
@@ -972,7 +968,6 @@ static void __add_new_profile(struct aa_namespace *ns, struct aa_policy *policy,
972 profile->parent = aa_get_profile((struct aa_profile *) policy); 968 profile->parent = aa_get_profile((struct aa_profile *) policy);
973 __list_add_profile(&policy->profiles, profile); 969 __list_add_profile(&policy->profiles, profile);
974 /* released on free_profile */ 970 /* released on free_profile */
975 profile->sid = aa_alloc_sid();
976 profile->ns = aa_get_namespace(ns); 971 profile->ns = aa_get_namespace(ns);
977} 972}
978 973
@@ -1110,14 +1105,8 @@ audit:
1110 if (!error) { 1105 if (!error) {
1111 if (rename_profile) 1106 if (rename_profile)
1112 __replace_profile(rename_profile, new_profile); 1107 __replace_profile(rename_profile, new_profile);
1113 if (old_profile) { 1108 if (old_profile)
1114 /* when there are both rename and old profiles
1115 * inherit old profiles sid
1116 */
1117 if (rename_profile)
1118 aa_free_sid(new_profile->sid);
1119 __replace_profile(old_profile, new_profile); 1109 __replace_profile(old_profile, new_profile);
1120 }
1121 if (!(old_profile || rename_profile)) 1110 if (!(old_profile || rename_profile))
1122 __add_new_profile(ns, policy, new_profile); 1111 __add_new_profile(ns, policy, new_profile);
1123 } 1112 }
@@ -1167,14 +1156,12 @@ ssize_t aa_remove_profiles(char *fqname, size_t size)
1167 if (fqname[0] == ':') { 1156 if (fqname[0] == ':') {
1168 char *ns_name; 1157 char *ns_name;
1169 name = aa_split_fqname(fqname, &ns_name); 1158 name = aa_split_fqname(fqname, &ns_name);
1170 if (ns_name) { 1159 /* released below */
1171 /* released below */ 1160 ns = aa_find_namespace(root, ns_name);
1172 ns = aa_find_namespace(root, ns_name); 1161 if (!ns) {
1173 if (!ns) { 1162 info = "namespace does not exist";
1174 info = "namespace does not exist"; 1163 error = -ENOENT;
1175 error = -ENOENT; 1164 goto fail;
1176 goto fail;
1177 }
1178 } 1165 }
1179 } else 1166 } else
1180 /* released below */ 1167 /* released below */
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 329b1fd30749..6dac7d77cb4d 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -27,7 +27,6 @@
27#include "include/match.h" 27#include "include/match.h"
28#include "include/policy.h" 28#include "include/policy.h"
29#include "include/policy_unpack.h" 29#include "include/policy_unpack.h"
30#include "include/sid.h"
31 30
32/* 31/*
33 * The AppArmor interface treats data as a type byte followed by the 32 * The AppArmor interface treats data as a type byte followed by the
@@ -290,6 +289,9 @@ static int unpack_strdup(struct aa_ext *e, char **string, const char *name)
290 return res; 289 return res;
291} 290}
292 291
292#define DFA_VALID_PERM_MASK 0xffffffff
293#define DFA_VALID_PERM2_MASK 0xffffffff
294
293/** 295/**
294 * verify_accept - verify the accept tables of a dfa 296 * verify_accept - verify the accept tables of a dfa
295 * @dfa: dfa to verify accept tables of (NOT NULL) 297 * @dfa: dfa to verify accept tables of (NOT NULL)
diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
index 1b41c542d376..6c9390179b89 100644
--- a/security/apparmor/procattr.c
+++ b/security/apparmor/procattr.c
@@ -163,9 +163,3 @@ int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test)
163 name = aa_split_fqname(fqname, &ns_name); 163 name = aa_split_fqname(fqname, &ns_name);
164 return aa_change_profile(ns_name, name, onexec, test); 164 return aa_change_profile(ns_name, name, onexec, test);
165} 165}
166
167int aa_setprocattr_permipc(char *fqname)
168{
169 /* TODO: add ipc permission querying */
170 return -ENOTSUPP;
171}
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
index e1f3d7ef2c54..748bf0ca6c9f 100644
--- a/security/apparmor/resource.c
+++ b/security/apparmor/resource.c
@@ -15,6 +15,7 @@
15#include <linux/audit.h> 15#include <linux/audit.h>
16 16
17#include "include/audit.h" 17#include "include/audit.h"
18#include "include/context.h"
18#include "include/resource.h" 19#include "include/resource.h"
19#include "include/policy.h" 20#include "include/policy.h"
20 21
@@ -90,17 +91,25 @@ int aa_map_resource(int resource)
90int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task, 91int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
91 unsigned int resource, struct rlimit *new_rlim) 92 unsigned int resource, struct rlimit *new_rlim)
92{ 93{
94 struct aa_profile *task_profile;
93 int error = 0; 95 int error = 0;
94 96
97 rcu_read_lock();
98 task_profile = aa_get_profile(aa_cred_profile(__task_cred(task)));
99 rcu_read_unlock();
100
95 /* TODO: extend resource control to handle other (non current) 101 /* TODO: extend resource control to handle other (non current)
96 * processes. AppArmor rules currently have the implicit assumption 102 * profiles. AppArmor rules currently have the implicit assumption
97 * that the task is setting the resource of the current process 103 * that the task is setting the resource of a task confined with
104 * the same profile.
98 */ 105 */
99 if ((task != current->group_leader) || 106 if (profile != task_profile ||
100 (profile->rlimits.mask & (1 << resource) && 107 (profile->rlimits.mask & (1 << resource) &&
101 new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max)) 108 new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max))
102 error = -EACCES; 109 error = -EACCES;
103 110
111 aa_put_profile(task_profile);
112
104 return audit_resource(profile, resource, new_rlim->rlim_max, error); 113 return audit_resource(profile, resource, new_rlim->rlim_max, error);
105} 114}
106 115
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 4bb3a775a996..245c6d92065b 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -17,6 +17,21 @@ config INTEGRITY_SIGNATURE
17 This is useful for evm and module keyrings, when keys are 17 This is useful for evm and module keyrings, when keys are
18 usually only added from initramfs. 18 usually only added from initramfs.
19 19
20config INTEGRITY_AUDIT
21 bool "Enables integrity auditing support "
22 depends on INTEGRITY && AUDIT
23 default y
24 help
25 In addition to enabling integrity auditing support, this
26 option adds a kernel parameter 'integrity_audit', which
27 controls the level of integrity auditing messages.
28 0 - basic integrity auditing messages (default)
29 1 - additional integrity auditing messages
30
31 Additional informational integrity auditing messages would
32 be enabled by specifying 'integrity_audit=1' on the kernel
33 command line.
34
20config INTEGRITY_ASYMMETRIC_KEYS 35config INTEGRITY_ASYMMETRIC_KEYS
21 boolean "Enable asymmetric keys support" 36 boolean "Enable asymmetric keys support"
22 depends on INTEGRITY_SIGNATURE 37 depends on INTEGRITY_SIGNATURE
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index ebb6409b3fcb..0f9cffb1f9ad 100644
--- a/security/integrity/Makefile
+++ b/security/integrity/Makefile
@@ -3,6 +3,7 @@
3# 3#
4 4
5obj-$(CONFIG_INTEGRITY) += integrity.o 5obj-$(CONFIG_INTEGRITY) += integrity.o
6obj-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
6obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o 7obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
7obj-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o 8obj-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
8 9
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index cdbde1762189..df0fa451a871 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/crypto.h> 18#include <linux/crypto.h>
19#include <linux/audit.h>
19#include <linux/xattr.h> 20#include <linux/xattr.h>
20#include <linux/integrity.h> 21#include <linux/integrity.h>
21#include <linux/evm.h> 22#include <linux/evm.h>
@@ -24,6 +25,9 @@
24 25
25int evm_initialized; 26int evm_initialized;
26 27
28static char *integrity_status_msg[] = {
29 "pass", "fail", "no_label", "no_xattrs", "unknown"
30};
27char *evm_hmac = "hmac(sha1)"; 31char *evm_hmac = "hmac(sha1)";
28char *evm_hash = "sha1"; 32char *evm_hash = "sha1";
29int evm_hmac_version = CONFIG_EVM_HMAC_VERSION; 33int evm_hmac_version = CONFIG_EVM_HMAC_VERSION;
@@ -262,9 +266,15 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
262 if ((evm_status == INTEGRITY_PASS) || 266 if ((evm_status == INTEGRITY_PASS) ||
263 (evm_status == INTEGRITY_NOXATTRS)) 267 (evm_status == INTEGRITY_NOXATTRS))
264 return 0; 268 return 0;
265 return -EPERM; 269 goto out;
266 } 270 }
267 evm_status = evm_verify_current_integrity(dentry); 271 evm_status = evm_verify_current_integrity(dentry);
272out:
273 if (evm_status != INTEGRITY_PASS)
274 integrity_audit_msg(AUDIT_INTEGRITY_METADATA, dentry->d_inode,
275 dentry->d_name.name, "appraise_metadata",
276 integrity_status_msg[evm_status],
277 -EPERM, 0);
268 return evm_status == INTEGRITY_PASS ? 0 : -EPERM; 278 return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
269} 279}
270 280
@@ -357,6 +367,9 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
357 if ((evm_status == INTEGRITY_PASS) || 367 if ((evm_status == INTEGRITY_PASS) ||
358 (evm_status == INTEGRITY_NOXATTRS)) 368 (evm_status == INTEGRITY_NOXATTRS))
359 return 0; 369 return 0;
370 integrity_audit_msg(AUDIT_INTEGRITY_METADATA, dentry->d_inode,
371 dentry->d_name.name, "appraise_metadata",
372 integrity_status_msg[evm_status], -EPERM, 0);
360 return -EPERM; 373 return -EPERM;
361} 374}
362 375
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index d232c73647ae..39196abaff0d 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -38,18 +38,6 @@ config IMA_MEASURE_PCR_IDX
38 that IMA uses to maintain the integrity aggregate of the 38 that IMA uses to maintain the integrity aggregate of the
39 measurement list. If unsure, use the default 10. 39 measurement list. If unsure, use the default 10.
40 40
41config IMA_AUDIT
42 bool "Enables auditing support"
43 depends on IMA
44 depends on AUDIT
45 default y
46 help
47 This option adds a kernel parameter 'ima_audit', which
48 allows informational auditing messages to be enabled
49 at boot. If this option is selected, informational integrity
50 auditing messages can be enabled with 'ima_audit=1' on
51 the kernel command line.
52
53config IMA_LSM_RULES 41config IMA_LSM_RULES
54 bool 42 bool
55 depends on IMA && AUDIT && (SECURITY_SELINUX || SECURITY_SMACK) 43 depends on IMA && AUDIT && (SECURITY_SELINUX || SECURITY_SMACK)
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 3f2ca6bdc384..56dfee7cbf61 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -7,5 +7,4 @@ obj-$(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 9 ima_policy.o
10ima-$(CONFIG_IMA_AUDIT) += ima_audit.o
11ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o 10ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index a41c9c18e5e0..b3dd616560f7 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -62,20 +62,6 @@ struct ima_queue_entry {
62}; 62};
63extern struct list_head ima_measurements; /* list of all measurements */ 63extern struct list_head ima_measurements; /* list of all measurements */
64 64
65#ifdef CONFIG_IMA_AUDIT
66/* declarations */
67void integrity_audit_msg(int audit_msgno, struct inode *inode,
68 const unsigned char *fname, const char *op,
69 const char *cause, int result, int info);
70#else
71static inline void integrity_audit_msg(int audit_msgno, struct inode *inode,
72 const unsigned char *fname,
73 const char *op, const char *cause,
74 int result, int info)
75{
76}
77#endif
78
79/* Internal IMA function definitions */ 65/* Internal IMA function definitions */
80int ima_init(void); 66int ima_init(void);
81void ima_cleanup(void); 67void ima_cleanup(void);
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 84c37c4db914..c42fb7a70dee 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -113,5 +113,19 @@ static inline int asymmetric_verify(struct key *keyring, const char *sig,
113} 113}
114#endif 114#endif
115 115
116#ifdef CONFIG_INTEGRITY_AUDIT
117/* declarations */
118void integrity_audit_msg(int audit_msgno, struct inode *inode,
119 const unsigned char *fname, const char *op,
120 const char *cause, int result, int info);
121#else
122static inline void integrity_audit_msg(int audit_msgno, struct inode *inode,
123 const unsigned char *fname,
124 const char *op, const char *cause,
125 int result, int info)
126{
127}
128#endif
129
116/* set during initialization */ 130/* set during initialization */
117extern int iint_initialized; 131extern int iint_initialized;
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/integrity_audit.c
index c586faae8fd6..d7efb30404aa 100644
--- a/security/integrity/ima/ima_audit.c
+++ b/security/integrity/integrity_audit.c
@@ -13,20 +13,20 @@
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/gfp.h> 14#include <linux/gfp.h>
15#include <linux/audit.h> 15#include <linux/audit.h>
16#include "ima.h" 16#include "integrity.h"
17 17
18static int ima_audit; 18static int integrity_audit_info;
19 19
20/* ima_audit_setup - enable informational auditing messages */ 20/* ima_audit_setup - enable informational auditing messages */
21static int __init ima_audit_setup(char *str) 21static int __init integrity_audit_setup(char *str)
22{ 22{
23 unsigned long audit; 23 unsigned long audit;
24 24
25 if (!strict_strtoul(str, 0, &audit)) 25 if (!strict_strtoul(str, 0, &audit))
26 ima_audit = audit ? 1 : 0; 26 integrity_audit_info = audit ? 1 : 0;
27 return 1; 27 return 1;
28} 28}
29__setup("ima_audit=", ima_audit_setup); 29__setup("integrity_audit=", integrity_audit_setup);
30 30
31void integrity_audit_msg(int audit_msgno, struct inode *inode, 31void integrity_audit_msg(int audit_msgno, struct inode *inode,
32 const unsigned char *fname, const char *op, 32 const unsigned char *fname, const char *op,
@@ -34,7 +34,7 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
34{ 34{
35 struct audit_buffer *ab; 35 struct audit_buffer *ab;
36 36
37 if (!ima_audit && audit_info == 1) /* Skip informational messages */ 37 if (!integrity_audit_info && audit_info == 1) /* Skip info messages */
38 return; 38 return;
39 39
40 ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno); 40 ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 8ad30955e15d..339614c76e63 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -29,6 +29,38 @@
29#define SMK_LONGLABEL 256 29#define SMK_LONGLABEL 256
30 30
31/* 31/*
32 * This is the repository for labels seen so that it is
33 * not necessary to keep allocating tiny chuncks of memory
34 * and so that they can be shared.
35 *
36 * Labels are never modified in place. Anytime a label
37 * is imported (e.g. xattrset on a file) the list is checked
38 * for it and it is added if it doesn't exist. The address
39 * is passed out in either case. Entries are added, but
40 * never deleted.
41 *
42 * Since labels are hanging around anyway it doesn't
43 * hurt to maintain a secid for those awkward situations
44 * where kernel components that ought to use LSM independent
45 * interfaces don't. The secid should go away when all of
46 * these components have been repaired.
47 *
48 * The cipso value associated with the label gets stored here, too.
49 *
50 * Keep the access rules for this subject label here so that
51 * the entire set of rules does not need to be examined every
52 * time.
53 */
54struct smack_known {
55 struct list_head list;
56 char *smk_known;
57 u32 smk_secid;
58 struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */
59 struct list_head smk_rules; /* access rules */
60 struct mutex smk_rules_lock; /* lock for rules */
61};
62
63/*
32 * Maximum number of bytes for the levels in a CIPSO IP option. 64 * Maximum number of bytes for the levels in a CIPSO IP option.
33 * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is 65 * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
34 * bigger than can be used, and 24 is the next lower multiple 66 * bigger than can be used, and 24 is the next lower multiple
@@ -46,25 +78,25 @@ struct superblock_smack {
46}; 78};
47 79
48struct socket_smack { 80struct socket_smack {
49 char *smk_out; /* outbound label */ 81 struct smack_known *smk_out; /* outbound label */
50 char *smk_in; /* inbound label */ 82 char *smk_in; /* inbound label */
51 char *smk_packet; /* TCP peer label */ 83 char *smk_packet; /* TCP peer label */
52}; 84};
53 85
54/* 86/*
55 * Inode smack data 87 * Inode smack data
56 */ 88 */
57struct inode_smack { 89struct inode_smack {
58 char *smk_inode; /* label of the fso */ 90 char *smk_inode; /* label of the fso */
59 char *smk_task; /* label of the task */ 91 struct smack_known *smk_task; /* label of the task */
60 char *smk_mmap; /* label of the mmap domain */ 92 struct smack_known *smk_mmap; /* label of the mmap domain */
61 struct mutex smk_lock; /* initialization lock */ 93 struct mutex smk_lock; /* initialization lock */
62 int smk_flags; /* smack inode flags */ 94 int smk_flags; /* smack inode flags */
63}; 95};
64 96
65struct task_smack { 97struct task_smack {
66 char *smk_task; /* label for access control */ 98 struct smack_known *smk_task; /* label for access control */
67 char *smk_forked; /* label when forked */ 99 struct smack_known *smk_forked; /* label when forked */
68 struct list_head smk_rules; /* per task access rules */ 100 struct list_head smk_rules; /* per task access rules */
69 struct mutex smk_rules_lock; /* lock for the rules */ 101 struct mutex smk_rules_lock; /* lock for the rules */
70}; 102};
@@ -78,7 +110,7 @@ struct task_smack {
78 */ 110 */
79struct smack_rule { 111struct smack_rule {
80 struct list_head list; 112 struct list_head list;
81 char *smk_subject; 113 struct smack_known *smk_subject;
82 char *smk_object; 114 char *smk_object;
83 int smk_access; 115 int smk_access;
84}; 116};
@@ -94,35 +126,14 @@ struct smk_netlbladdr {
94}; 126};
95 127
96/* 128/*
97 * This is the repository for labels seen so that it is 129 * An entry in the table identifying ports.
98 * not necessary to keep allocating tiny chuncks of memory
99 * and so that they can be shared.
100 *
101 * Labels are never modified in place. Anytime a label
102 * is imported (e.g. xattrset on a file) the list is checked
103 * for it and it is added if it doesn't exist. The address
104 * is passed out in either case. Entries are added, but
105 * never deleted.
106 *
107 * Since labels are hanging around anyway it doesn't
108 * hurt to maintain a secid for those awkward situations
109 * where kernel components that ought to use LSM independent
110 * interfaces don't. The secid should go away when all of
111 * these components have been repaired.
112 *
113 * The cipso value associated with the label gets stored here, too.
114 *
115 * Keep the access rules for this subject label here so that
116 * the entire set of rules does not need to be examined every
117 * time.
118 */ 130 */
119struct smack_known { 131struct smk_port_label {
120 struct list_head list; 132 struct list_head list;
121 char *smk_known; 133 struct sock *smk_sock; /* socket initialized on */
122 u32 smk_secid; 134 unsigned short smk_port; /* the port number */
123 struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */ 135 char *smk_in; /* incoming label */
124 struct list_head smk_rules; /* access rules */ 136 struct smack_known *smk_out; /* outgoing label */
125 struct mutex smk_rules_lock; /* lock for rules */
126}; 137};
127 138
128/* 139/*
@@ -132,6 +143,7 @@ struct smack_known {
132#define SMK_FSFLOOR "smackfsfloor=" 143#define SMK_FSFLOOR "smackfsfloor="
133#define SMK_FSHAT "smackfshat=" 144#define SMK_FSHAT "smackfshat="
134#define SMK_FSROOT "smackfsroot=" 145#define SMK_FSROOT "smackfsroot="
146#define SMK_FSTRANS "smackfstransmute="
135 147
136#define SMACK_CIPSO_OPTION "-CIPSO" 148#define SMACK_CIPSO_OPTION "-CIPSO"
137 149
@@ -203,9 +215,9 @@ struct inode_smack *new_inode_smack(char *);
203 * These functions are in smack_access.c 215 * These functions are in smack_access.c
204 */ 216 */
205int smk_access_entry(char *, char *, struct list_head *); 217int smk_access_entry(char *, char *, struct list_head *);
206int smk_access(char *, char *, int, struct smk_audit_info *); 218int smk_access(struct smack_known *, char *, int, struct smk_audit_info *);
207int smk_curacc(char *, u32, struct smk_audit_info *); 219int smk_curacc(char *, u32, struct smk_audit_info *);
208char *smack_from_secid(const u32); 220struct smack_known *smack_from_secid(const u32);
209char *smk_parse_smack(const char *string, int len); 221char *smk_parse_smack(const char *string, int len);
210int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); 222int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
211char *smk_import(const char *, int); 223char *smk_import(const char *, int);
@@ -218,7 +230,7 @@ u32 smack_to_secid(const char *);
218 */ 230 */
219extern int smack_cipso_direct; 231extern int smack_cipso_direct;
220extern int smack_cipso_mapped; 232extern int smack_cipso_mapped;
221extern char *smack_net_ambient; 233extern struct smack_known *smack_net_ambient;
222extern char *smack_onlycap; 234extern char *smack_onlycap;
223extern const char *smack_cipso_option; 235extern const char *smack_cipso_option;
224 236
@@ -254,17 +266,17 @@ static inline char *smk_of_inode(const struct inode *isp)
254} 266}
255 267
256/* 268/*
257 * Present a pointer to the smack label in an task blob. 269 * Present a pointer to the smack label entry in an task blob.
258 */ 270 */
259static inline char *smk_of_task(const struct task_smack *tsp) 271static inline struct smack_known *smk_of_task(const struct task_smack *tsp)
260{ 272{
261 return tsp->smk_task; 273 return tsp->smk_task;
262} 274}
263 275
264/* 276/*
265 * Present a pointer to the forked smack label in an task blob. 277 * Present a pointer to the forked smack label entry in an task blob.
266 */ 278 */
267static inline char *smk_of_forked(const struct task_smack *tsp) 279static inline struct smack_known *smk_of_forked(const struct task_smack *tsp)
268{ 280{
269 return tsp->smk_forked; 281 return tsp->smk_forked;
270} 282}
@@ -272,7 +284,7 @@ static inline char *smk_of_forked(const struct task_smack *tsp)
272/* 284/*
273 * Present a pointer to the smack label in the current task blob. 285 * Present a pointer to the smack label in the current task blob.
274 */ 286 */
275static inline char *smk_of_current(void) 287static inline struct smack_known *smk_of_current(void)
276{ 288{
277 return smk_of_task(current_security()); 289 return smk_of_task(current_security());
278} 290}
@@ -283,9 +295,11 @@ static inline char *smk_of_current(void)
283 */ 295 */
284static inline int smack_privileged(int cap) 296static inline int smack_privileged(int cap)
285{ 297{
298 struct smack_known *skp = smk_of_current();
299
286 if (!capable(cap)) 300 if (!capable(cap))
287 return 0; 301 return 0;
288 if (smack_onlycap == NULL || smack_onlycap == smk_of_current()) 302 if (smack_onlycap == NULL || smack_onlycap == skp->smk_known)
289 return 1; 303 return 1;
290 return 0; 304 return 0;
291} 305}
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 2e397a88d410..6a0377f38620 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -93,7 +93,7 @@ int smk_access_entry(char *subject_label, char *object_label,
93 93
94 list_for_each_entry_rcu(srp, rule_list, list) { 94 list_for_each_entry_rcu(srp, rule_list, list) {
95 if (srp->smk_object == object_label && 95 if (srp->smk_object == object_label &&
96 srp->smk_subject == subject_label) { 96 srp->smk_subject->smk_known == subject_label) {
97 may = srp->smk_access; 97 may = srp->smk_access;
98 break; 98 break;
99 } 99 }
@@ -104,7 +104,7 @@ int smk_access_entry(char *subject_label, char *object_label,
104 104
105/** 105/**
106 * smk_access - determine if a subject has a specific access to an object 106 * smk_access - determine if a subject has a specific access to an object
107 * @subject_label: a pointer to the subject's Smack label 107 * @subject_known: a pointer to the subject's Smack label entry
108 * @object_label: a pointer to the object's Smack label 108 * @object_label: a pointer to the object's Smack label
109 * @request: the access requested, in "MAY" format 109 * @request: the access requested, in "MAY" format
110 * @a : a pointer to the audit data 110 * @a : a pointer to the audit data
@@ -115,10 +115,9 @@ int smk_access_entry(char *subject_label, char *object_label,
115 * 115 *
116 * Smack labels are shared on smack_list 116 * Smack labels are shared on smack_list
117 */ 117 */
118int smk_access(char *subject_label, char *object_label, int request, 118int smk_access(struct smack_known *subject_known, char *object_label,
119 struct smk_audit_info *a) 119 int request, struct smk_audit_info *a)
120{ 120{
121 struct smack_known *skp;
122 int may = MAY_NOT; 121 int may = MAY_NOT;
123 int rc = 0; 122 int rc = 0;
124 123
@@ -127,7 +126,7 @@ int smk_access(char *subject_label, char *object_label, int request,
127 * 126 *
128 * A star subject can't access any object. 127 * A star subject can't access any object.
129 */ 128 */
130 if (subject_label == smack_known_star.smk_known) { 129 if (subject_known == &smack_known_star) {
131 rc = -EACCES; 130 rc = -EACCES;
132 goto out_audit; 131 goto out_audit;
133 } 132 }
@@ -137,7 +136,7 @@ int smk_access(char *subject_label, char *object_label, int request,
137 * An internet subject can access any object. 136 * An internet subject can access any object.
138 */ 137 */
139 if (object_label == smack_known_web.smk_known || 138 if (object_label == smack_known_web.smk_known ||
140 subject_label == smack_known_web.smk_known) 139 subject_known == &smack_known_web)
141 goto out_audit; 140 goto out_audit;
142 /* 141 /*
143 * A star object can be accessed by any subject. 142 * A star object can be accessed by any subject.
@@ -148,7 +147,7 @@ int smk_access(char *subject_label, char *object_label, int request,
148 * An object can be accessed in any way by a subject 147 * An object can be accessed in any way by a subject
149 * with the same label. 148 * with the same label.
150 */ 149 */
151 if (subject_label == object_label) 150 if (subject_known->smk_known == object_label)
152 goto out_audit; 151 goto out_audit;
153 /* 152 /*
154 * A hat subject can read any object. 153 * A hat subject can read any object.
@@ -157,7 +156,7 @@ int smk_access(char *subject_label, char *object_label, int request,
157 if ((request & MAY_ANYREAD) == request) { 156 if ((request & MAY_ANYREAD) == request) {
158 if (object_label == smack_known_floor.smk_known) 157 if (object_label == smack_known_floor.smk_known)
159 goto out_audit; 158 goto out_audit;
160 if (subject_label == smack_known_hat.smk_known) 159 if (subject_known == &smack_known_hat)
161 goto out_audit; 160 goto out_audit;
162 } 161 }
163 /* 162 /*
@@ -167,9 +166,9 @@ int smk_access(char *subject_label, char *object_label, int request,
167 * good. A negative response from smk_access_entry() 166 * good. A negative response from smk_access_entry()
168 * indicates there is no entry for this pair. 167 * indicates there is no entry for this pair.
169 */ 168 */
170 skp = smk_find_entry(subject_label);
171 rcu_read_lock(); 169 rcu_read_lock();
172 may = smk_access_entry(subject_label, object_label, &skp->smk_rules); 170 may = smk_access_entry(subject_known->smk_known, object_label,
171 &subject_known->smk_rules);
173 rcu_read_unlock(); 172 rcu_read_unlock();
174 173
175 if (may > 0 && (request & may) == request) 174 if (may > 0 && (request & may) == request)
@@ -179,7 +178,8 @@ int smk_access(char *subject_label, char *object_label, int request,
179out_audit: 178out_audit:
180#ifdef CONFIG_AUDIT 179#ifdef CONFIG_AUDIT
181 if (a) 180 if (a)
182 smack_log(subject_label, object_label, request, rc, a); 181 smack_log(subject_known->smk_known, object_label, request,
182 rc, a);
183#endif 183#endif
184 return rc; 184 return rc;
185} 185}
@@ -198,20 +198,21 @@ out_audit:
198int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) 198int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
199{ 199{
200 struct task_smack *tsp = current_security(); 200 struct task_smack *tsp = current_security();
201 char *sp = smk_of_task(tsp); 201 struct smack_known *skp = smk_of_task(tsp);
202 int may; 202 int may;
203 int rc; 203 int rc;
204 204
205 /* 205 /*
206 * Check the global rule list 206 * Check the global rule list
207 */ 207 */
208 rc = smk_access(sp, obj_label, mode, NULL); 208 rc = smk_access(skp, obj_label, mode, NULL);
209 if (rc == 0) { 209 if (rc == 0) {
210 /* 210 /*
211 * If there is an entry in the task's rule list 211 * If there is an entry in the task's rule list
212 * it can further restrict access. 212 * it can further restrict access.
213 */ 213 */
214 may = smk_access_entry(sp, obj_label, &tsp->smk_rules); 214 may = smk_access_entry(skp->smk_known, obj_label,
215 &tsp->smk_rules);
215 if (may < 0) 216 if (may < 0)
216 goto out_audit; 217 goto out_audit;
217 if ((mode & may) == mode) 218 if ((mode & may) == mode)
@@ -228,7 +229,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
228out_audit: 229out_audit:
229#ifdef CONFIG_AUDIT 230#ifdef CONFIG_AUDIT
230 if (a) 231 if (a)
231 smack_log(sp, obj_label, mode, rc, a); 232 smack_log(skp->smk_known, obj_label, mode, rc, a);
232#endif 233#endif
233 return rc; 234 return rc;
234} 235}
@@ -402,6 +403,8 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
402 sap->flags |= NETLBL_SECATTR_MLS_CAT; 403 sap->flags |= NETLBL_SECATTR_MLS_CAT;
403 sap->attr.mls.lvl = level; 404 sap->attr.mls.lvl = level;
404 sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 405 sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
406 if (!sap->attr.mls.cat)
407 return -ENOMEM;
405 sap->attr.mls.cat->startbit = 0; 408 sap->attr.mls.cat->startbit = 0;
406 409
407 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++) 410 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++)
@@ -513,10 +516,10 @@ char *smk_import(const char *string, int len)
513 * smack_from_secid - find the Smack label associated with a secid 516 * smack_from_secid - find the Smack label associated with a secid
514 * @secid: an integer that might be associated with a Smack label 517 * @secid: an integer that might be associated with a Smack label
515 * 518 *
516 * Returns a pointer to the appropriate Smack label if there is one, 519 * Returns a pointer to the appropriate Smack label entry if there is one,
517 * otherwise a pointer to the invalid Smack label. 520 * otherwise a pointer to the invalid Smack label.
518 */ 521 */
519char *smack_from_secid(const u32 secid) 522struct smack_known *smack_from_secid(const u32 secid)
520{ 523{
521 struct smack_known *skp; 524 struct smack_known *skp;
522 525
@@ -524,7 +527,7 @@ char *smack_from_secid(const u32 secid)
524 list_for_each_entry_rcu(skp, &smack_known_list, list) { 527 list_for_each_entry_rcu(skp, &smack_known_list, list) {
525 if (skp->smk_secid == secid) { 528 if (skp->smk_secid == secid) {
526 rcu_read_unlock(); 529 rcu_read_unlock();
527 return skp->smk_known; 530 return skp;
528 } 531 }
529 } 532 }
530 533
@@ -533,7 +536,7 @@ char *smack_from_secid(const u32 secid)
533 * of a secid that is not on the list. 536 * of a secid that is not on the list.
534 */ 537 */
535 rcu_read_unlock(); 538 rcu_read_unlock();
536 return smack_known_invalid.smk_known; 539 return &smack_known_invalid;
537} 540}
538 541
539/** 542/**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index d52c780bdb78..6a083303501d 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -27,10 +27,13 @@
27#include <linux/ip.h> 27#include <linux/ip.h>
28#include <linux/tcp.h> 28#include <linux/tcp.h>
29#include <linux/udp.h> 29#include <linux/udp.h>
30#include <linux/dccp.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <linux/mutex.h> 32#include <linux/mutex.h>
32#include <linux/pipe_fs_i.h> 33#include <linux/pipe_fs_i.h>
33#include <net/cipso_ipv4.h> 34#include <net/cipso_ipv4.h>
35#include <net/ip.h>
36#include <net/ipv6.h>
34#include <linux/audit.h> 37#include <linux/audit.h>
35#include <linux/magic.h> 38#include <linux/magic.h>
36#include <linux/dcache.h> 39#include <linux/dcache.h>
@@ -45,6 +48,12 @@
45#define TRANS_TRUE "TRUE" 48#define TRANS_TRUE "TRUE"
46#define TRANS_TRUE_SIZE 4 49#define TRANS_TRUE_SIZE 4
47 50
51#define SMK_CONNECTING 0
52#define SMK_RECEIVING 1
53#define SMK_SENDING 2
54
55LIST_HEAD(smk_ipv6_port_list);
56
48/** 57/**
49 * smk_fetch - Fetch the smack label from a file. 58 * smk_fetch - Fetch the smack label from a file.
50 * @ip: a pointer to the inode 59 * @ip: a pointer to the inode
@@ -53,11 +62,12 @@
53 * Returns a pointer to the master list entry for the Smack label 62 * Returns a pointer to the master list entry for the Smack label
54 * or NULL if there was no label to fetch. 63 * or NULL if there was no label to fetch.
55 */ 64 */
56static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp) 65static struct smack_known *smk_fetch(const char *name, struct inode *ip,
66 struct dentry *dp)
57{ 67{
58 int rc; 68 int rc;
59 char *buffer; 69 char *buffer;
60 char *result = NULL; 70 struct smack_known *skp = NULL;
61 71
62 if (ip->i_op->getxattr == NULL) 72 if (ip->i_op->getxattr == NULL)
63 return NULL; 73 return NULL;
@@ -68,11 +78,11 @@ static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp)
68 78
69 rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL); 79 rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL);
70 if (rc > 0) 80 if (rc > 0)
71 result = smk_import(buffer, rc); 81 skp = smk_import_entry(buffer, rc);
72 82
73 kfree(buffer); 83 kfree(buffer);
74 84
75 return result; 85 return skp;
76} 86}
77 87
78/** 88/**
@@ -102,7 +112,8 @@ struct inode_smack *new_inode_smack(char *smack)
102 * 112 *
103 * Returns the new blob or NULL if there's no memory available 113 * Returns the new blob or NULL if there's no memory available
104 */ 114 */
105static struct task_smack *new_task_smack(char *task, char *forked, gfp_t gfp) 115static struct task_smack *new_task_smack(struct smack_known *task,
116 struct smack_known *forked, gfp_t gfp)
106{ 117{
107 struct task_smack *tsp; 118 struct task_smack *tsp;
108 119
@@ -164,17 +175,17 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
164{ 175{
165 int rc; 176 int rc;
166 struct smk_audit_info ad; 177 struct smk_audit_info ad;
167 char *tsp; 178 struct smack_known *skp;
168 179
169 rc = cap_ptrace_access_check(ctp, mode); 180 rc = cap_ptrace_access_check(ctp, mode);
170 if (rc != 0) 181 if (rc != 0)
171 return rc; 182 return rc;
172 183
173 tsp = smk_of_task(task_security(ctp)); 184 skp = smk_of_task(task_security(ctp));
174 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 185 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
175 smk_ad_setfield_u_tsk(&ad, ctp); 186 smk_ad_setfield_u_tsk(&ad, ctp);
176 187
177 rc = smk_curacc(tsp, MAY_READWRITE, &ad); 188 rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad);
178 return rc; 189 return rc;
179} 190}
180 191
@@ -190,17 +201,17 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
190{ 201{
191 int rc; 202 int rc;
192 struct smk_audit_info ad; 203 struct smk_audit_info ad;
193 char *tsp; 204 struct smack_known *skp;
194 205
195 rc = cap_ptrace_traceme(ptp); 206 rc = cap_ptrace_traceme(ptp);
196 if (rc != 0) 207 if (rc != 0)
197 return rc; 208 return rc;
198 209
199 tsp = smk_of_task(task_security(ptp)); 210 skp = smk_of_task(task_security(ptp));
200 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 211 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
201 smk_ad_setfield_u_tsk(&ad, ptp); 212 smk_ad_setfield_u_tsk(&ad, ptp);
202 213
203 rc = smk_curacc(tsp, MAY_READWRITE, &ad); 214 rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad);
204 return rc; 215 return rc;
205} 216}
206 217
@@ -215,12 +226,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
215static int smack_syslog(int typefrom_file) 226static int smack_syslog(int typefrom_file)
216{ 227{
217 int rc = 0; 228 int rc = 0;
218 char *sp = smk_of_current(); 229 struct smack_known *skp = smk_of_current();
219 230
220 if (smack_privileged(CAP_MAC_OVERRIDE)) 231 if (smack_privileged(CAP_MAC_OVERRIDE))
221 return 0; 232 return 0;
222 233
223 if (sp != smack_known_floor.smk_known) 234 if (skp != &smack_known_floor)
224 rc = -EACCES; 235 rc = -EACCES;
225 236
226 return rc; 237 return rc;
@@ -250,8 +261,9 @@ static int smack_sb_alloc_security(struct super_block *sb)
250 sbsp->smk_default = smack_known_floor.smk_known; 261 sbsp->smk_default = smack_known_floor.smk_known;
251 sbsp->smk_floor = smack_known_floor.smk_known; 262 sbsp->smk_floor = smack_known_floor.smk_known;
252 sbsp->smk_hat = smack_known_hat.smk_known; 263 sbsp->smk_hat = smack_known_hat.smk_known;
253 sbsp->smk_initialized = 0; 264 /*
254 265 * smk_initialized will be zero from kzalloc.
266 */
255 sb->s_security = sbsp; 267 sb->s_security = sbsp;
256 268
257 return 0; 269 return 0;
@@ -295,6 +307,8 @@ static int smack_sb_copy_data(char *orig, char *smackopts)
295 dp = smackopts; 307 dp = smackopts;
296 else if (strstr(cp, SMK_FSROOT) == cp) 308 else if (strstr(cp, SMK_FSROOT) == cp)
297 dp = smackopts; 309 dp = smackopts;
310 else if (strstr(cp, SMK_FSTRANS) == cp)
311 dp = smackopts;
298 else 312 else
299 dp = otheropts; 313 dp = otheropts;
300 314
@@ -330,8 +344,9 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
330 char *op; 344 char *op;
331 char *commap; 345 char *commap;
332 char *nsp; 346 char *nsp;
347 int transmute = 0;
333 348
334 if (sp->smk_initialized != 0) 349 if (sp->smk_initialized)
335 return 0; 350 return 0;
336 351
337 sp->smk_initialized = 1; 352 sp->smk_initialized = 1;
@@ -362,6 +377,13 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
362 nsp = smk_import(op, 0); 377 nsp = smk_import(op, 0);
363 if (nsp != NULL) 378 if (nsp != NULL)
364 sp->smk_root = nsp; 379 sp->smk_root = nsp;
380 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) {
381 op += strlen(SMK_FSTRANS);
382 nsp = smk_import(op, 0);
383 if (nsp != NULL) {
384 sp->smk_root = nsp;
385 transmute = 1;
386 }
365 } 387 }
366 } 388 }
367 389
@@ -369,11 +391,15 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
369 * Initialize the root inode. 391 * Initialize the root inode.
370 */ 392 */
371 isp = inode->i_security; 393 isp = inode->i_security;
372 if (isp == NULL) 394 if (inode->i_security == NULL) {
373 inode->i_security = new_inode_smack(sp->smk_root); 395 inode->i_security = new_inode_smack(sp->smk_root);
374 else 396 isp = inode->i_security;
397 } else
375 isp->smk_inode = sp->smk_root; 398 isp->smk_inode = sp->smk_root;
376 399
400 if (transmute)
401 isp->smk_flags |= SMK_INODE_TRANSMUTE;
402
377 return 0; 403 return 0;
378} 404}
379 405
@@ -524,7 +550,9 @@ static int smack_bprm_secureexec(struct linux_binprm *bprm)
524 */ 550 */
525static int smack_inode_alloc_security(struct inode *inode) 551static int smack_inode_alloc_security(struct inode *inode)
526{ 552{
527 inode->i_security = new_inode_smack(smk_of_current()); 553 struct smack_known *skp = smk_of_current();
554
555 inode->i_security = new_inode_smack(skp->smk_known);
528 if (inode->i_security == NULL) 556 if (inode->i_security == NULL)
529 return -ENOMEM; 557 return -ENOMEM;
530 return 0; 558 return 0;
@@ -557,9 +585,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
557 const struct qstr *qstr, char **name, 585 const struct qstr *qstr, char **name,
558 void **value, size_t *len) 586 void **value, size_t *len)
559{ 587{
560 struct smack_known *skp;
561 struct inode_smack *issp = inode->i_security; 588 struct inode_smack *issp = inode->i_security;
562 char *csp = smk_of_current(); 589 struct smack_known *skp = smk_of_current();
563 char *isp = smk_of_inode(inode); 590 char *isp = smk_of_inode(inode);
564 char *dsp = smk_of_inode(dir); 591 char *dsp = smk_of_inode(dir);
565 int may; 592 int may;
@@ -571,9 +598,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
571 } 598 }
572 599
573 if (value) { 600 if (value) {
574 skp = smk_find_entry(csp);
575 rcu_read_lock(); 601 rcu_read_lock();
576 may = smk_access_entry(csp, dsp, &skp->smk_rules); 602 may = smk_access_entry(skp->smk_known, dsp, &skp->smk_rules);
577 rcu_read_unlock(); 603 rcu_read_unlock();
578 604
579 /* 605 /*
@@ -862,29 +888,31 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
862static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, 888static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
863 const void *value, size_t size, int flags) 889 const void *value, size_t size, int flags)
864{ 890{
865 char *nsp; 891 struct smack_known *skp;
866 struct inode_smack *isp = dentry->d_inode->i_security; 892 struct inode_smack *isp = dentry->d_inode->i_security;
867 893
894 if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
895 isp->smk_flags |= SMK_INODE_TRANSMUTE;
896 return;
897 }
898
899 skp = smk_import_entry(value, size);
868 if (strcmp(name, XATTR_NAME_SMACK) == 0) { 900 if (strcmp(name, XATTR_NAME_SMACK) == 0) {
869 nsp = smk_import(value, size); 901 if (skp != NULL)
870 if (nsp != NULL) 902 isp->smk_inode = skp->smk_known;
871 isp->smk_inode = nsp;
872 else 903 else
873 isp->smk_inode = smack_known_invalid.smk_known; 904 isp->smk_inode = smack_known_invalid.smk_known;
874 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { 905 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
875 nsp = smk_import(value, size); 906 if (skp != NULL)
876 if (nsp != NULL) 907 isp->smk_task = skp;
877 isp->smk_task = nsp;
878 else 908 else
879 isp->smk_task = smack_known_invalid.smk_known; 909 isp->smk_task = &smack_known_invalid;
880 } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { 910 } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
881 nsp = smk_import(value, size); 911 if (skp != NULL)
882 if (nsp != NULL) 912 isp->smk_mmap = skp;
883 isp->smk_mmap = nsp;
884 else 913 else
885 isp->smk_mmap = smack_known_invalid.smk_known; 914 isp->smk_mmap = &smack_known_invalid;
886 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) 915 }
887 isp->smk_flags |= SMK_INODE_TRANSMUTE;
888 916
889 return; 917 return;
890} 918}
@@ -990,7 +1018,7 @@ static int smack_inode_getsecurity(const struct inode *inode,
990 if (strcmp(name, XATTR_SMACK_IPIN) == 0) 1018 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
991 isp = ssp->smk_in; 1019 isp = ssp->smk_in;
992 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) 1020 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
993 isp = ssp->smk_out; 1021 isp = ssp->smk_out->smk_known;
994 else 1022 else
995 return -EOPNOTSUPP; 1023 return -EOPNOTSUPP;
996 1024
@@ -1070,7 +1098,9 @@ static int smack_file_permission(struct file *file, int mask)
1070 */ 1098 */
1071static int smack_file_alloc_security(struct file *file) 1099static int smack_file_alloc_security(struct file *file)
1072{ 1100{
1073 file->f_security = smk_of_current(); 1101 struct smack_known *skp = smk_of_current();
1102
1103 file->f_security = skp->smk_known;
1074 return 0; 1104 return 0;
1075} 1105}
1076 1106
@@ -1181,10 +1211,9 @@ static int smack_mmap_file(struct file *file,
1181 unsigned long flags) 1211 unsigned long flags)
1182{ 1212{
1183 struct smack_known *skp; 1213 struct smack_known *skp;
1214 struct smack_known *mkp;
1184 struct smack_rule *srp; 1215 struct smack_rule *srp;
1185 struct task_smack *tsp; 1216 struct task_smack *tsp;
1186 char *sp;
1187 char *msmack;
1188 char *osmack; 1217 char *osmack;
1189 struct inode_smack *isp; 1218 struct inode_smack *isp;
1190 int may; 1219 int may;
@@ -1198,11 +1227,10 @@ static int smack_mmap_file(struct file *file,
1198 isp = file_inode(file)->i_security; 1227 isp = file_inode(file)->i_security;
1199 if (isp->smk_mmap == NULL) 1228 if (isp->smk_mmap == NULL)
1200 return 0; 1229 return 0;
1201 msmack = isp->smk_mmap; 1230 mkp = isp->smk_mmap;
1202 1231
1203 tsp = current_security(); 1232 tsp = current_security();
1204 sp = smk_of_current(); 1233 skp = smk_of_current();
1205 skp = smk_find_entry(sp);
1206 rc = 0; 1234 rc = 0;
1207 1235
1208 rcu_read_lock(); 1236 rcu_read_lock();
@@ -1216,13 +1244,13 @@ static int smack_mmap_file(struct file *file,
1216 /* 1244 /*
1217 * Matching labels always allows access. 1245 * Matching labels always allows access.
1218 */ 1246 */
1219 if (msmack == osmack) 1247 if (mkp->smk_known == osmack)
1220 continue; 1248 continue;
1221 /* 1249 /*
1222 * If there is a matching local rule take 1250 * If there is a matching local rule take
1223 * that into account as well. 1251 * that into account as well.
1224 */ 1252 */
1225 may = smk_access_entry(srp->smk_subject, osmack, 1253 may = smk_access_entry(srp->smk_subject->smk_known, osmack,
1226 &tsp->smk_rules); 1254 &tsp->smk_rules);
1227 if (may == -ENOENT) 1255 if (may == -ENOENT)
1228 may = srp->smk_access; 1256 may = srp->smk_access;
@@ -1240,8 +1268,8 @@ static int smack_mmap_file(struct file *file,
1240 * If there isn't one a SMACK64MMAP subject 1268 * If there isn't one a SMACK64MMAP subject
1241 * can't have as much access as current. 1269 * can't have as much access as current.
1242 */ 1270 */
1243 skp = smk_find_entry(msmack); 1271 mmay = smk_access_entry(mkp->smk_known, osmack,
1244 mmay = smk_access_entry(msmack, osmack, &skp->smk_rules); 1272 &mkp->smk_rules);
1245 if (mmay == -ENOENT) { 1273 if (mmay == -ENOENT) {
1246 rc = -EACCES; 1274 rc = -EACCES;
1247 break; 1275 break;
@@ -1250,7 +1278,8 @@ static int smack_mmap_file(struct file *file,
1250 * If there is a local entry it modifies the 1278 * If there is a local entry it modifies the
1251 * potential access, too. 1279 * potential access, too.
1252 */ 1280 */
1253 tmay = smk_access_entry(msmack, osmack, &tsp->smk_rules); 1281 tmay = smk_access_entry(mkp->smk_known, osmack,
1282 &tsp->smk_rules);
1254 if (tmay != -ENOENT) 1283 if (tmay != -ENOENT)
1255 mmay &= tmay; 1284 mmay &= tmay;
1256 1285
@@ -1279,7 +1308,9 @@ static int smack_mmap_file(struct file *file,
1279 */ 1308 */
1280static int smack_file_set_fowner(struct file *file) 1309static int smack_file_set_fowner(struct file *file)
1281{ 1310{
1282 file->f_security = smk_of_current(); 1311 struct smack_known *skp = smk_of_current();
1312
1313 file->f_security = skp->smk_known;
1283 return 0; 1314 return 0;
1284} 1315}
1285 1316
@@ -1297,9 +1328,10 @@ static int smack_file_set_fowner(struct file *file)
1297static int smack_file_send_sigiotask(struct task_struct *tsk, 1328static int smack_file_send_sigiotask(struct task_struct *tsk,
1298 struct fown_struct *fown, int signum) 1329 struct fown_struct *fown, int signum)
1299{ 1330{
1331 struct smack_known *skp;
1332 struct smack_known *tkp = smk_of_task(tsk->cred->security);
1300 struct file *file; 1333 struct file *file;
1301 int rc; 1334 int rc;
1302 char *tsp = smk_of_task(tsk->cred->security);
1303 struct smk_audit_info ad; 1335 struct smk_audit_info ad;
1304 1336
1305 /* 1337 /*
@@ -1308,13 +1340,14 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
1308 file = container_of(fown, struct file, f_owner); 1340 file = container_of(fown, struct file, f_owner);
1309 1341
1310 /* we don't log here as rc can be overriden */ 1342 /* we don't log here as rc can be overriden */
1311 rc = smk_access(file->f_security, tsp, MAY_WRITE, NULL); 1343 skp = smk_find_entry(file->f_security);
1344 rc = smk_access(skp, tkp->smk_known, MAY_WRITE, NULL);
1312 if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) 1345 if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
1313 rc = 0; 1346 rc = 0;
1314 1347
1315 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1348 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1316 smk_ad_setfield_u_tsk(&ad, tsk); 1349 smk_ad_setfield_u_tsk(&ad, tsk);
1317 smack_log(file->f_security, tsp, MAY_WRITE, rc, &ad); 1350 smack_log(file->f_security, tkp->smk_known, MAY_WRITE, rc, &ad);
1318 return rc; 1351 return rc;
1319} 1352}
1320 1353
@@ -1469,12 +1502,12 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
1469static int smack_kernel_act_as(struct cred *new, u32 secid) 1502static int smack_kernel_act_as(struct cred *new, u32 secid)
1470{ 1503{
1471 struct task_smack *new_tsp = new->security; 1504 struct task_smack *new_tsp = new->security;
1472 char *smack = smack_from_secid(secid); 1505 struct smack_known *skp = smack_from_secid(secid);
1473 1506
1474 if (smack == NULL) 1507 if (skp == NULL)
1475 return -EINVAL; 1508 return -EINVAL;
1476 1509
1477 new_tsp->smk_task = smack; 1510 new_tsp->smk_task = skp;
1478 return 0; 1511 return 0;
1479} 1512}
1480 1513
@@ -1492,8 +1525,8 @@ static int smack_kernel_create_files_as(struct cred *new,
1492 struct inode_smack *isp = inode->i_security; 1525 struct inode_smack *isp = inode->i_security;
1493 struct task_smack *tsp = new->security; 1526 struct task_smack *tsp = new->security;
1494 1527
1495 tsp->smk_forked = isp->smk_inode; 1528 tsp->smk_forked = smk_find_entry(isp->smk_inode);
1496 tsp->smk_task = isp->smk_inode; 1529 tsp->smk_task = tsp->smk_forked;
1497 return 0; 1530 return 0;
1498} 1531}
1499 1532
@@ -1509,10 +1542,11 @@ static int smk_curacc_on_task(struct task_struct *p, int access,
1509 const char *caller) 1542 const char *caller)
1510{ 1543{
1511 struct smk_audit_info ad; 1544 struct smk_audit_info ad;
1545 struct smack_known *skp = smk_of_task(task_security(p));
1512 1546
1513 smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); 1547 smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
1514 smk_ad_setfield_u_tsk(&ad, p); 1548 smk_ad_setfield_u_tsk(&ad, p);
1515 return smk_curacc(smk_of_task(task_security(p)), access, &ad); 1549 return smk_curacc(skp->smk_known, access, &ad);
1516} 1550}
1517 1551
1518/** 1552/**
@@ -1558,7 +1592,9 @@ static int smack_task_getsid(struct task_struct *p)
1558 */ 1592 */
1559static void smack_task_getsecid(struct task_struct *p, u32 *secid) 1593static void smack_task_getsecid(struct task_struct *p, u32 *secid)
1560{ 1594{
1561 *secid = smack_to_secid(smk_of_task(task_security(p))); 1595 struct smack_known *skp = smk_of_task(task_security(p));
1596
1597 *secid = skp->smk_secid;
1562} 1598}
1563 1599
1564/** 1600/**
@@ -1662,6 +1698,8 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1662 int sig, u32 secid) 1698 int sig, u32 secid)
1663{ 1699{
1664 struct smk_audit_info ad; 1700 struct smk_audit_info ad;
1701 struct smack_known *skp;
1702 struct smack_known *tkp = smk_of_task(task_security(p));
1665 1703
1666 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1704 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1667 smk_ad_setfield_u_tsk(&ad, p); 1705 smk_ad_setfield_u_tsk(&ad, p);
@@ -1670,15 +1708,14 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1670 * can write the receiver. 1708 * can write the receiver.
1671 */ 1709 */
1672 if (secid == 0) 1710 if (secid == 0)
1673 return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE, 1711 return smk_curacc(tkp->smk_known, MAY_WRITE, &ad);
1674 &ad);
1675 /* 1712 /*
1676 * If the secid isn't 0 we're dealing with some USB IO 1713 * If the secid isn't 0 we're dealing with some USB IO
1677 * specific behavior. This is not clean. For one thing 1714 * specific behavior. This is not clean. For one thing
1678 * we can't take privilege into account. 1715 * we can't take privilege into account.
1679 */ 1716 */
1680 return smk_access(smack_from_secid(secid), 1717 skp = smack_from_secid(secid);
1681 smk_of_task(task_security(p)), MAY_WRITE, &ad); 1718 return smk_access(skp, tkp->smk_known, MAY_WRITE, &ad);
1682} 1719}
1683 1720
1684/** 1721/**
@@ -1710,7 +1747,9 @@ static int smack_task_wait(struct task_struct *p)
1710static void smack_task_to_inode(struct task_struct *p, struct inode *inode) 1747static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1711{ 1748{
1712 struct inode_smack *isp = inode->i_security; 1749 struct inode_smack *isp = inode->i_security;
1713 isp->smk_inode = smk_of_task(task_security(p)); 1750 struct smack_known *skp = smk_of_task(task_security(p));
1751
1752 isp->smk_inode = skp->smk_known;
1714} 1753}
1715 1754
1716/* 1755/*
@@ -1729,15 +1768,15 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1729 */ 1768 */
1730static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) 1769static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
1731{ 1770{
1732 char *csp = smk_of_current(); 1771 struct smack_known *skp = smk_of_current();
1733 struct socket_smack *ssp; 1772 struct socket_smack *ssp;
1734 1773
1735 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); 1774 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
1736 if (ssp == NULL) 1775 if (ssp == NULL)
1737 return -ENOMEM; 1776 return -ENOMEM;
1738 1777
1739 ssp->smk_in = csp; 1778 ssp->smk_in = skp->smk_known;
1740 ssp->smk_out = csp; 1779 ssp->smk_out = skp;
1741 ssp->smk_packet = NULL; 1780 ssp->smk_packet = NULL;
1742 1781
1743 sk->sk_security = ssp; 1782 sk->sk_security = ssp;
@@ -1824,7 +1863,7 @@ static int smack_netlabel(struct sock *sk, int labeled)
1824 labeled == SMACK_UNLABELED_SOCKET) 1863 labeled == SMACK_UNLABELED_SOCKET)
1825 netlbl_sock_delattr(sk); 1864 netlbl_sock_delattr(sk);
1826 else { 1865 else {
1827 skp = smk_find_entry(ssp->smk_out); 1866 skp = ssp->smk_out;
1828 rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel); 1867 rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
1829 } 1868 }
1830 1869
@@ -1847,6 +1886,7 @@ static int smack_netlabel(struct sock *sk, int labeled)
1847 */ 1886 */
1848static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) 1887static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1849{ 1888{
1889 struct smack_known *skp;
1850 int rc; 1890 int rc;
1851 int sk_lbl; 1891 int sk_lbl;
1852 char *hostsp; 1892 char *hostsp;
@@ -1865,7 +1905,8 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1865 ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr; 1905 ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
1866#endif 1906#endif
1867 sk_lbl = SMACK_UNLABELED_SOCKET; 1907 sk_lbl = SMACK_UNLABELED_SOCKET;
1868 rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); 1908 skp = ssp->smk_out;
1909 rc = smk_access(skp, hostsp, MAY_WRITE, &ad);
1869 } else { 1910 } else {
1870 sk_lbl = SMACK_CIPSO_SOCKET; 1911 sk_lbl = SMACK_CIPSO_SOCKET;
1871 rc = 0; 1912 rc = 0;
@@ -1878,6 +1919,155 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1878} 1919}
1879 1920
1880/** 1921/**
1922 * smk_ipv6_port_label - Smack port access table management
1923 * @sock: socket
1924 * @address: address
1925 *
1926 * Create or update the port list entry
1927 */
1928static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
1929{
1930 struct sock *sk = sock->sk;
1931 struct sockaddr_in6 *addr6;
1932 struct socket_smack *ssp = sock->sk->sk_security;
1933 struct smk_port_label *spp;
1934 unsigned short port = 0;
1935
1936 if (address == NULL) {
1937 /*
1938 * This operation is changing the Smack information
1939 * on the bound socket. Take the changes to the port
1940 * as well.
1941 */
1942 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
1943 if (sk != spp->smk_sock)
1944 continue;
1945 spp->smk_in = ssp->smk_in;
1946 spp->smk_out = ssp->smk_out;
1947 return;
1948 }
1949 /*
1950 * A NULL address is only used for updating existing
1951 * bound entries. If there isn't one, it's OK.
1952 */
1953 return;
1954 }
1955
1956 addr6 = (struct sockaddr_in6 *)address;
1957 port = ntohs(addr6->sin6_port);
1958 /*
1959 * This is a special case that is safely ignored.
1960 */
1961 if (port == 0)
1962 return;
1963
1964 /*
1965 * Look for an existing port list entry.
1966 * This is an indication that a port is getting reused.
1967 */
1968 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
1969 if (spp->smk_port != port)
1970 continue;
1971 spp->smk_port = port;
1972 spp->smk_sock = sk;
1973 spp->smk_in = ssp->smk_in;
1974 spp->smk_out = ssp->smk_out;
1975 return;
1976 }
1977
1978 /*
1979 * A new port entry is required.
1980 */
1981 spp = kzalloc(sizeof(*spp), GFP_KERNEL);
1982 if (spp == NULL)
1983 return;
1984
1985 spp->smk_port = port;
1986 spp->smk_sock = sk;
1987 spp->smk_in = ssp->smk_in;
1988 spp->smk_out = ssp->smk_out;
1989
1990 list_add(&spp->list, &smk_ipv6_port_list);
1991 return;
1992}
1993
1994/**
1995 * smk_ipv6_port_check - check Smack port access
1996 * @sock: socket
1997 * @address: address
1998 *
1999 * Create or update the port list entry
2000 */
2001static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
2002 int act)
2003{
2004 __be16 *bep;
2005 __be32 *be32p;
2006 struct sockaddr_in6 *addr6;
2007 struct smk_port_label *spp;
2008 struct socket_smack *ssp = sk->sk_security;
2009 struct smack_known *skp;
2010 unsigned short port = 0;
2011 char *object;
2012 struct smk_audit_info ad;
2013#ifdef CONFIG_AUDIT
2014 struct lsm_network_audit net;
2015#endif
2016
2017 if (act == SMK_RECEIVING) {
2018 skp = smack_net_ambient;
2019 object = ssp->smk_in;
2020 } else {
2021 skp = ssp->smk_out;
2022 object = smack_net_ambient->smk_known;
2023 }
2024
2025 /*
2026 * Get the IP address and port from the address.
2027 */
2028 addr6 = (struct sockaddr_in6 *)address;
2029 port = ntohs(addr6->sin6_port);
2030 bep = (__be16 *)(&addr6->sin6_addr);
2031 be32p = (__be32 *)(&addr6->sin6_addr);
2032
2033 /*
2034 * It's remote, so port lookup does no good.
2035 */
2036 if (be32p[0] || be32p[1] || be32p[2] || bep[6] || ntohs(bep[7]) != 1)
2037 goto auditout;
2038
2039 /*
2040 * It's local so the send check has to have passed.
2041 */
2042 if (act == SMK_RECEIVING) {
2043 skp = &smack_known_web;
2044 goto auditout;
2045 }
2046
2047 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
2048 if (spp->smk_port != port)
2049 continue;
2050 object = spp->smk_in;
2051 if (act == SMK_CONNECTING)
2052 ssp->smk_packet = spp->smk_out->smk_known;
2053 break;
2054 }
2055
2056auditout:
2057
2058#ifdef CONFIG_AUDIT
2059 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2060 ad.a.u.net->family = sk->sk_family;
2061 ad.a.u.net->dport = port;
2062 if (act == SMK_RECEIVING)
2063 ad.a.u.net->v6info.saddr = addr6->sin6_addr;
2064 else
2065 ad.a.u.net->v6info.daddr = addr6->sin6_addr;
2066#endif
2067 return smk_access(skp, object, MAY_WRITE, &ad);
2068}
2069
2070/**
1881 * smack_inode_setsecurity - set smack xattrs 2071 * smack_inode_setsecurity - set smack xattrs
1882 * @inode: the object 2072 * @inode: the object
1883 * @name: attribute name 2073 * @name: attribute name
@@ -1892,7 +2082,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1892static int smack_inode_setsecurity(struct inode *inode, const char *name, 2082static int smack_inode_setsecurity(struct inode *inode, const char *name,
1893 const void *value, size_t size, int flags) 2083 const void *value, size_t size, int flags)
1894{ 2084{
1895 char *sp; 2085 struct smack_known *skp;
1896 struct inode_smack *nsp = inode->i_security; 2086 struct inode_smack *nsp = inode->i_security;
1897 struct socket_smack *ssp; 2087 struct socket_smack *ssp;
1898 struct socket *sock; 2088 struct socket *sock;
@@ -1901,12 +2091,12 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1901 if (value == NULL || size > SMK_LONGLABEL || size == 0) 2091 if (value == NULL || size > SMK_LONGLABEL || size == 0)
1902 return -EACCES; 2092 return -EACCES;
1903 2093
1904 sp = smk_import(value, size); 2094 skp = smk_import_entry(value, size);
1905 if (sp == NULL) 2095 if (skp == NULL)
1906 return -EINVAL; 2096 return -EINVAL;
1907 2097
1908 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { 2098 if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
1909 nsp->smk_inode = sp; 2099 nsp->smk_inode = skp->smk_known;
1910 nsp->smk_flags |= SMK_INODE_INSTANT; 2100 nsp->smk_flags |= SMK_INODE_INSTANT;
1911 return 0; 2101 return 0;
1912 } 2102 }
@@ -1923,10 +2113,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1923 ssp = sock->sk->sk_security; 2113 ssp = sock->sk->sk_security;
1924 2114
1925 if (strcmp(name, XATTR_SMACK_IPIN) == 0) 2115 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
1926 ssp->smk_in = sp; 2116 ssp->smk_in = skp->smk_known;
1927 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { 2117 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
1928 ssp->smk_out = sp; 2118 ssp->smk_out = skp;
1929 if (sock->sk->sk_family != PF_UNIX) { 2119 if (sock->sk->sk_family == PF_INET) {
1930 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 2120 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
1931 if (rc != 0) 2121 if (rc != 0)
1932 printk(KERN_WARNING 2122 printk(KERN_WARNING
@@ -1936,6 +2126,9 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1936 } else 2126 } else
1937 return -EOPNOTSUPP; 2127 return -EOPNOTSUPP;
1938 2128
2129 if (sock->sk->sk_family == PF_INET6)
2130 smk_ipv6_port_label(sock, NULL);
2131
1939 return 0; 2132 return 0;
1940} 2133}
1941 2134
@@ -1963,6 +2156,25 @@ static int smack_socket_post_create(struct socket *sock, int family,
1963} 2156}
1964 2157
1965/** 2158/**
2159 * smack_socket_bind - record port binding information.
2160 * @sock: the socket
2161 * @address: the port address
2162 * @addrlen: size of the address
2163 *
2164 * Records the label bound to a port.
2165 *
2166 * Returns 0
2167 */
2168static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
2169 int addrlen)
2170{
2171 if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
2172 smk_ipv6_port_label(sock, address);
2173
2174 return 0;
2175}
2176
2177/**
1966 * smack_socket_connect - connect access check 2178 * smack_socket_connect - connect access check
1967 * @sock: the socket 2179 * @sock: the socket
1968 * @sap: the other end 2180 * @sap: the other end
@@ -1975,12 +2187,24 @@ static int smack_socket_post_create(struct socket *sock, int family,
1975static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, 2187static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
1976 int addrlen) 2188 int addrlen)
1977{ 2189{
1978 if (sock->sk == NULL || sock->sk->sk_family != PF_INET) 2190 int rc = 0;
2191
2192 if (sock->sk == NULL)
1979 return 0; 2193 return 0;
1980 if (addrlen < sizeof(struct sockaddr_in))
1981 return -EINVAL;
1982 2194
1983 return smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap); 2195 switch (sock->sk->sk_family) {
2196 case PF_INET:
2197 if (addrlen < sizeof(struct sockaddr_in))
2198 return -EINVAL;
2199 rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
2200 break;
2201 case PF_INET6:
2202 if (addrlen < sizeof(struct sockaddr_in6))
2203 return -EINVAL;
2204 rc = smk_ipv6_port_check(sock->sk, sap, SMK_CONNECTING);
2205 break;
2206 }
2207 return rc;
1984} 2208}
1985 2209
1986/** 2210/**
@@ -2011,7 +2235,9 @@ static int smack_flags_to_may(int flags)
2011 */ 2235 */
2012static int smack_msg_msg_alloc_security(struct msg_msg *msg) 2236static int smack_msg_msg_alloc_security(struct msg_msg *msg)
2013{ 2237{
2014 msg->security = smk_of_current(); 2238 struct smack_known *skp = smk_of_current();
2239
2240 msg->security = skp->smk_known;
2015 return 0; 2241 return 0;
2016} 2242}
2017 2243
@@ -2046,8 +2272,9 @@ static char *smack_of_shm(struct shmid_kernel *shp)
2046static int smack_shm_alloc_security(struct shmid_kernel *shp) 2272static int smack_shm_alloc_security(struct shmid_kernel *shp)
2047{ 2273{
2048 struct kern_ipc_perm *isp = &shp->shm_perm; 2274 struct kern_ipc_perm *isp = &shp->shm_perm;
2275 struct smack_known *skp = smk_of_current();
2049 2276
2050 isp->security = smk_of_current(); 2277 isp->security = skp->smk_known;
2051 return 0; 2278 return 0;
2052} 2279}
2053 2280
@@ -2169,8 +2396,9 @@ static char *smack_of_sem(struct sem_array *sma)
2169static int smack_sem_alloc_security(struct sem_array *sma) 2396static int smack_sem_alloc_security(struct sem_array *sma)
2170{ 2397{
2171 struct kern_ipc_perm *isp = &sma->sem_perm; 2398 struct kern_ipc_perm *isp = &sma->sem_perm;
2399 struct smack_known *skp = smk_of_current();
2172 2400
2173 isp->security = smk_of_current(); 2401 isp->security = skp->smk_known;
2174 return 0; 2402 return 0;
2175} 2403}
2176 2404
@@ -2287,8 +2515,9 @@ static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
2287static int smack_msg_queue_alloc_security(struct msg_queue *msq) 2515static int smack_msg_queue_alloc_security(struct msg_queue *msq)
2288{ 2516{
2289 struct kern_ipc_perm *kisp = &msq->q_perm; 2517 struct kern_ipc_perm *kisp = &msq->q_perm;
2518 struct smack_known *skp = smk_of_current();
2290 2519
2291 kisp->security = smk_of_current(); 2520 kisp->security = skp->smk_known;
2292 return 0; 2521 return 0;
2293} 2522}
2294 2523
@@ -2460,8 +2689,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2460 struct super_block *sbp; 2689 struct super_block *sbp;
2461 struct superblock_smack *sbsp; 2690 struct superblock_smack *sbsp;
2462 struct inode_smack *isp; 2691 struct inode_smack *isp;
2463 char *csp = smk_of_current(); 2692 struct smack_known *skp;
2464 char *fetched; 2693 struct smack_known *ckp = smk_of_current();
2465 char *final; 2694 char *final;
2466 char trattr[TRANS_TRUE_SIZE]; 2695 char trattr[TRANS_TRUE_SIZE];
2467 int transflag = 0; 2696 int transflag = 0;
@@ -2528,7 +2757,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2528 * Programs that change smack have to treat the 2757 * Programs that change smack have to treat the
2529 * pty with respect. 2758 * pty with respect.
2530 */ 2759 */
2531 final = csp; 2760 final = ckp->smk_known;
2532 break; 2761 break;
2533 case SOCKFS_MAGIC: 2762 case SOCKFS_MAGIC:
2534 /* 2763 /*
@@ -2583,9 +2812,9 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2583 * Get the dentry for xattr. 2812 * Get the dentry for xattr.
2584 */ 2813 */
2585 dp = dget(opt_dentry); 2814 dp = dget(opt_dentry);
2586 fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp); 2815 skp = smk_fetch(XATTR_NAME_SMACK, inode, dp);
2587 if (fetched != NULL) 2816 if (skp != NULL)
2588 final = fetched; 2817 final = skp->smk_known;
2589 2818
2590 /* 2819 /*
2591 * Transmuting directory 2820 * Transmuting directory
@@ -2625,7 +2854,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2625 } 2854 }
2626 2855
2627 if (final == NULL) 2856 if (final == NULL)
2628 isp->smk_inode = csp; 2857 isp->smk_inode = ckp->smk_known;
2629 else 2858 else
2630 isp->smk_inode = final; 2859 isp->smk_inode = final;
2631 2860
@@ -2648,13 +2877,14 @@ unlockandout:
2648 */ 2877 */
2649static int smack_getprocattr(struct task_struct *p, char *name, char **value) 2878static int smack_getprocattr(struct task_struct *p, char *name, char **value)
2650{ 2879{
2880 struct smack_known *skp = smk_of_task(task_security(p));
2651 char *cp; 2881 char *cp;
2652 int slen; 2882 int slen;
2653 2883
2654 if (strcmp(name, "current") != 0) 2884 if (strcmp(name, "current") != 0)
2655 return -EINVAL; 2885 return -EINVAL;
2656 2886
2657 cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL); 2887 cp = kstrdup(skp->smk_known, GFP_KERNEL);
2658 if (cp == NULL) 2888 if (cp == NULL)
2659 return -ENOMEM; 2889 return -ENOMEM;
2660 2890
@@ -2680,7 +2910,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2680{ 2910{
2681 struct task_smack *tsp; 2911 struct task_smack *tsp;
2682 struct cred *new; 2912 struct cred *new;
2683 char *newsmack; 2913 struct smack_known *skp;
2684 2914
2685 /* 2915 /*
2686 * Changing another process' Smack value is too dangerous 2916 * Changing another process' Smack value is too dangerous
@@ -2698,14 +2928,14 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2698 if (strcmp(name, "current") != 0) 2928 if (strcmp(name, "current") != 0)
2699 return -EINVAL; 2929 return -EINVAL;
2700 2930
2701 newsmack = smk_import(value, size); 2931 skp = smk_import_entry(value, size);
2702 if (newsmack == NULL) 2932 if (skp == NULL)
2703 return -EINVAL; 2933 return -EINVAL;
2704 2934
2705 /* 2935 /*
2706 * No process is ever allowed the web ("@") label. 2936 * No process is ever allowed the web ("@") label.
2707 */ 2937 */
2708 if (newsmack == smack_known_web.smk_known) 2938 if (skp == &smack_known_web)
2709 return -EPERM; 2939 return -EPERM;
2710 2940
2711 new = prepare_creds(); 2941 new = prepare_creds();
@@ -2713,7 +2943,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2713 return -ENOMEM; 2943 return -ENOMEM;
2714 2944
2715 tsp = new->security; 2945 tsp = new->security;
2716 tsp->smk_task = newsmack; 2946 tsp->smk_task = skp;
2717 2947
2718 commit_creds(new); 2948 commit_creds(new);
2719 return size; 2949 return size;
@@ -2731,6 +2961,7 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2731static int smack_unix_stream_connect(struct sock *sock, 2961static int smack_unix_stream_connect(struct sock *sock,
2732 struct sock *other, struct sock *newsk) 2962 struct sock *other, struct sock *newsk)
2733{ 2963{
2964 struct smack_known *skp;
2734 struct socket_smack *ssp = sock->sk_security; 2965 struct socket_smack *ssp = sock->sk_security;
2735 struct socket_smack *osp = other->sk_security; 2966 struct socket_smack *osp = other->sk_security;
2736 struct socket_smack *nsp = newsk->sk_security; 2967 struct socket_smack *nsp = newsk->sk_security;
@@ -2744,15 +2975,17 @@ static int smack_unix_stream_connect(struct sock *sock,
2744 smk_ad_setfield_u_net_sk(&ad, other); 2975 smk_ad_setfield_u_net_sk(&ad, other);
2745#endif 2976#endif
2746 2977
2747 if (!smack_privileged(CAP_MAC_OVERRIDE)) 2978 if (!smack_privileged(CAP_MAC_OVERRIDE)) {
2748 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 2979 skp = ssp->smk_out;
2980 rc = smk_access(skp, osp->smk_in, MAY_WRITE, &ad);
2981 }
2749 2982
2750 /* 2983 /*
2751 * Cross reference the peer labels for SO_PEERSEC. 2984 * Cross reference the peer labels for SO_PEERSEC.
2752 */ 2985 */
2753 if (rc == 0) { 2986 if (rc == 0) {
2754 nsp->smk_packet = ssp->smk_out; 2987 nsp->smk_packet = ssp->smk_out->smk_known;
2755 ssp->smk_packet = osp->smk_out; 2988 ssp->smk_packet = osp->smk_out->smk_known;
2756 } 2989 }
2757 2990
2758 return rc; 2991 return rc;
@@ -2770,8 +3003,8 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2770{ 3003{
2771 struct socket_smack *ssp = sock->sk->sk_security; 3004 struct socket_smack *ssp = sock->sk->sk_security;
2772 struct socket_smack *osp = other->sk->sk_security; 3005 struct socket_smack *osp = other->sk->sk_security;
3006 struct smack_known *skp;
2773 struct smk_audit_info ad; 3007 struct smk_audit_info ad;
2774 int rc = 0;
2775 3008
2776#ifdef CONFIG_AUDIT 3009#ifdef CONFIG_AUDIT
2777 struct lsm_network_audit net; 3010 struct lsm_network_audit net;
@@ -2780,10 +3013,11 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2780 smk_ad_setfield_u_net_sk(&ad, other->sk); 3013 smk_ad_setfield_u_net_sk(&ad, other->sk);
2781#endif 3014#endif
2782 3015
2783 if (!smack_privileged(CAP_MAC_OVERRIDE)) 3016 if (smack_privileged(CAP_MAC_OVERRIDE))
2784 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 3017 return 0;
2785 3018
2786 return rc; 3019 skp = ssp->smk_out;
3020 return smk_access(skp, osp->smk_in, MAY_WRITE, &ad);
2787} 3021}
2788 3022
2789/** 3023/**
@@ -2792,22 +3026,32 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2792 * @msg: the message 3026 * @msg: the message
2793 * @size: the size of the message 3027 * @size: the size of the message
2794 * 3028 *
2795 * Return 0 if the current subject can write to the destination 3029 * Return 0 if the current subject can write to the destination host.
2796 * host. This is only a question if the destination is a single 3030 * For IPv4 this is only a question if the destination is a single label host.
2797 * label host. 3031 * For IPv6 this is a check against the label of the port.
2798 */ 3032 */
2799static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, 3033static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
2800 int size) 3034 int size)
2801{ 3035{
2802 struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; 3036 struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
3037 struct sockaddr *sap = (struct sockaddr *) msg->msg_name;
3038 int rc = 0;
2803 3039
2804 /* 3040 /*
2805 * Perfectly reasonable for this to be NULL 3041 * Perfectly reasonable for this to be NULL
2806 */ 3042 */
2807 if (sip == NULL || sip->sin_family != AF_INET) 3043 if (sip == NULL)
2808 return 0; 3044 return 0;
2809 3045
2810 return smack_netlabel_send(sock->sk, sip); 3046 switch (sip->sin_family) {
3047 case AF_INET:
3048 rc = smack_netlabel_send(sock->sk, sip);
3049 break;
3050 case AF_INET6:
3051 rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
3052 break;
3053 }
3054 return rc;
2811} 3055}
2812 3056
2813/** 3057/**
@@ -2815,13 +3059,12 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
2815 * @sap: netlabel secattr 3059 * @sap: netlabel secattr
2816 * @ssp: socket security information 3060 * @ssp: socket security information
2817 * 3061 *
2818 * Returns a pointer to a Smack label found on the label list. 3062 * Returns a pointer to a Smack label entry found on the label list.
2819 */ 3063 */
2820static char *smack_from_secattr(struct netlbl_lsm_secattr *sap, 3064static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2821 struct socket_smack *ssp) 3065 struct socket_smack *ssp)
2822{ 3066{
2823 struct smack_known *kp; 3067 struct smack_known *skp;
2824 char *sp;
2825 int found = 0; 3068 int found = 0;
2826 3069
2827 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { 3070 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
@@ -2836,11 +3079,11 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2836 * ambient value. 3079 * ambient value.
2837 */ 3080 */
2838 rcu_read_lock(); 3081 rcu_read_lock();
2839 list_for_each_entry(kp, &smack_known_list, list) { 3082 list_for_each_entry(skp, &smack_known_list, list) {
2840 if (sap->attr.mls.lvl != kp->smk_netlabel.attr.mls.lvl) 3083 if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl)
2841 continue; 3084 continue;
2842 if (memcmp(sap->attr.mls.cat, 3085 if (memcmp(sap->attr.mls.cat,
2843 kp->smk_netlabel.attr.mls.cat, 3086 skp->smk_netlabel.attr.mls.cat,
2844 SMK_CIPSOLEN) != 0) 3087 SMK_CIPSOLEN) != 0)
2845 continue; 3088 continue;
2846 found = 1; 3089 found = 1;
@@ -2849,17 +3092,17 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2849 rcu_read_unlock(); 3092 rcu_read_unlock();
2850 3093
2851 if (found) 3094 if (found)
2852 return kp->smk_known; 3095 return skp;
2853 3096
2854 if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known) 3097 if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known)
2855 return smack_known_web.smk_known; 3098 return &smack_known_web;
2856 return smack_known_star.smk_known; 3099 return &smack_known_star;
2857 } 3100 }
2858 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) { 3101 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) {
2859 /* 3102 /*
2860 * Looks like a fallback, which gives us a secid. 3103 * Looks like a fallback, which gives us a secid.
2861 */ 3104 */
2862 sp = smack_from_secid(sap->attr.secid); 3105 skp = smack_from_secid(sap->attr.secid);
2863 /* 3106 /*
2864 * This has got to be a bug because it is 3107 * This has got to be a bug because it is
2865 * impossible to specify a fallback without 3108 * impossible to specify a fallback without
@@ -2867,8 +3110,8 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2867 * it has a secid, and the only way to get a 3110 * it has a secid, and the only way to get a
2868 * secid is from a fallback. 3111 * secid is from a fallback.
2869 */ 3112 */
2870 BUG_ON(sp == NULL); 3113 BUG_ON(skp == NULL);
2871 return sp; 3114 return skp;
2872 } 3115 }
2873 /* 3116 /*
2874 * Without guidance regarding the smack value 3117 * Without guidance regarding the smack value
@@ -2878,6 +3121,54 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2878 return smack_net_ambient; 3121 return smack_net_ambient;
2879} 3122}
2880 3123
3124static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr *sap)
3125{
3126 struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
3127 u8 nexthdr;
3128 int offset;
3129 int proto = -EINVAL;
3130 struct ipv6hdr _ipv6h;
3131 struct ipv6hdr *ip6;
3132 __be16 frag_off;
3133 struct tcphdr _tcph, *th;
3134 struct udphdr _udph, *uh;
3135 struct dccp_hdr _dccph, *dh;
3136
3137 sip->sin6_port = 0;
3138
3139 offset = skb_network_offset(skb);
3140 ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
3141 if (ip6 == NULL)
3142 return -EINVAL;
3143 sip->sin6_addr = ip6->saddr;
3144
3145 nexthdr = ip6->nexthdr;
3146 offset += sizeof(_ipv6h);
3147 offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
3148 if (offset < 0)
3149 return -EINVAL;
3150
3151 proto = nexthdr;
3152 switch (proto) {
3153 case IPPROTO_TCP:
3154 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
3155 if (th != NULL)
3156 sip->sin6_port = th->source;
3157 break;
3158 case IPPROTO_UDP:
3159 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
3160 if (uh != NULL)
3161 sip->sin6_port = uh->source;
3162 break;
3163 case IPPROTO_DCCP:
3164 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
3165 if (dh != NULL)
3166 sip->sin6_port = dh->dccph_sport;
3167 break;
3168 }
3169 return proto;
3170}
3171
2881/** 3172/**
2882 * smack_socket_sock_rcv_skb - Smack packet delivery access check 3173 * smack_socket_sock_rcv_skb - Smack packet delivery access check
2883 * @sk: socket 3174 * @sk: socket
@@ -2889,43 +3180,52 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2889{ 3180{
2890 struct netlbl_lsm_secattr secattr; 3181 struct netlbl_lsm_secattr secattr;
2891 struct socket_smack *ssp = sk->sk_security; 3182 struct socket_smack *ssp = sk->sk_security;
2892 char *csp; 3183 struct smack_known *skp;
2893 int rc; 3184 struct sockaddr sadd;
3185 int rc = 0;
2894 struct smk_audit_info ad; 3186 struct smk_audit_info ad;
2895#ifdef CONFIG_AUDIT 3187#ifdef CONFIG_AUDIT
2896 struct lsm_network_audit net; 3188 struct lsm_network_audit net;
2897#endif 3189#endif
2898 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) 3190 switch (sk->sk_family) {
2899 return 0; 3191 case PF_INET:
2900 3192 /*
2901 /* 3193 * Translate what netlabel gave us.
2902 * Translate what netlabel gave us. 3194 */
2903 */ 3195 netlbl_secattr_init(&secattr);
2904 netlbl_secattr_init(&secattr);
2905 3196
2906 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); 3197 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
2907 if (rc == 0) 3198 if (rc == 0)
2908 csp = smack_from_secattr(&secattr, ssp); 3199 skp = smack_from_secattr(&secattr, ssp);
2909 else 3200 else
2910 csp = smack_net_ambient; 3201 skp = smack_net_ambient;
2911 3202
2912 netlbl_secattr_destroy(&secattr); 3203 netlbl_secattr_destroy(&secattr);
2913 3204
2914#ifdef CONFIG_AUDIT 3205#ifdef CONFIG_AUDIT
2915 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); 3206 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2916 ad.a.u.net->family = sk->sk_family; 3207 ad.a.u.net->family = sk->sk_family;
2917 ad.a.u.net->netif = skb->skb_iif; 3208 ad.a.u.net->netif = skb->skb_iif;
2918 ipv4_skb_to_auditdata(skb, &ad.a, NULL); 3209 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
2919#endif 3210#endif
2920 /* 3211 /*
2921 * Receiving a packet requires that the other end 3212 * Receiving a packet requires that the other end
2922 * be able to write here. Read access is not required. 3213 * be able to write here. Read access is not required.
2923 * This is the simplist possible security model 3214 * This is the simplist possible security model
2924 * for networking. 3215 * for networking.
2925 */ 3216 */
2926 rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad); 3217 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
2927 if (rc != 0) 3218 if (rc != 0)
2928 netlbl_skbuff_err(skb, rc, 0); 3219 netlbl_skbuff_err(skb, rc, 0);
3220 break;
3221 case PF_INET6:
3222 rc = smk_skb_to_addr_ipv6(skb, &sadd);
3223 if (rc == IPPROTO_UDP || rc == IPPROTO_TCP)
3224 rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING);
3225 else
3226 rc = 0;
3227 break;
3228 }
2929 return rc; 3229 return rc;
2930} 3230}
2931 3231
@@ -2979,7 +3279,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
2979{ 3279{
2980 struct netlbl_lsm_secattr secattr; 3280 struct netlbl_lsm_secattr secattr;
2981 struct socket_smack *ssp = NULL; 3281 struct socket_smack *ssp = NULL;
2982 char *sp; 3282 struct smack_known *skp;
2983 int family = PF_UNSPEC; 3283 int family = PF_UNSPEC;
2984 u32 s = 0; /* 0 is the invalid secid */ 3284 u32 s = 0; /* 0 is the invalid secid */
2985 int rc; 3285 int rc;
@@ -2995,7 +3295,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
2995 3295
2996 if (family == PF_UNIX) { 3296 if (family == PF_UNIX) {
2997 ssp = sock->sk->sk_security; 3297 ssp = sock->sk->sk_security;
2998 s = smack_to_secid(ssp->smk_out); 3298 s = ssp->smk_out->smk_secid;
2999 } else if (family == PF_INET || family == PF_INET6) { 3299 } else if (family == PF_INET || family == PF_INET6) {
3000 /* 3300 /*
3001 * Translate what netlabel gave us. 3301 * Translate what netlabel gave us.
@@ -3005,8 +3305,8 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
3005 netlbl_secattr_init(&secattr); 3305 netlbl_secattr_init(&secattr);
3006 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3306 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3007 if (rc == 0) { 3307 if (rc == 0) {
3008 sp = smack_from_secattr(&secattr, ssp); 3308 skp = smack_from_secattr(&secattr, ssp);
3009 s = smack_to_secid(sp); 3309 s = skp->smk_secid;
3010 } 3310 }
3011 netlbl_secattr_destroy(&secattr); 3311 netlbl_secattr_destroy(&secattr);
3012 } 3312 }
@@ -3027,13 +3327,15 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
3027static void smack_sock_graft(struct sock *sk, struct socket *parent) 3327static void smack_sock_graft(struct sock *sk, struct socket *parent)
3028{ 3328{
3029 struct socket_smack *ssp; 3329 struct socket_smack *ssp;
3330 struct smack_known *skp = smk_of_current();
3030 3331
3031 if (sk == NULL || 3332 if (sk == NULL ||
3032 (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)) 3333 (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
3033 return; 3334 return;
3034 3335
3035 ssp = sk->sk_security; 3336 ssp = sk->sk_security;
3036 ssp->smk_in = ssp->smk_out = smk_of_current(); 3337 ssp->smk_in = skp->smk_known;
3338 ssp->smk_out = skp;
3037 /* cssp->smk_packet is already set in smack_inet_csk_clone() */ 3339 /* cssp->smk_packet is already set in smack_inet_csk_clone() */
3038} 3340}
3039 3341
@@ -3055,7 +3357,6 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3055 struct netlbl_lsm_secattr secattr; 3357 struct netlbl_lsm_secattr secattr;
3056 struct sockaddr_in addr; 3358 struct sockaddr_in addr;
3057 struct iphdr *hdr; 3359 struct iphdr *hdr;
3058 char *sp;
3059 char *hsp; 3360 char *hsp;
3060 int rc; 3361 int rc;
3061 struct smk_audit_info ad; 3362 struct smk_audit_info ad;
@@ -3063,16 +3364,24 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3063 struct lsm_network_audit net; 3364 struct lsm_network_audit net;
3064#endif 3365#endif
3065 3366
3066 /* handle mapped IPv4 packets arriving via IPv6 sockets */ 3367 if (family == PF_INET6) {
3067 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) 3368 /*
3068 family = PF_INET; 3369 * Handle mapped IPv4 packets arriving
3370 * via IPv6 sockets. Don't set up netlabel
3371 * processing on IPv6.
3372 */
3373 if (skb->protocol == htons(ETH_P_IP))
3374 family = PF_INET;
3375 else
3376 return 0;
3377 }
3069 3378
3070 netlbl_secattr_init(&secattr); 3379 netlbl_secattr_init(&secattr);
3071 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3380 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3072 if (rc == 0) 3381 if (rc == 0)
3073 sp = smack_from_secattr(&secattr, ssp); 3382 skp = smack_from_secattr(&secattr, ssp);
3074 else 3383 else
3075 sp = smack_known_huh.smk_known; 3384 skp = &smack_known_huh;
3076 netlbl_secattr_destroy(&secattr); 3385 netlbl_secattr_destroy(&secattr);
3077 3386
3078#ifdef CONFIG_AUDIT 3387#ifdef CONFIG_AUDIT
@@ -3085,7 +3394,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3085 * Receiving a packet requires that the other end be able to write 3394 * Receiving a packet requires that the other end be able to write
3086 * here. Read access is not required. 3395 * here. Read access is not required.
3087 */ 3396 */
3088 rc = smk_access(sp, ssp->smk_in, MAY_WRITE, &ad); 3397 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
3089 if (rc != 0) 3398 if (rc != 0)
3090 return rc; 3399 return rc;
3091 3400
@@ -3093,7 +3402,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3093 * Save the peer's label in the request_sock so we can later setup 3402 * Save the peer's label in the request_sock so we can later setup
3094 * smk_packet in the child socket so that SO_PEERCRED can report it. 3403 * smk_packet in the child socket so that SO_PEERCRED can report it.
3095 */ 3404 */
3096 req->peer_secid = smack_to_secid(sp); 3405 req->peer_secid = skp->smk_secid;
3097 3406
3098 /* 3407 /*
3099 * We need to decide if we want to label the incoming connection here 3408 * We need to decide if we want to label the incoming connection here
@@ -3106,10 +3415,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3106 hsp = smack_host_label(&addr); 3415 hsp = smack_host_label(&addr);
3107 rcu_read_unlock(); 3416 rcu_read_unlock();
3108 3417
3109 if (hsp == NULL) { 3418 if (hsp == NULL)
3110 skp = smk_find_entry(sp);
3111 rc = netlbl_req_setattr(req, &skp->smk_netlabel); 3419 rc = netlbl_req_setattr(req, &skp->smk_netlabel);
3112 } else 3420 else
3113 netlbl_req_delattr(req); 3421 netlbl_req_delattr(req);
3114 3422
3115 return rc; 3423 return rc;
@@ -3126,10 +3434,12 @@ static void smack_inet_csk_clone(struct sock *sk,
3126 const struct request_sock *req) 3434 const struct request_sock *req)
3127{ 3435{
3128 struct socket_smack *ssp = sk->sk_security; 3436 struct socket_smack *ssp = sk->sk_security;
3437 struct smack_known *skp;
3129 3438
3130 if (req->peer_secid != 0) 3439 if (req->peer_secid != 0) {
3131 ssp->smk_packet = smack_from_secid(req->peer_secid); 3440 skp = smack_from_secid(req->peer_secid);
3132 else 3441 ssp->smk_packet = skp->smk_known;
3442 } else
3133 ssp->smk_packet = NULL; 3443 ssp->smk_packet = NULL;
3134} 3444}
3135 3445
@@ -3155,7 +3465,9 @@ static void smack_inet_csk_clone(struct sock *sk,
3155static int smack_key_alloc(struct key *key, const struct cred *cred, 3465static int smack_key_alloc(struct key *key, const struct cred *cred,
3156 unsigned long flags) 3466 unsigned long flags)
3157{ 3467{
3158 key->security = smk_of_task(cred->security); 3468 struct smack_known *skp = smk_of_task(cred->security);
3469
3470 key->security = skp->smk_known;
3159 return 0; 3471 return 0;
3160} 3472}
3161 3473
@@ -3184,7 +3496,7 @@ static int smack_key_permission(key_ref_t key_ref,
3184{ 3496{
3185 struct key *keyp; 3497 struct key *keyp;
3186 struct smk_audit_info ad; 3498 struct smk_audit_info ad;
3187 char *tsp = smk_of_task(cred->security); 3499 struct smack_known *tkp = smk_of_task(cred->security);
3188 3500
3189 keyp = key_ref_to_ptr(key_ref); 3501 keyp = key_ref_to_ptr(key_ref);
3190 if (keyp == NULL) 3502 if (keyp == NULL)
@@ -3198,15 +3510,14 @@ static int smack_key_permission(key_ref_t key_ref,
3198 /* 3510 /*
3199 * This should not occur 3511 * This should not occur
3200 */ 3512 */
3201 if (tsp == NULL) 3513 if (tkp == NULL)
3202 return -EACCES; 3514 return -EACCES;
3203#ifdef CONFIG_AUDIT 3515#ifdef CONFIG_AUDIT
3204 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); 3516 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
3205 ad.a.u.key_struct.key = keyp->serial; 3517 ad.a.u.key_struct.key = keyp->serial;
3206 ad.a.u.key_struct.key_desc = keyp->description; 3518 ad.a.u.key_struct.key_desc = keyp->description;
3207#endif 3519#endif
3208 return smk_access(tsp, keyp->security, 3520 return smk_access(tkp, keyp->security, MAY_READWRITE, &ad);
3209 MAY_READWRITE, &ad);
3210} 3521}
3211#endif /* CONFIG_KEYS */ 3522#endif /* CONFIG_KEYS */
3212 3523
@@ -3288,7 +3599,7 @@ static int smack_audit_rule_known(struct audit_krule *krule)
3288static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, 3599static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3289 struct audit_context *actx) 3600 struct audit_context *actx)
3290{ 3601{
3291 char *smack; 3602 struct smack_known *skp;
3292 char *rule = vrule; 3603 char *rule = vrule;
3293 3604
3294 if (!rule) { 3605 if (!rule) {
@@ -3300,7 +3611,7 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3300 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER) 3611 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
3301 return 0; 3612 return 0;
3302 3613
3303 smack = smack_from_secid(secid); 3614 skp = smack_from_secid(secid);
3304 3615
3305 /* 3616 /*
3306 * No need to do string comparisons. If a match occurs, 3617 * No need to do string comparisons. If a match occurs,
@@ -3308,9 +3619,9 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
3308 * label. 3619 * label.
3309 */ 3620 */
3310 if (op == Audit_equal) 3621 if (op == Audit_equal)
3311 return (rule == smack); 3622 return (rule == skp->smk_known);
3312 if (op == Audit_not_equal) 3623 if (op == Audit_not_equal)
3313 return (rule != smack); 3624 return (rule != skp->smk_known);
3314 3625
3315 return 0; 3626 return 0;
3316} 3627}
@@ -3338,11 +3649,11 @@ static void smack_audit_rule_free(void *vrule)
3338 */ 3649 */
3339static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 3650static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
3340{ 3651{
3341 char *sp = smack_from_secid(secid); 3652 struct smack_known *skp = smack_from_secid(secid);
3342 3653
3343 if (secdata) 3654 if (secdata)
3344 *secdata = sp; 3655 *secdata = skp->smk_known;
3345 *seclen = strlen(sp); 3656 *seclen = strlen(skp->smk_known);
3346 return 0; 3657 return 0;
3347} 3658}
3348 3659
@@ -3498,6 +3809,7 @@ struct security_operations smack_ops = {
3498 .unix_may_send = smack_unix_may_send, 3809 .unix_may_send = smack_unix_may_send,
3499 3810
3500 .socket_post_create = smack_socket_post_create, 3811 .socket_post_create = smack_socket_post_create,
3812 .socket_bind = smack_socket_bind,
3501 .socket_connect = smack_socket_connect, 3813 .socket_connect = smack_socket_connect,
3502 .socket_sendmsg = smack_socket_sendmsg, 3814 .socket_sendmsg = smack_socket_sendmsg,
3503 .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, 3815 .socket_sock_rcv_skb = smack_socket_sock_rcv_skb,
@@ -3577,8 +3889,8 @@ static __init int smack_init(void)
3577 if (!security_module_enable(&smack_ops)) 3889 if (!security_module_enable(&smack_ops))
3578 return 0; 3890 return 0;
3579 3891
3580 tsp = new_task_smack(smack_known_floor.smk_known, 3892 tsp = new_task_smack(&smack_known_floor, &smack_known_floor,
3581 smack_known_floor.smk_known, GFP_KERNEL); 3893 GFP_KERNEL);
3582 if (tsp == NULL) 3894 if (tsp == NULL)
3583 return -ENOMEM; 3895 return -ENOMEM;
3584 3896
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 53a08b85bda4..ab167037b2dd 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -66,7 +66,7 @@ static DEFINE_MUTEX(smk_netlbladdr_lock);
66 * If it isn't somehow marked, use this. 66 * If it isn't somehow marked, use this.
67 * It can be reset via smackfs/ambient 67 * It can be reset via smackfs/ambient
68 */ 68 */
69char *smack_net_ambient; 69struct smack_known *smack_net_ambient;
70 70
71/* 71/*
72 * This is the level in a CIPSO header that indicates a 72 * This is the level in a CIPSO header that indicates a
@@ -112,7 +112,7 @@ struct smack_master_list {
112LIST_HEAD(smack_rule_list); 112LIST_HEAD(smack_rule_list);
113 113
114struct smack_parsed_rule { 114struct smack_parsed_rule {
115 char *smk_subject; 115 struct smack_known *smk_subject;
116 char *smk_object; 116 char *smk_object;
117 int smk_access1; 117 int smk_access1;
118 int smk_access2; 118 int smk_access2;
@@ -163,9 +163,11 @@ static inline void smack_catset_bit(unsigned int cat, char *catsetp)
163 */ 163 */
164static void smk_netlabel_audit_set(struct netlbl_audit *nap) 164static void smk_netlabel_audit_set(struct netlbl_audit *nap)
165{ 165{
166 struct smack_known *skp = smk_of_current();
167
166 nap->loginuid = audit_get_loginuid(current); 168 nap->loginuid = audit_get_loginuid(current);
167 nap->sessionid = audit_get_sessionid(current); 169 nap->sessionid = audit_get_sessionid(current);
168 nap->secid = smack_to_secid(smk_of_current()); 170 nap->secid = skp->smk_secid;
169} 171}
170 172
171/* 173/*
@@ -306,7 +308,7 @@ static int smk_fill_rule(const char *subject, const char *object,
306 struct smack_known *skp; 308 struct smack_known *skp;
307 309
308 if (import) { 310 if (import) {
309 rule->smk_subject = smk_import(subject, len); 311 rule->smk_subject = smk_import_entry(subject, len);
310 if (rule->smk_subject == NULL) 312 if (rule->smk_subject == NULL)
311 return -1; 313 return -1;
312 314
@@ -321,7 +323,7 @@ static int smk_fill_rule(const char *subject, const char *object,
321 kfree(cp); 323 kfree(cp);
322 if (skp == NULL) 324 if (skp == NULL)
323 return -1; 325 return -1;
324 rule->smk_subject = skp->smk_known; 326 rule->smk_subject = skp;
325 327
326 cp = smk_parse_smack(object, len); 328 cp = smk_parse_smack(object, len);
327 if (cp == NULL) 329 if (cp == NULL)
@@ -445,7 +447,6 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
445 struct list_head *rule_list, 447 struct list_head *rule_list,
446 struct mutex *rule_lock, int format) 448 struct mutex *rule_lock, int format)
447{ 449{
448 struct smack_known *skp;
449 struct smack_parsed_rule *rule; 450 struct smack_parsed_rule *rule;
450 char *data; 451 char *data;
451 int datalen; 452 int datalen;
@@ -505,12 +506,10 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
505 goto out_free_rule; 506 goto out_free_rule;
506 } 507 }
507 508
508
509 if (rule_list == NULL) { 509 if (rule_list == NULL) {
510 load = 1; 510 load = 1;
511 skp = smk_find_entry(rule->smk_subject); 511 rule_list = &rule->smk_subject->smk_rules;
512 rule_list = &skp->smk_rules; 512 rule_lock = &rule->smk_subject->smk_rules_lock;
513 rule_lock = &skp->smk_rules_lock;
514 } 513 }
515 514
516 rc = smk_set_access(rule, rule_list, rule_lock, load); 515 rc = smk_set_access(rule, rule_list, rule_lock, load);
@@ -579,13 +578,14 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
579 * because you should expect to be able to write 578 * because you should expect to be able to write
580 * anything you read back. 579 * anything you read back.
581 */ 580 */
582 if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) 581 if (strlen(srp->smk_subject->smk_known) >= max ||
582 strlen(srp->smk_object) >= max)
583 return; 583 return;
584 584
585 if (srp->smk_access == 0) 585 if (srp->smk_access == 0)
586 return; 586 return;
587 587
588 seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); 588 seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object);
589 589
590 seq_putc(s, ' '); 590 seq_putc(s, ' ');
591 591
@@ -738,9 +738,9 @@ static void smk_unlbl_ambient(char *oldambient)
738 __func__, __LINE__, rc); 738 __func__, __LINE__, rc);
739 } 739 }
740 if (smack_net_ambient == NULL) 740 if (smack_net_ambient == NULL)
741 smack_net_ambient = smack_known_floor.smk_known; 741 smack_net_ambient = &smack_known_floor;
742 742
743 rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET, 743 rc = netlbl_cfg_unlbl_map_add(smack_net_ambient->smk_known, PF_INET,
744 NULL, NULL, &nai); 744 NULL, NULL, &nai);
745 if (rc != 0) 745 if (rc != 0)
746 printk(KERN_WARNING "%s:%d add rc = %d\n", 746 printk(KERN_WARNING "%s:%d add rc = %d\n",
@@ -881,7 +881,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
881 if (format == SMK_FIXED24_FMT) 881 if (format == SMK_FIXED24_FMT)
882 rule += SMK_LABELLEN; 882 rule += SMK_LABELLEN;
883 else 883 else
884 rule += strlen(skp->smk_known); 884 rule += strlen(skp->smk_known) + 1;
885 885
886 ret = sscanf(rule, "%d", &maplevel); 886 ret = sscanf(rule, "%d", &maplevel);
887 if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL) 887 if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL)
@@ -1535,11 +1535,12 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
1535 */ 1535 */
1536 mutex_lock(&smack_ambient_lock); 1536 mutex_lock(&smack_ambient_lock);
1537 1537
1538 asize = strlen(smack_net_ambient) + 1; 1538 asize = strlen(smack_net_ambient->smk_known) + 1;
1539 1539
1540 if (cn >= asize) 1540 if (cn >= asize)
1541 rc = simple_read_from_buffer(buf, cn, ppos, 1541 rc = simple_read_from_buffer(buf, cn, ppos,
1542 smack_net_ambient, asize); 1542 smack_net_ambient->smk_known,
1543 asize);
1543 else 1544 else
1544 rc = -EINVAL; 1545 rc = -EINVAL;
1545 1546
@@ -1560,8 +1561,8 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
1560static ssize_t smk_write_ambient(struct file *file, const char __user *buf, 1561static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1561 size_t count, loff_t *ppos) 1562 size_t count, loff_t *ppos)
1562{ 1563{
1564 struct smack_known *skp;
1563 char *oldambient; 1565 char *oldambient;
1564 char *smack = NULL;
1565 char *data; 1566 char *data;
1566 int rc = count; 1567 int rc = count;
1567 1568
@@ -1577,16 +1578,16 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1577 goto out; 1578 goto out;
1578 } 1579 }
1579 1580
1580 smack = smk_import(data, count); 1581 skp = smk_import_entry(data, count);
1581 if (smack == NULL) { 1582 if (skp == NULL) {
1582 rc = -EINVAL; 1583 rc = -EINVAL;
1583 goto out; 1584 goto out;
1584 } 1585 }
1585 1586
1586 mutex_lock(&smack_ambient_lock); 1587 mutex_lock(&smack_ambient_lock);
1587 1588
1588 oldambient = smack_net_ambient; 1589 oldambient = smack_net_ambient->smk_known;
1589 smack_net_ambient = smack; 1590 smack_net_ambient = skp;
1590 smk_unlbl_ambient(oldambient); 1591 smk_unlbl_ambient(oldambient);
1591 1592
1592 mutex_unlock(&smack_ambient_lock); 1593 mutex_unlock(&smack_ambient_lock);
@@ -1645,7 +1646,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1645 size_t count, loff_t *ppos) 1646 size_t count, loff_t *ppos)
1646{ 1647{
1647 char *data; 1648 char *data;
1648 char *sp = smk_of_task(current->cred->security); 1649 struct smack_known *skp = smk_of_task(current->cred->security);
1649 int rc = count; 1650 int rc = count;
1650 1651
1651 if (!smack_privileged(CAP_MAC_ADMIN)) 1652 if (!smack_privileged(CAP_MAC_ADMIN))
@@ -1656,7 +1657,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1656 * explicitly for clarity. The smk_access() implementation 1657 * explicitly for clarity. The smk_access() implementation
1657 * would use smk_access(smack_onlycap, MAY_WRITE) 1658 * would use smk_access(smack_onlycap, MAY_WRITE)
1658 */ 1659 */
1659 if (smack_onlycap != NULL && smack_onlycap != sp) 1660 if (smack_onlycap != NULL && smack_onlycap != skp->smk_known)
1660 return -EPERM; 1661 return -EPERM;
1661 1662
1662 data = kzalloc(count, GFP_KERNEL); 1663 data = kzalloc(count, GFP_KERNEL);
@@ -1866,8 +1867,8 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
1866 if (res) 1867 if (res)
1867 return -EINVAL; 1868 return -EINVAL;
1868 1869
1869 res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access1, 1870 res = smk_access(rule.smk_subject, rule.smk_object,
1870 NULL); 1871 rule.smk_access1, NULL);
1871 data[0] = res == 0 ? '1' : '0'; 1872 data[0] = res == 0 ? '1' : '0';
1872 data[1] = '\0'; 1873 data[1] = '\0';
1873 1874