aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-11 00:51:23 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-11 00:51:23 -0500
commite7691a1ce341c80ed9504244a36b31c025217391 (patch)
treee9941bb350f64a726130e299c411821da6f41a53 /security
parent5cd9599bba428762025db6027764f1c59d0b1e1b (diff)
parent8fcc99549522fc7a0bbaeb5755855ab0d9a59ce8 (diff)
Merge branch 'for-linus' of git://selinuxproject.org/~jmorris/linux-security
* 'for-linus' of git://selinuxproject.org/~jmorris/linux-security: (32 commits) ima: fix invalid memory reference ima: free duplicate measurement memory security: update security_file_mmap() docs selinux: Casting (void *) value returned by kmalloc is useless apparmor: fix module parameter handling Security: tomoyo: add .gitignore file tomoyo: add missing rcu_dereference() apparmor: add missing rcu_dereference() evm: prevent racing during tfm allocation evm: key must be set once during initialization mpi/mpi-mpow: NULL dereference on allocation failure digsig: build dependency fix KEYS: Give key types their own lockdep class for key->sem TPM: fix transmit_cmd error logic TPM: NSC and TIS drivers X86 dependency fix TPM: Export wait_for_stat for other vendor specific drivers TPM: Use vendor specific function for status probe tpm_tis: add delay after aborting command tpm_tis: Check return code from getting timeouts/durations tpm: Introduce function to poll for result of self test ... Fix up trivial conflict in lib/Makefile due to addition of CONFIG_MPI and SIGSIG next to CONFIG_DQL addition.
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/audit.c2
-rw-r--r--security/apparmor/lsm.c6
-rw-r--r--security/integrity/Kconfig14
-rw-r--r--security/integrity/Makefile1
-rw-r--r--security/integrity/digsig.c48
-rw-r--r--security/integrity/evm/evm.h12
-rw-r--r--security/integrity/evm/evm_crypto.c76
-rw-r--r--security/integrity/evm/evm_main.c94
-rw-r--r--security/integrity/ima/ima_api.c4
-rw-r--r--security/integrity/ima/ima_queue.c17
-rw-r--r--security/integrity/integrity.h21
-rw-r--r--security/keys/key.c3
-rw-r--r--security/selinux/selinuxfs.c14
-rw-r--r--security/selinux/ss/conditional.c2
-rw-r--r--security/tomoyo/.gitignore2
-rw-r--r--security/tomoyo/common.h2
16 files changed, 259 insertions, 59 deletions
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 96502b22b268..f3fafedd798a 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -133,7 +133,7 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
133 struct aa_profile *profile = sa->aad.profile; 133 struct aa_profile *profile = sa->aad.profile;
134 pid_t pid; 134 pid_t pid;
135 rcu_read_lock(); 135 rcu_read_lock();
136 pid = tsk->real_parent->pid; 136 pid = rcu_dereference(tsk->real_parent)->pid;
137 rcu_read_unlock(); 137 rcu_read_unlock();
138 audit_log_format(ab, " parent=%d", pid); 138 audit_log_format(ab, " parent=%d", pid);
139 if (profile->ns != root_ns) { 139 if (profile->ns != root_ns) {
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 2c0a0ff41399..d7f06f8b2837 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -670,7 +670,7 @@ static struct security_operations apparmor_ops = {
670 670
671static int param_set_aabool(const char *val, const struct kernel_param *kp); 671static int param_set_aabool(const char *val, const struct kernel_param *kp);
672static int param_get_aabool(char *buffer, const struct kernel_param *kp); 672static int param_get_aabool(char *buffer, const struct kernel_param *kp);
673#define param_check_aabool(name, p) __param_check(name, p, int) 673#define param_check_aabool param_check_bool
674static struct kernel_param_ops param_ops_aabool = { 674static struct kernel_param_ops param_ops_aabool = {
675 .set = param_set_aabool, 675 .set = param_set_aabool,
676 .get = param_get_aabool 676 .get = param_get_aabool
@@ -678,7 +678,7 @@ static struct kernel_param_ops param_ops_aabool = {
678 678
679static int param_set_aauint(const char *val, const struct kernel_param *kp); 679static int param_set_aauint(const char *val, const struct kernel_param *kp);
680static int param_get_aauint(char *buffer, const struct kernel_param *kp); 680static int param_get_aauint(char *buffer, const struct kernel_param *kp);
681#define param_check_aauint(name, p) __param_check(name, p, int) 681#define param_check_aauint param_check_uint
682static struct kernel_param_ops param_ops_aauint = { 682static struct kernel_param_ops param_ops_aauint = {
683 .set = param_set_aauint, 683 .set = param_set_aauint,
684 .get = param_get_aauint 684 .get = param_get_aauint
@@ -686,7 +686,7 @@ static struct kernel_param_ops param_ops_aauint = {
686 686
687static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp); 687static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp);
688static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp); 688static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp);
689#define param_check_aalockpolicy(name, p) __param_check(name, p, int) 689#define param_check_aalockpolicy param_check_bool
690static struct kernel_param_ops param_ops_aalockpolicy = { 690static struct kernel_param_ops param_ops_aalockpolicy = {
691 .set = param_set_aalockpolicy, 691 .set = param_set_aalockpolicy,
692 .get = param_get_aalockpolicy 692 .get = param_get_aalockpolicy
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 4bf00acf7937..d384ea921482 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -3,5 +3,19 @@ config INTEGRITY
3 def_bool y 3 def_bool y
4 depends on IMA || EVM 4 depends on IMA || EVM
5 5
6config INTEGRITY_DIGSIG
7 boolean "Digital signature verification using multiple keyrings"
8 depends on INTEGRITY && KEYS
9 default n
10 select DIGSIG
11 help
12 This option enables digital signature verification support
13 using multiple keyrings. It defines separate keyrings for each
14 of the different use cases - evm, ima, and modules.
15 Different keyrings improves search performance, but also allow
16 to "lock" certain keyring to prevent adding new keys.
17 This is useful for evm and module keyrings, when keys are
18 usually only added from initramfs.
19
6source security/integrity/ima/Kconfig 20source security/integrity/ima/Kconfig
7source security/integrity/evm/Kconfig 21source security/integrity/evm/Kconfig
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index 0ae44aea6516..bece0563ee5e 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_DIGSIG) += digsig.o
6 7
7integrity-y := iint.o 8integrity-y := iint.o
8 9
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
new file mode 100644
index 000000000000..2dc167d7cde9
--- /dev/null
+++ b/security/integrity/digsig.c
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2011 Intel Corporation
3 *
4 * Author:
5 * Dmitry Kasatkin <dmitry.kasatkin@intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 *
11 */
12
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15#include <linux/err.h>
16#include <linux/rbtree.h>
17#include <linux/key-type.h>
18#include <linux/digsig.h>
19
20#include "integrity.h"
21
22static struct key *keyring[INTEGRITY_KEYRING_MAX];
23
24static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
25 "_evm",
26 "_module",
27 "_ima",
28};
29
30int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
31 const char *digest, int digestlen)
32{
33 if (id >= INTEGRITY_KEYRING_MAX)
34 return -EINVAL;
35
36 if (!keyring[id]) {
37 keyring[id] =
38 request_key(&key_type_keyring, keyring_name[id], NULL);
39 if (IS_ERR(keyring[id])) {
40 int err = PTR_ERR(keyring[id]);
41 pr_err("no %s keyring: %d\n", keyring_name[id], err);
42 keyring[id] = NULL;
43 return err;
44 }
45 }
46
47 return digsig_verify(keyring[id], sig, siglen, digest, digestlen);
48}
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index d320f5197437..c885247ebcf7 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -12,14 +12,21 @@
12 * File: evm.h 12 * File: evm.h
13 * 13 *
14 */ 14 */
15
16#ifndef __INTEGRITY_EVM_H
17#define __INTEGRITY_EVM_H
18
15#include <linux/xattr.h> 19#include <linux/xattr.h>
16#include <linux/security.h> 20#include <linux/security.h>
21
17#include "../integrity.h" 22#include "../integrity.h"
18 23
19extern int evm_initialized; 24extern int evm_initialized;
20extern char *evm_hmac; 25extern char *evm_hmac;
26extern char *evm_hash;
21 27
22extern struct crypto_shash *hmac_tfm; 28extern struct crypto_shash *hmac_tfm;
29extern struct crypto_shash *hash_tfm;
23 30
24/* List of EVM protected security xattrs */ 31/* List of EVM protected security xattrs */
25extern char *evm_config_xattrnames[]; 32extern char *evm_config_xattrnames[];
@@ -32,7 +39,12 @@ extern int evm_update_evmxattr(struct dentry *dentry,
32extern int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, 39extern int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
33 const char *req_xattr_value, 40 const char *req_xattr_value,
34 size_t req_xattr_value_len, char *digest); 41 size_t req_xattr_value_len, char *digest);
42extern int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
43 const char *req_xattr_value,
44 size_t req_xattr_value_len, char *digest);
35extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr, 45extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr,
36 char *hmac_val); 46 char *hmac_val);
37extern int evm_init_secfs(void); 47extern int evm_init_secfs(void);
38extern void evm_cleanup_secfs(void); 48extern void evm_cleanup_secfs(void);
49
50#endif
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 8738deff26fa..49a464f5595b 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -26,44 +26,56 @@ static unsigned char evmkey[MAX_KEY_SIZE];
26static int evmkey_len = MAX_KEY_SIZE; 26static int evmkey_len = MAX_KEY_SIZE;
27 27
28struct crypto_shash *hmac_tfm; 28struct crypto_shash *hmac_tfm;
29struct crypto_shash *hash_tfm;
29 30
30static DEFINE_MUTEX(mutex); 31static DEFINE_MUTEX(mutex);
31 32
32static struct shash_desc *init_desc(void) 33static struct shash_desc *init_desc(char type)
33{ 34{
34 int rc; 35 long rc;
36 char *algo;
37 struct crypto_shash **tfm;
35 struct shash_desc *desc; 38 struct shash_desc *desc;
36 39
37 if (hmac_tfm == NULL) { 40 if (type == EVM_XATTR_HMAC) {
41 tfm = &hmac_tfm;
42 algo = evm_hmac;
43 } else {
44 tfm = &hash_tfm;
45 algo = evm_hash;
46 }
47
48 if (*tfm == NULL) {
38 mutex_lock(&mutex); 49 mutex_lock(&mutex);
39 if (hmac_tfm) 50 if (*tfm)
40 goto out; 51 goto out;
41 hmac_tfm = crypto_alloc_shash(evm_hmac, 0, CRYPTO_ALG_ASYNC); 52 *tfm = crypto_alloc_shash(algo, 0, CRYPTO_ALG_ASYNC);
42 if (IS_ERR(hmac_tfm)) { 53 if (IS_ERR(*tfm)) {
43 pr_err("Can not allocate %s (reason: %ld)\n", 54 rc = PTR_ERR(*tfm);
44 evm_hmac, PTR_ERR(hmac_tfm)); 55 pr_err("Can not allocate %s (reason: %ld)\n", algo, rc);
45 rc = PTR_ERR(hmac_tfm); 56 *tfm = NULL;
46 hmac_tfm = NULL;
47 mutex_unlock(&mutex); 57 mutex_unlock(&mutex);
48 return ERR_PTR(rc); 58 return ERR_PTR(rc);
49 } 59 }
50 rc = crypto_shash_setkey(hmac_tfm, evmkey, evmkey_len); 60 if (type == EVM_XATTR_HMAC) {
51 if (rc) { 61 rc = crypto_shash_setkey(*tfm, evmkey, evmkey_len);
52 crypto_free_shash(hmac_tfm); 62 if (rc) {
53 hmac_tfm = NULL; 63 crypto_free_shash(*tfm);
54 mutex_unlock(&mutex); 64 *tfm = NULL;
55 return ERR_PTR(rc); 65 mutex_unlock(&mutex);
66 return ERR_PTR(rc);
67 }
56 } 68 }
57out: 69out:
58 mutex_unlock(&mutex); 70 mutex_unlock(&mutex);
59 } 71 }
60 72
61 desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac_tfm), 73 desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm),
62 GFP_KERNEL); 74 GFP_KERNEL);
63 if (!desc) 75 if (!desc)
64 return ERR_PTR(-ENOMEM); 76 return ERR_PTR(-ENOMEM);
65 77
66 desc->tfm = hmac_tfm; 78 desc->tfm = *tfm;
67 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 79 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
68 80
69 rc = crypto_shash_init(desc); 81 rc = crypto_shash_init(desc);
@@ -108,9 +120,11 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
108 * the hmac using the requested xattr value. Don't alloc/free memory for 120 * the hmac using the requested xattr value. Don't alloc/free memory for
109 * each xattr, but attempt to re-use the previously allocated memory. 121 * each xattr, but attempt to re-use the previously allocated memory.
110 */ 122 */
111int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, 123static int evm_calc_hmac_or_hash(struct dentry *dentry,
112 const char *req_xattr_value, size_t req_xattr_value_len, 124 const char *req_xattr_name,
113 char *digest) 125 const char *req_xattr_value,
126 size_t req_xattr_value_len,
127 char type, char *digest)
114{ 128{
115 struct inode *inode = dentry->d_inode; 129 struct inode *inode = dentry->d_inode;
116 struct shash_desc *desc; 130 struct shash_desc *desc;
@@ -122,7 +136,7 @@ int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
122 136
123 if (!inode->i_op || !inode->i_op->getxattr) 137 if (!inode->i_op || !inode->i_op->getxattr)
124 return -EOPNOTSUPP; 138 return -EOPNOTSUPP;
125 desc = init_desc(); 139 desc = init_desc(type);
126 if (IS_ERR(desc)) 140 if (IS_ERR(desc))
127 return PTR_ERR(desc); 141 return PTR_ERR(desc);
128 142
@@ -156,6 +170,22 @@ out:
156 return error; 170 return error;
157} 171}
158 172
173int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
174 const char *req_xattr_value, size_t req_xattr_value_len,
175 char *digest)
176{
177 return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
178 req_xattr_value_len, EVM_XATTR_HMAC, digest);
179}
180
181int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
182 const char *req_xattr_value, size_t req_xattr_value_len,
183 char *digest)
184{
185 return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
186 req_xattr_value_len, IMA_XATTR_DIGEST, digest);
187}
188
159/* 189/*
160 * Calculate the hmac and update security.evm xattr 190 * Calculate the hmac and update security.evm xattr
161 * 191 *
@@ -186,7 +216,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
186{ 216{
187 struct shash_desc *desc; 217 struct shash_desc *desc;
188 218
189 desc = init_desc(); 219 desc = init_desc(EVM_XATTR_HMAC);
190 if (IS_ERR(desc)) { 220 if (IS_ERR(desc)) {
191 printk(KERN_INFO "init_desc failed\n"); 221 printk(KERN_INFO "init_desc failed\n");
192 return PTR_ERR(desc); 222 return PTR_ERR(desc);
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 92d3d99a9f7b..8901501425f4 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -25,6 +25,7 @@
25int evm_initialized; 25int evm_initialized;
26 26
27char *evm_hmac = "hmac(sha1)"; 27char *evm_hmac = "hmac(sha1)";
28char *evm_hash = "sha1";
28 29
29char *evm_config_xattrnames[] = { 30char *evm_config_xattrnames[] = {
30#ifdef CONFIG_SECURITY_SELINUX 31#ifdef CONFIG_SECURITY_SELINUX
@@ -46,6 +47,29 @@ static int __init evm_set_fixmode(char *str)
46} 47}
47__setup("evm=", evm_set_fixmode); 48__setup("evm=", evm_set_fixmode);
48 49
50static int evm_find_protected_xattrs(struct dentry *dentry)
51{
52 struct inode *inode = dentry->d_inode;
53 char **xattr;
54 int error;
55 int count = 0;
56
57 if (!inode->i_op || !inode->i_op->getxattr)
58 return -EOPNOTSUPP;
59
60 for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) {
61 error = inode->i_op->getxattr(dentry, *xattr, NULL, 0);
62 if (error < 0) {
63 if (error == -ENODATA)
64 continue;
65 return error;
66 }
67 count++;
68 }
69
70 return count;
71}
72
49/* 73/*
50 * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr 74 * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr
51 * 75 *
@@ -65,32 +89,72 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
65 size_t xattr_value_len, 89 size_t xattr_value_len,
66 struct integrity_iint_cache *iint) 90 struct integrity_iint_cache *iint)
67{ 91{
68 struct evm_ima_xattr_data xattr_data; 92 struct evm_ima_xattr_data *xattr_data = NULL;
93 struct evm_ima_xattr_data calc;
69 enum integrity_status evm_status = INTEGRITY_PASS; 94 enum integrity_status evm_status = INTEGRITY_PASS;
70 int rc; 95 int rc, xattr_len;
71 96
72 if (iint && iint->evm_status == INTEGRITY_PASS) 97 if (iint && iint->evm_status == INTEGRITY_PASS)
73 return iint->evm_status; 98 return iint->evm_status;
74 99
75 /* if status is not PASS, try to check again - against -ENOMEM */ 100 /* if status is not PASS, try to check again - against -ENOMEM */
76 101
77 rc = evm_calc_hmac(dentry, xattr_name, xattr_value, 102 /* first need to know the sig type */
78 xattr_value_len, xattr_data.digest); 103 rc = vfs_getxattr_alloc(dentry, XATTR_NAME_EVM, (char **)&xattr_data, 0,
79 if (rc < 0) { 104 GFP_NOFS);
80 evm_status = (rc == -ENODATA) 105 if (rc <= 0) {
81 ? INTEGRITY_NOXATTRS : INTEGRITY_FAIL; 106 if (rc == 0)
107 evm_status = INTEGRITY_FAIL; /* empty */
108 else if (rc == -ENODATA) {
109 rc = evm_find_protected_xattrs(dentry);
110 if (rc > 0)
111 evm_status = INTEGRITY_NOLABEL;
112 else if (rc == 0)
113 evm_status = INTEGRITY_NOXATTRS; /* new file */
114 }
82 goto out; 115 goto out;
83 } 116 }
84 117
85 xattr_data.type = EVM_XATTR_HMAC; 118 xattr_len = rc - 1;
86 rc = vfs_xattr_cmp(dentry, XATTR_NAME_EVM, (u8 *)&xattr_data, 119
87 sizeof xattr_data, GFP_NOFS); 120 /* check value type */
88 if (rc < 0) 121 switch (xattr_data->type) {
89 evm_status = (rc == -ENODATA) 122 case EVM_XATTR_HMAC:
90 ? INTEGRITY_NOLABEL : INTEGRITY_FAIL; 123 rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
124 xattr_value_len, calc.digest);
125 if (rc)
126 break;
127 rc = memcmp(xattr_data->digest, calc.digest,
128 sizeof(calc.digest));
129 if (rc)
130 rc = -EINVAL;
131 break;
132 case EVM_IMA_XATTR_DIGSIG:
133 rc = evm_calc_hash(dentry, xattr_name, xattr_value,
134 xattr_value_len, calc.digest);
135 if (rc)
136 break;
137 rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
138 xattr_data->digest, xattr_len,
139 calc.digest, sizeof(calc.digest));
140 if (!rc) {
141 /* we probably want to replace rsa with hmac here */
142 evm_update_evmxattr(dentry, xattr_name, xattr_value,
143 xattr_value_len);
144 }
145 break;
146 default:
147 rc = -EINVAL;
148 break;
149 }
150
151 if (rc)
152 evm_status = (rc == -ENODATA) ?
153 INTEGRITY_NOXATTRS : INTEGRITY_FAIL;
91out: 154out:
92 if (iint) 155 if (iint)
93 iint->evm_status = evm_status; 156 iint->evm_status = evm_status;
157 kfree(xattr_data);
94 return evm_status; 158 return evm_status;
95} 159}
96 160
@@ -354,6 +418,8 @@ static int __init init_evm(void)
354 printk(KERN_INFO "EVM: Error registering secfs\n"); 418 printk(KERN_INFO "EVM: Error registering secfs\n");
355 goto err; 419 goto err;
356 } 420 }
421
422 return 0;
357err: 423err:
358 return error; 424 return error;
359} 425}
@@ -363,6 +429,8 @@ static void __exit cleanup_evm(void)
363 evm_cleanup_secfs(); 429 evm_cleanup_secfs();
364 if (hmac_tfm) 430 if (hmac_tfm)
365 crypto_free_shash(hmac_tfm); 431 crypto_free_shash(hmac_tfm);
432 if (hash_tfm)
433 crypto_free_shash(hash_tfm);
366} 434}
367 435
368/* 436/*
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 0d50df04ccc4..88a2788b981d 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -178,8 +178,8 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
178 strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX); 178 strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
179 179
180 result = ima_store_template(entry, violation, inode); 180 result = ima_store_template(entry, violation, inode);
181 if (!result) 181 if (!result || result == -EEXIST)
182 iint->flags |= IMA_MEASURED; 182 iint->flags |= IMA_MEASURED;
183 else 183 if (result < 0)
184 kfree(entry); 184 kfree(entry);
185} 185}
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index 8e28f04a5e2e..55a6271bce7a 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -23,6 +23,8 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include "ima.h" 24#include "ima.h"
25 25
26#define AUDIT_CAUSE_LEN_MAX 32
27
26LIST_HEAD(ima_measurements); /* list of all measurements */ 28LIST_HEAD(ima_measurements); /* list of all measurements */
27 29
28/* key: inode (before secure-hashing a file) */ 30/* key: inode (before secure-hashing a file) */
@@ -94,7 +96,8 @@ static int ima_pcr_extend(const u8 *hash)
94 96
95 result = tpm_pcr_extend(TPM_ANY_NUM, CONFIG_IMA_MEASURE_PCR_IDX, hash); 97 result = tpm_pcr_extend(TPM_ANY_NUM, CONFIG_IMA_MEASURE_PCR_IDX, hash);
96 if (result != 0) 98 if (result != 0)
97 pr_err("IMA: Error Communicating to TPM chip\n"); 99 pr_err("IMA: Error Communicating to TPM chip, result: %d\n",
100 result);
98 return result; 101 return result;
99} 102}
100 103
@@ -106,14 +109,16 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
106{ 109{
107 u8 digest[IMA_DIGEST_SIZE]; 110 u8 digest[IMA_DIGEST_SIZE];
108 const char *audit_cause = "hash_added"; 111 const char *audit_cause = "hash_added";
112 char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX];
109 int audit_info = 1; 113 int audit_info = 1;
110 int result = 0; 114 int result = 0, tpmresult = 0;
111 115
112 mutex_lock(&ima_extend_list_mutex); 116 mutex_lock(&ima_extend_list_mutex);
113 if (!violation) { 117 if (!violation) {
114 memcpy(digest, entry->digest, sizeof digest); 118 memcpy(digest, entry->digest, sizeof digest);
115 if (ima_lookup_digest_entry(digest)) { 119 if (ima_lookup_digest_entry(digest)) {
116 audit_cause = "hash_exists"; 120 audit_cause = "hash_exists";
121 result = -EEXIST;
117 goto out; 122 goto out;
118 } 123 }
119 } 124 }
@@ -128,9 +133,11 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
128 if (violation) /* invalidate pcr */ 133 if (violation) /* invalidate pcr */
129 memset(digest, 0xff, sizeof digest); 134 memset(digest, 0xff, sizeof digest);
130 135
131 result = ima_pcr_extend(digest); 136 tpmresult = ima_pcr_extend(digest);
132 if (result != 0) { 137 if (tpmresult != 0) {
133 audit_cause = "TPM error"; 138 snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TPM_error(%d)",
139 tpmresult);
140 audit_cause = tpm_audit_cause;
134 audit_info = 0; 141 audit_info = 0;
135 } 142 }
136out: 143out:
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 3143a3c39868..4da6ba81d153 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -46,5 +46,26 @@ struct integrity_iint_cache {
46struct integrity_iint_cache *integrity_iint_insert(struct inode *inode); 46struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
47struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 47struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
48 48
49#define INTEGRITY_KEYRING_EVM 0
50#define INTEGRITY_KEYRING_MODULE 1
51#define INTEGRITY_KEYRING_IMA 2
52#define INTEGRITY_KEYRING_MAX 3
53
54#ifdef CONFIG_INTEGRITY_DIGSIG
55
56int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
57 const char *digest, int digestlen);
58
59#else
60
61static inline int integrity_digsig_verify(const unsigned int id,
62 const char *sig, int siglen,
63 const char *digest, int digestlen)
64{
65 return -EOPNOTSUPP;
66}
67
68#endif /* CONFIG_INTEGRITY_DIGSIG */
69
49/* set during initialization */ 70/* set during initialization */
50extern int iint_initialized; 71extern int iint_initialized;
diff --git a/security/keys/key.c b/security/keys/key.c
index 4414abddcb5b..4f64c7267afb 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -291,6 +291,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
291 291
292 atomic_set(&key->usage, 1); 292 atomic_set(&key->usage, 1);
293 init_rwsem(&key->sem); 293 init_rwsem(&key->sem);
294 lockdep_set_class(&key->sem, &type->lock_class);
294 key->type = type; 295 key->type = type;
295 key->user = user; 296 key->user = user;
296 key->quotalen = quotalen; 297 key->quotalen = quotalen;
@@ -946,6 +947,8 @@ int register_key_type(struct key_type *ktype)
946 struct key_type *p; 947 struct key_type *p;
947 int ret; 948 int ret;
948 949
950 memset(&ktype->lock_class, 0, sizeof(ktype->lock_class));
951
949 ret = -EEXIST; 952 ret = -EEXIST;
950 down_write(&key_types_sem); 953 down_write(&key_types_sem);
951 954
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index f46658722c78..48a7d0014b4f 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -749,14 +749,6 @@ out:
749 return length; 749 return length;
750} 750}
751 751
752static inline int hexcode_to_int(int code) {
753 if (code == '\0' || !isxdigit(code))
754 return -1;
755 if (isdigit(code))
756 return code - '0';
757 return tolower(code) - 'a' + 10;
758}
759
760static ssize_t sel_write_create(struct file *file, char *buf, size_t size) 752static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
761{ 753{
762 char *scon = NULL, *tcon = NULL; 754 char *scon = NULL, *tcon = NULL;
@@ -808,9 +800,11 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
808 if (c1 == '+') 800 if (c1 == '+')
809 c1 = ' '; 801 c1 = ' ';
810 else if (c1 == '%') { 802 else if (c1 == '%') {
811 if ((c1 = hexcode_to_int(*r++)) < 0) 803 c1 = hex_to_bin(*r++);
804 if (c1 < 0)
812 goto out; 805 goto out;
813 if ((c2 = hexcode_to_int(*r++)) < 0) 806 c2 = hex_to_bin(*r++);
807 if (c2 < 0)
814 goto out; 808 goto out;
815 c1 = (c1 << 4) | c2; 809 c1 = (c1 << 4) | c2;
816 } 810 }
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index 2ec904177fe0..377d148e7157 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -175,7 +175,7 @@ void cond_policydb_destroy(struct policydb *p)
175int cond_init_bool_indexes(struct policydb *p) 175int cond_init_bool_indexes(struct policydb *p)
176{ 176{
177 kfree(p->bool_val_to_struct); 177 kfree(p->bool_val_to_struct);
178 p->bool_val_to_struct = (struct cond_bool_datum **) 178 p->bool_val_to_struct =
179 kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum *), GFP_KERNEL); 179 kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum *), GFP_KERNEL);
180 if (!p->bool_val_to_struct) 180 if (!p->bool_val_to_struct)
181 return -ENOMEM; 181 return -ENOMEM;
diff --git a/security/tomoyo/.gitignore b/security/tomoyo/.gitignore
new file mode 100644
index 000000000000..5caf1a6f5907
--- /dev/null
+++ b/security/tomoyo/.gitignore
@@ -0,0 +1,2 @@
1builtin-policy.h
2policy/
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index deeab7be5b97..9512222d5581 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -1122,7 +1122,7 @@ static inline pid_t tomoyo_sys_getppid(void)
1122{ 1122{
1123 pid_t pid; 1123 pid_t pid;
1124 rcu_read_lock(); 1124 rcu_read_lock();
1125 pid = task_tgid_vnr(current->real_parent); 1125 pid = task_tgid_vnr(rcu_dereference(current->real_parent));
1126 rcu_read_unlock(); 1126 rcu_read_unlock();
1127 return pid; 1127 return pid;
1128} 1128}