diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-16 01:54:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-16 01:54:12 -0400 |
commit | f91e654474d413201ae578820fb63f8a811f6c4e (patch) | |
tree | 7f32d5757381b3371dbf095510622472c7d3aa43 /security | |
parent | c715ebeb0303b196f17376f189ae4e168d98b563 (diff) | |
parent | 3dd0f18c70d94ca2432c78c5735744429f071b0b (diff) |
Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull integrity updates from James Morris:
"This adds support for EVM signatures based on larger digests, contains
a new audit record AUDIT_INTEGRITY_POLICY_RULE to differentiate the
IMA policy rules from the IMA-audit messages, addresses two deadlocks
due to either loading or searching for crypto algorithms, and cleans
up the audit messages"
* 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
EVM: fix return value check in evm_write_xattrs()
integrity: prevent deadlock during digsig verification.
evm: Allow non-SHA1 digital signatures
evm: Don't deadlock if a crypto algorithm is unavailable
integrity: silence warning when CONFIG_SECURITYFS is not enabled
ima: Differentiate auditing policy rules from "audit" actions
ima: Do not audit if CONFIG_INTEGRITY_AUDIT is not set
ima: Use audit_log_format() rather than audit_log_string()
ima: Call audit_log_string() rather than logging it untrusted
Diffstat (limited to 'security')
-rw-r--r-- | security/integrity/digsig_asymmetric.c | 23 | ||||
-rw-r--r-- | security/integrity/evm/Kconfig | 1 | ||||
-rw-r--r-- | security/integrity/evm/evm.h | 10 | ||||
-rw-r--r-- | security/integrity/evm/evm_crypto.c | 50 | ||||
-rw-r--r-- | security/integrity/evm/evm_main.c | 19 | ||||
-rw-r--r-- | security/integrity/evm/evm_secfs.c | 4 | ||||
-rw-r--r-- | security/integrity/iint.c | 9 | ||||
-rw-r--r-- | security/integrity/ima/Kconfig | 1 | ||||
-rw-r--r-- | security/integrity/ima/ima_policy.c | 9 | ||||
-rw-r--r-- | security/integrity/integrity.h | 15 | ||||
-rw-r--r-- | security/integrity/integrity_audit.c | 6 | ||||
-rw-r--r-- | security/security.c | 7 |
12 files changed, 108 insertions, 46 deletions
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c index ab6a029062a1..6dc075144508 100644 --- a/security/integrity/digsig_asymmetric.c +++ b/security/integrity/digsig_asymmetric.c | |||
@@ -115,3 +115,26 @@ int asymmetric_verify(struct key *keyring, const char *sig, | |||
115 | pr_debug("%s() = %d\n", __func__, ret); | 115 | pr_debug("%s() = %d\n", __func__, ret); |
116 | return ret; | 116 | return ret; |
117 | } | 117 | } |
118 | |||
119 | /** | ||
120 | * integrity_kernel_module_request - prevent crypto-pkcs1pad(rsa,*) requests | ||
121 | * @kmod_name: kernel module name | ||
122 | * | ||
123 | * We have situation, when public_key_verify_signature() in case of RSA | ||
124 | * algorithm use alg_name to store internal information in order to | ||
125 | * construct an algorithm on the fly, but crypto_larval_lookup() will try | ||
126 | * to use alg_name in order to load kernel module with same name. | ||
127 | * Since we don't have any real "crypto-pkcs1pad(rsa,*)" kernel modules, | ||
128 | * we are safe to fail such module request from crypto_larval_lookup(). | ||
129 | * | ||
130 | * In this way we prevent modprobe execution during digsig verification | ||
131 | * and avoid possible deadlock if modprobe and/or it's dependencies | ||
132 | * also signed with digsig. | ||
133 | */ | ||
134 | int integrity_kernel_module_request(char *kmod_name) | ||
135 | { | ||
136 | if (strncmp(kmod_name, "crypto-pkcs1pad(rsa,", 20) == 0) | ||
137 | return -EINVAL; | ||
138 | |||
139 | return 0; | ||
140 | } | ||
diff --git a/security/integrity/evm/Kconfig b/security/integrity/evm/Kconfig index d593346d0bba..60221852b26a 100644 --- a/security/integrity/evm/Kconfig +++ b/security/integrity/evm/Kconfig | |||
@@ -4,6 +4,7 @@ config EVM | |||
4 | select ENCRYPTED_KEYS | 4 | select ENCRYPTED_KEYS |
5 | select CRYPTO_HMAC | 5 | select CRYPTO_HMAC |
6 | select CRYPTO_SHA1 | 6 | select CRYPTO_SHA1 |
7 | select CRYPTO_HASH_INFO | ||
7 | default n | 8 | default n |
8 | help | 9 | help |
9 | EVM protects a file's security extended attributes against | 10 | EVM protects a file's security extended attributes against |
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h index 1257c3c24723..c3f437f5db10 100644 --- a/security/integrity/evm/evm.h +++ b/security/integrity/evm/evm.h | |||
@@ -47,6 +47,11 @@ extern struct crypto_shash *hash_tfm; | |||
47 | /* List of EVM protected security xattrs */ | 47 | /* List of EVM protected security xattrs */ |
48 | extern struct list_head evm_config_xattrnames; | 48 | extern struct list_head evm_config_xattrnames; |
49 | 49 | ||
50 | struct evm_digest { | ||
51 | struct ima_digest_data hdr; | ||
52 | char digest[IMA_MAX_DIGEST_SIZE]; | ||
53 | } __packed; | ||
54 | |||
50 | int evm_init_key(void); | 55 | int evm_init_key(void); |
51 | int evm_update_evmxattr(struct dentry *dentry, | 56 | int evm_update_evmxattr(struct dentry *dentry, |
52 | const char *req_xattr_name, | 57 | const char *req_xattr_name, |
@@ -54,10 +59,11 @@ int evm_update_evmxattr(struct dentry *dentry, | |||
54 | size_t req_xattr_value_len); | 59 | size_t req_xattr_value_len); |
55 | int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, | 60 | int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, |
56 | const char *req_xattr_value, | 61 | const char *req_xattr_value, |
57 | size_t req_xattr_value_len, char *digest); | 62 | size_t req_xattr_value_len, struct evm_digest *data); |
58 | int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, | 63 | int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, |
59 | const char *req_xattr_value, | 64 | const char *req_xattr_value, |
60 | size_t req_xattr_value_len, char type, char *digest); | 65 | size_t req_xattr_value_len, char type, |
66 | struct evm_digest *data); | ||
61 | int evm_init_hmac(struct inode *inode, const struct xattr *xattr, | 67 | int evm_init_hmac(struct inode *inode, const struct xattr *xattr, |
62 | char *hmac_val); | 68 | char *hmac_val); |
63 | int evm_init_secfs(void); | 69 | int evm_init_secfs(void); |
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index b60524310855..8a3905bb02c7 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/evm.h> | 21 | #include <linux/evm.h> |
22 | #include <keys/encrypted-type.h> | 22 | #include <keys/encrypted-type.h> |
23 | #include <crypto/hash.h> | 23 | #include <crypto/hash.h> |
24 | #include <crypto/hash_info.h> | ||
24 | #include "evm.h" | 25 | #include "evm.h" |
25 | 26 | ||
26 | #define EVMKEY "evm-key" | 27 | #define EVMKEY "evm-key" |
@@ -29,7 +30,7 @@ static unsigned char evmkey[MAX_KEY_SIZE]; | |||
29 | static int evmkey_len = MAX_KEY_SIZE; | 30 | static int evmkey_len = MAX_KEY_SIZE; |
30 | 31 | ||
31 | struct crypto_shash *hmac_tfm; | 32 | struct crypto_shash *hmac_tfm; |
32 | struct crypto_shash *hash_tfm; | 33 | static struct crypto_shash *evm_tfm[HASH_ALGO__LAST]; |
33 | 34 | ||
34 | static DEFINE_MUTEX(mutex); | 35 | static DEFINE_MUTEX(mutex); |
35 | 36 | ||
@@ -38,7 +39,6 @@ static DEFINE_MUTEX(mutex); | |||
38 | static unsigned long evm_set_key_flags; | 39 | static unsigned long evm_set_key_flags; |
39 | 40 | ||
40 | static char * const evm_hmac = "hmac(sha1)"; | 41 | static char * const evm_hmac = "hmac(sha1)"; |
41 | static char * const evm_hash = "sha1"; | ||
42 | 42 | ||
43 | /** | 43 | /** |
44 | * evm_set_key() - set EVM HMAC key from the kernel | 44 | * evm_set_key() - set EVM HMAC key from the kernel |
@@ -74,10 +74,10 @@ busy: | |||
74 | } | 74 | } |
75 | EXPORT_SYMBOL_GPL(evm_set_key); | 75 | EXPORT_SYMBOL_GPL(evm_set_key); |
76 | 76 | ||
77 | static struct shash_desc *init_desc(char type) | 77 | static struct shash_desc *init_desc(char type, uint8_t hash_algo) |
78 | { | 78 | { |
79 | long rc; | 79 | long rc; |
80 | char *algo; | 80 | const char *algo; |
81 | struct crypto_shash **tfm; | 81 | struct crypto_shash **tfm; |
82 | struct shash_desc *desc; | 82 | struct shash_desc *desc; |
83 | 83 | ||
@@ -89,15 +89,16 @@ static struct shash_desc *init_desc(char type) | |||
89 | tfm = &hmac_tfm; | 89 | tfm = &hmac_tfm; |
90 | algo = evm_hmac; | 90 | algo = evm_hmac; |
91 | } else { | 91 | } else { |
92 | tfm = &hash_tfm; | 92 | tfm = &evm_tfm[hash_algo]; |
93 | algo = evm_hash; | 93 | algo = hash_algo_name[hash_algo]; |
94 | } | 94 | } |
95 | 95 | ||
96 | if (*tfm == NULL) { | 96 | if (*tfm == NULL) { |
97 | mutex_lock(&mutex); | 97 | mutex_lock(&mutex); |
98 | if (*tfm) | 98 | if (*tfm) |
99 | goto out; | 99 | goto out; |
100 | *tfm = crypto_alloc_shash(algo, 0, CRYPTO_ALG_ASYNC); | 100 | *tfm = crypto_alloc_shash(algo, 0, |
101 | CRYPTO_ALG_ASYNC | CRYPTO_NOLOAD); | ||
101 | if (IS_ERR(*tfm)) { | 102 | if (IS_ERR(*tfm)) { |
102 | rc = PTR_ERR(*tfm); | 103 | rc = PTR_ERR(*tfm); |
103 | pr_err("Can not allocate %s (reason: %ld)\n", algo, rc); | 104 | pr_err("Can not allocate %s (reason: %ld)\n", algo, rc); |
@@ -186,10 +187,10 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode, | |||
186 | * each xattr, but attempt to re-use the previously allocated memory. | 187 | * each xattr, but attempt to re-use the previously allocated memory. |
187 | */ | 188 | */ |
188 | static int evm_calc_hmac_or_hash(struct dentry *dentry, | 189 | static int evm_calc_hmac_or_hash(struct dentry *dentry, |
189 | const char *req_xattr_name, | 190 | const char *req_xattr_name, |
190 | const char *req_xattr_value, | 191 | const char *req_xattr_value, |
191 | size_t req_xattr_value_len, | 192 | size_t req_xattr_value_len, |
192 | char type, char *digest) | 193 | uint8_t type, struct evm_digest *data) |
193 | { | 194 | { |
194 | struct inode *inode = d_backing_inode(dentry); | 195 | struct inode *inode = d_backing_inode(dentry); |
195 | struct xattr_list *xattr; | 196 | struct xattr_list *xattr; |
@@ -204,10 +205,12 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, | |||
204 | inode->i_sb->s_user_ns != &init_user_ns) | 205 | inode->i_sb->s_user_ns != &init_user_ns) |
205 | return -EOPNOTSUPP; | 206 | return -EOPNOTSUPP; |
206 | 207 | ||
207 | desc = init_desc(type); | 208 | desc = init_desc(type, data->hdr.algo); |
208 | if (IS_ERR(desc)) | 209 | if (IS_ERR(desc)) |
209 | return PTR_ERR(desc); | 210 | return PTR_ERR(desc); |
210 | 211 | ||
212 | data->hdr.length = crypto_shash_digestsize(desc->tfm); | ||
213 | |||
211 | error = -ENODATA; | 214 | error = -ENODATA; |
212 | list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) { | 215 | list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) { |
213 | bool is_ima = false; | 216 | bool is_ima = false; |
@@ -239,7 +242,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry, | |||
239 | if (is_ima) | 242 | if (is_ima) |
240 | ima_present = true; | 243 | ima_present = true; |
241 | } | 244 | } |
242 | hmac_add_misc(desc, inode, type, digest); | 245 | hmac_add_misc(desc, inode, type, data->digest); |
243 | 246 | ||
244 | /* Portable EVM signatures must include an IMA hash */ | 247 | /* Portable EVM signatures must include an IMA hash */ |
245 | if (type == EVM_XATTR_PORTABLE_DIGSIG && !ima_present) | 248 | if (type == EVM_XATTR_PORTABLE_DIGSIG && !ima_present) |
@@ -252,18 +255,18 @@ out: | |||
252 | 255 | ||
253 | int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, | 256 | int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name, |
254 | const char *req_xattr_value, size_t req_xattr_value_len, | 257 | const char *req_xattr_value, size_t req_xattr_value_len, |
255 | char *digest) | 258 | struct evm_digest *data) |
256 | { | 259 | { |
257 | return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value, | 260 | return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value, |
258 | req_xattr_value_len, EVM_XATTR_HMAC, digest); | 261 | req_xattr_value_len, EVM_XATTR_HMAC, data); |
259 | } | 262 | } |
260 | 263 | ||
261 | int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, | 264 | int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name, |
262 | const char *req_xattr_value, size_t req_xattr_value_len, | 265 | const char *req_xattr_value, size_t req_xattr_value_len, |
263 | char type, char *digest) | 266 | char type, struct evm_digest *data) |
264 | { | 267 | { |
265 | return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value, | 268 | return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value, |
266 | req_xattr_value_len, type, digest); | 269 | req_xattr_value_len, type, data); |
267 | } | 270 | } |
268 | 271 | ||
269 | static int evm_is_immutable(struct dentry *dentry, struct inode *inode) | 272 | static int evm_is_immutable(struct dentry *dentry, struct inode *inode) |
@@ -303,7 +306,7 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name, | |||
303 | const char *xattr_value, size_t xattr_value_len) | 306 | const char *xattr_value, size_t xattr_value_len) |
304 | { | 307 | { |
305 | struct inode *inode = d_backing_inode(dentry); | 308 | struct inode *inode = d_backing_inode(dentry); |
306 | struct evm_ima_xattr_data xattr_data; | 309 | struct evm_digest data; |
307 | int rc = 0; | 310 | int rc = 0; |
308 | 311 | ||
309 | /* | 312 | /* |
@@ -316,13 +319,14 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name, | |||
316 | if (rc) | 319 | if (rc) |
317 | return -EPERM; | 320 | return -EPERM; |
318 | 321 | ||
322 | data.hdr.algo = HASH_ALGO_SHA1; | ||
319 | rc = evm_calc_hmac(dentry, xattr_name, xattr_value, | 323 | rc = evm_calc_hmac(dentry, xattr_name, xattr_value, |
320 | xattr_value_len, xattr_data.digest); | 324 | xattr_value_len, &data); |
321 | if (rc == 0) { | 325 | if (rc == 0) { |
322 | xattr_data.type = EVM_XATTR_HMAC; | 326 | data.hdr.xattr.sha1.type = EVM_XATTR_HMAC; |
323 | rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM, | 327 | rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM, |
324 | &xattr_data, | 328 | &data.hdr.xattr.data[1], |
325 | sizeof(xattr_data), 0); | 329 | SHA1_DIGEST_SIZE + 1, 0); |
326 | } else if (rc == -ENODATA && (inode->i_opflags & IOP_XATTR)) { | 330 | } else if (rc == -ENODATA && (inode->i_opflags & IOP_XATTR)) { |
327 | rc = __vfs_removexattr(dentry, XATTR_NAME_EVM); | 331 | rc = __vfs_removexattr(dentry, XATTR_NAME_EVM); |
328 | } | 332 | } |
@@ -334,7 +338,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr, | |||
334 | { | 338 | { |
335 | struct shash_desc *desc; | 339 | struct shash_desc *desc; |
336 | 340 | ||
337 | desc = init_desc(EVM_XATTR_HMAC); | 341 | desc = init_desc(EVM_XATTR_HMAC, HASH_ALGO_SHA1); |
338 | if (IS_ERR(desc)) { | 342 | if (IS_ERR(desc)) { |
339 | pr_info("init_desc failed\n"); | 343 | pr_info("init_desc failed\n"); |
340 | return PTR_ERR(desc); | 344 | return PTR_ERR(desc); |
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index f9eff5041e4c..7f3f54d89a6e 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/magic.h> | 25 | #include <linux/magic.h> |
26 | 26 | ||
27 | #include <crypto/hash.h> | 27 | #include <crypto/hash.h> |
28 | #include <crypto/hash_info.h> | ||
28 | #include <crypto/algapi.h> | 29 | #include <crypto/algapi.h> |
29 | #include "evm.h" | 30 | #include "evm.h" |
30 | 31 | ||
@@ -134,8 +135,9 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry, | |||
134 | struct integrity_iint_cache *iint) | 135 | struct integrity_iint_cache *iint) |
135 | { | 136 | { |
136 | struct evm_ima_xattr_data *xattr_data = NULL; | 137 | struct evm_ima_xattr_data *xattr_data = NULL; |
137 | struct evm_ima_xattr_data calc; | 138 | struct signature_v2_hdr *hdr; |
138 | enum integrity_status evm_status = INTEGRITY_PASS; | 139 | enum integrity_status evm_status = INTEGRITY_PASS; |
140 | struct evm_digest digest; | ||
139 | struct inode *inode; | 141 | struct inode *inode; |
140 | int rc, xattr_len; | 142 | int rc, xattr_len; |
141 | 143 | ||
@@ -171,25 +173,28 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry, | |||
171 | evm_status = INTEGRITY_FAIL; | 173 | evm_status = INTEGRITY_FAIL; |
172 | goto out; | 174 | goto out; |
173 | } | 175 | } |
176 | |||
177 | digest.hdr.algo = HASH_ALGO_SHA1; | ||
174 | rc = evm_calc_hmac(dentry, xattr_name, xattr_value, | 178 | rc = evm_calc_hmac(dentry, xattr_name, xattr_value, |
175 | xattr_value_len, calc.digest); | 179 | xattr_value_len, &digest); |
176 | if (rc) | 180 | if (rc) |
177 | break; | 181 | break; |
178 | rc = crypto_memneq(xattr_data->digest, calc.digest, | 182 | rc = crypto_memneq(xattr_data->digest, digest.digest, |
179 | sizeof(calc.digest)); | 183 | SHA1_DIGEST_SIZE); |
180 | if (rc) | 184 | if (rc) |
181 | rc = -EINVAL; | 185 | rc = -EINVAL; |
182 | break; | 186 | break; |
183 | case EVM_IMA_XATTR_DIGSIG: | 187 | case EVM_IMA_XATTR_DIGSIG: |
184 | case EVM_XATTR_PORTABLE_DIGSIG: | 188 | case EVM_XATTR_PORTABLE_DIGSIG: |
189 | hdr = (struct signature_v2_hdr *)xattr_data; | ||
190 | digest.hdr.algo = hdr->hash_algo; | ||
185 | rc = evm_calc_hash(dentry, xattr_name, xattr_value, | 191 | rc = evm_calc_hash(dentry, xattr_name, xattr_value, |
186 | xattr_value_len, xattr_data->type, | 192 | xattr_value_len, xattr_data->type, &digest); |
187 | calc.digest); | ||
188 | if (rc) | 193 | if (rc) |
189 | break; | 194 | break; |
190 | rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM, | 195 | rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM, |
191 | (const char *)xattr_data, xattr_len, | 196 | (const char *)xattr_data, xattr_len, |
192 | calc.digest, sizeof(calc.digest)); | 197 | digest.digest, digest.hdr.length); |
193 | if (!rc) { | 198 | if (!rc) { |
194 | inode = d_backing_inode(dentry); | 199 | inode = d_backing_inode(dentry); |
195 | 200 | ||
diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c index 637eb999e340..77de71b7794c 100644 --- a/security/integrity/evm/evm_secfs.c +++ b/security/integrity/evm/evm_secfs.c | |||
@@ -193,8 +193,8 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf, | |||
193 | return -E2BIG; | 193 | return -E2BIG; |
194 | 194 | ||
195 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_EVM_XATTR); | 195 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_EVM_XATTR); |
196 | if (IS_ERR(ab)) | 196 | if (!ab) |
197 | return PTR_ERR(ab); | 197 | return -ENOMEM; |
198 | 198 | ||
199 | xattr = kmalloc(sizeof(struct xattr_list), GFP_KERNEL); | 199 | xattr = kmalloc(sizeof(struct xattr_list), GFP_KERNEL); |
200 | if (!xattr) { | 200 | if (!xattr) { |
diff --git a/security/integrity/iint.c b/security/integrity/iint.c index 149faa81f6f0..5a6810041e5c 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c | |||
@@ -219,10 +219,13 @@ static int __init integrity_fs_init(void) | |||
219 | { | 219 | { |
220 | integrity_dir = securityfs_create_dir("integrity", NULL); | 220 | integrity_dir = securityfs_create_dir("integrity", NULL); |
221 | if (IS_ERR(integrity_dir)) { | 221 | if (IS_ERR(integrity_dir)) { |
222 | pr_err("Unable to create integrity sysfs dir: %ld\n", | 222 | int ret = PTR_ERR(integrity_dir); |
223 | PTR_ERR(integrity_dir)); | 223 | |
224 | if (ret != -ENODEV) | ||
225 | pr_err("Unable to create integrity sysfs dir: %d\n", | ||
226 | ret); | ||
224 | integrity_dir = NULL; | 227 | integrity_dir = NULL; |
225 | return PTR_ERR(integrity_dir); | 228 | return ret; |
226 | } | 229 | } |
227 | 230 | ||
228 | return 0; | 231 | return 0; |
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 004919d9bf09..13b446328dda 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig | |||
@@ -12,6 +12,7 @@ config IMA | |||
12 | select TCG_TIS if TCG_TPM && X86 | 12 | select TCG_TIS if TCG_TPM && X86 |
13 | select TCG_CRB if TCG_TPM && ACPI | 13 | select TCG_CRB if TCG_TPM && ACPI |
14 | select TCG_IBMVTPM if TCG_TPM && PPC_PSERIES | 14 | select TCG_IBMVTPM if TCG_TPM && PPC_PSERIES |
15 | select INTEGRITY_AUDIT if AUDIT | ||
15 | help | 16 | help |
16 | The Trusted Computing Group(TCG) runtime Integrity | 17 | The Trusted Computing Group(TCG) runtime Integrity |
17 | Measurement Architecture(IMA) maintains a list of hash | 18 | Measurement Architecture(IMA) maintains a list of hash |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 1659abb344f9..8c9499867c91 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
@@ -657,14 +657,16 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, | |||
657 | static void ima_log_string_op(struct audit_buffer *ab, char *key, char *value, | 657 | static void ima_log_string_op(struct audit_buffer *ab, char *key, char *value, |
658 | bool (*rule_operator)(kuid_t, kuid_t)) | 658 | bool (*rule_operator)(kuid_t, kuid_t)) |
659 | { | 659 | { |
660 | if (!ab) | ||
661 | return; | ||
662 | |||
660 | if (rule_operator == &uid_gt) | 663 | if (rule_operator == &uid_gt) |
661 | audit_log_format(ab, "%s>", key); | 664 | audit_log_format(ab, "%s>", key); |
662 | else if (rule_operator == &uid_lt) | 665 | else if (rule_operator == &uid_lt) |
663 | audit_log_format(ab, "%s<", key); | 666 | audit_log_format(ab, "%s<", key); |
664 | else | 667 | else |
665 | audit_log_format(ab, "%s=", key); | 668 | audit_log_format(ab, "%s=", key); |
666 | audit_log_untrustedstring(ab, value); | 669 | audit_log_format(ab, "%s ", value); |
667 | audit_log_format(ab, " "); | ||
668 | } | 670 | } |
669 | static void ima_log_string(struct audit_buffer *ab, char *key, char *value) | 671 | static void ima_log_string(struct audit_buffer *ab, char *key, char *value) |
670 | { | 672 | { |
@@ -679,7 +681,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
679 | bool uid_token; | 681 | bool uid_token; |
680 | int result = 0; | 682 | int result = 0; |
681 | 683 | ||
682 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE); | 684 | ab = integrity_audit_log_start(audit_context(), GFP_KERNEL, |
685 | AUDIT_INTEGRITY_POLICY_RULE); | ||
683 | 686 | ||
684 | entry->uid = INVALID_UID; | 687 | entry->uid = INVALID_UID; |
685 | entry->fowner = INVALID_UID; | 688 | entry->fowner = INVALID_UID; |
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 0bb372eed62a..e60473b13a8d 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/integrity.h> | 15 | #include <linux/integrity.h> |
16 | #include <crypto/sha.h> | 16 | #include <crypto/sha.h> |
17 | #include <linux/key.h> | 17 | #include <linux/key.h> |
18 | #include <linux/audit.h> | ||
18 | 19 | ||
19 | /* iint action cache flags */ | 20 | /* iint action cache flags */ |
20 | #define IMA_MEASURE 0x00000001 | 21 | #define IMA_MEASURE 0x00000001 |
@@ -199,6 +200,13 @@ static inline void evm_load_x509(void) | |||
199 | void integrity_audit_msg(int audit_msgno, struct inode *inode, | 200 | void integrity_audit_msg(int audit_msgno, struct inode *inode, |
200 | const unsigned char *fname, const char *op, | 201 | const unsigned char *fname, const char *op, |
201 | const char *cause, int result, int info); | 202 | const char *cause, int result, int info); |
203 | |||
204 | static inline struct audit_buffer * | ||
205 | integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type) | ||
206 | { | ||
207 | return audit_log_start(ctx, gfp_mask, type); | ||
208 | } | ||
209 | |||
202 | #else | 210 | #else |
203 | static inline void integrity_audit_msg(int audit_msgno, struct inode *inode, | 211 | static inline void integrity_audit_msg(int audit_msgno, struct inode *inode, |
204 | const unsigned char *fname, | 212 | const unsigned char *fname, |
@@ -206,4 +214,11 @@ static inline void integrity_audit_msg(int audit_msgno, struct inode *inode, | |||
206 | int result, int info) | 214 | int result, int info) |
207 | { | 215 | { |
208 | } | 216 | } |
217 | |||
218 | static inline struct audit_buffer * | ||
219 | integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type) | ||
220 | { | ||
221 | return NULL; | ||
222 | } | ||
223 | |||
209 | #endif | 224 | #endif |
diff --git a/security/integrity/integrity_audit.c b/security/integrity/integrity_audit.c index ab10a25310a1..82c98f7d217e 100644 --- a/security/integrity/integrity_audit.c +++ b/security/integrity/integrity_audit.c | |||
@@ -45,11 +45,7 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode, | |||
45 | from_kuid(&init_user_ns, audit_get_loginuid(current)), | 45 | from_kuid(&init_user_ns, audit_get_loginuid(current)), |
46 | audit_get_sessionid(current)); | 46 | audit_get_sessionid(current)); |
47 | audit_log_task_context(ab); | 47 | audit_log_task_context(ab); |
48 | audit_log_format(ab, " op="); | 48 | audit_log_format(ab, " op=%s cause=%s comm=", op, cause); |
49 | audit_log_string(ab, op); | ||
50 | audit_log_format(ab, " cause="); | ||
51 | audit_log_string(ab, cause); | ||
52 | audit_log_format(ab, " comm="); | ||
53 | audit_log_untrustedstring(ab, get_task_comm(name, current)); | 49 | audit_log_untrustedstring(ab, get_task_comm(name, current)); |
54 | if (fname) { | 50 | if (fname) { |
55 | audit_log_format(ab, " name="); | 51 | audit_log_format(ab, " name="); |
diff --git a/security/security.c b/security/security.c index ab4f96347ebb..47cfff01d7ec 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -1032,7 +1032,12 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode) | |||
1032 | 1032 | ||
1033 | int security_kernel_module_request(char *kmod_name) | 1033 | int security_kernel_module_request(char *kmod_name) |
1034 | { | 1034 | { |
1035 | return call_int_hook(kernel_module_request, 0, kmod_name); | 1035 | int ret; |
1036 | |||
1037 | ret = call_int_hook(kernel_module_request, 0, kmod_name); | ||
1038 | if (ret) | ||
1039 | return ret; | ||
1040 | return integrity_kernel_module_request(kmod_name); | ||
1036 | } | 1041 | } |
1037 | 1042 | ||
1038 | int security_kernel_read_file(struct file *file, enum kernel_read_file_id id) | 1043 | int security_kernel_read_file(struct file *file, enum kernel_read_file_id id) |