aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS2
-rw-r--r--crypto/asymmetric_keys/signature.c1
-rw-r--r--fs/namei.c2
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--include/linux/ima.h4
-rw-r--r--include/linux/security.h2
-rw-r--r--security/integrity/Kconfig46
-rw-r--r--security/integrity/Makefile6
-rw-r--r--security/integrity/digsig_asymmetric.c5
-rw-r--r--security/integrity/evm/Kconfig8
-rw-r--r--security/integrity/evm/evm_main.c17
-rw-r--r--security/integrity/ima/Kconfig2
-rw-r--r--security/integrity/ima/ima.h15
-rw-r--r--security/integrity/ima/ima_api.c5
-rw-r--r--security/integrity/ima/ima_appraise.c11
-rw-r--r--security/integrity/ima/ima_crypto.c20
-rw-r--r--security/integrity/ima/ima_main.c52
-rw-r--r--security/integrity/ima/ima_template.c30
-rw-r--r--security/integrity/integrity.h2
19 files changed, 109 insertions, 123 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 55762cba8516..992335ca0b2c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7955,6 +7955,8 @@ F: drivers/mmc/host/sdhci-pltfm.[ch]
7955 7955
7956SECURE COMPUTING 7956SECURE COMPUTING
7957M: Kees Cook <keescook@chromium.org> 7957M: Kees Cook <keescook@chromium.org>
7958R: Andy Lutomirski <luto@amacapital.net>
7959R: Will Drewry <wad@chromium.org>
7958T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git seccomp 7960T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git seccomp
7959S: Supported 7961S: Supported
7960F: kernel/seccomp.c 7962F: kernel/seccomp.c
diff --git a/crypto/asymmetric_keys/signature.c b/crypto/asymmetric_keys/signature.c
index 50b3f880b4ff..7525fd183574 100644
--- a/crypto/asymmetric_keys/signature.c
+++ b/crypto/asymmetric_keys/signature.c
@@ -11,6 +11,7 @@
11 * 2 of the Licence, or (at your option) any later version. 11 * 2 of the Licence, or (at your option) any later version.
12 */ 12 */
13 13
14#define pr_fmt(fmt) "SIG: "fmt
14#include <keys/asymmetric-subtype.h> 15#include <keys/asymmetric-subtype.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/err.h> 17#include <linux/err.h>
diff --git a/fs/namei.c b/fs/namei.c
index 985c6f368485..005771f97189 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3058,7 +3058,7 @@ opened:
3058 error = open_check_o_direct(file); 3058 error = open_check_o_direct(file);
3059 if (error) 3059 if (error)
3060 goto exit_fput; 3060 goto exit_fput;
3061 error = ima_file_check(file, op->acc_mode); 3061 error = ima_file_check(file, op->acc_mode, *opened);
3062 if (error) 3062 if (error)
3063 goto exit_fput; 3063 goto exit_fput;
3064 3064
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 140c496f612c..d49c778faecb 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -709,7 +709,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
709 host_err = PTR_ERR(*filp); 709 host_err = PTR_ERR(*filp);
710 *filp = NULL; 710 *filp = NULL;
711 } else { 711 } else {
712 host_err = ima_file_check(*filp, may_flags); 712 host_err = ima_file_check(*filp, may_flags, 0);
713 713
714 if (may_flags & NFSD_MAY_64BIT_COOKIE) 714 if (may_flags & NFSD_MAY_64BIT_COOKIE)
715 (*filp)->f_mode |= FMODE_64BITHASH; 715 (*filp)->f_mode |= FMODE_64BITHASH;
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 7cf5e9b32550..120ccc53fcb7 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -15,7 +15,7 @@ struct linux_binprm;
15 15
16#ifdef CONFIG_IMA 16#ifdef CONFIG_IMA
17extern int ima_bprm_check(struct linux_binprm *bprm); 17extern int ima_bprm_check(struct linux_binprm *bprm);
18extern int ima_file_check(struct file *file, int mask); 18extern int ima_file_check(struct file *file, int mask, int opened);
19extern void ima_file_free(struct file *file); 19extern void ima_file_free(struct file *file);
20extern int ima_file_mmap(struct file *file, unsigned long prot); 20extern int ima_file_mmap(struct file *file, unsigned long prot);
21extern int ima_module_check(struct file *file); 21extern int ima_module_check(struct file *file);
@@ -27,7 +27,7 @@ static inline int ima_bprm_check(struct linux_binprm *bprm)
27 return 0; 27 return 0;
28} 28}
29 29
30static inline int ima_file_check(struct file *file, int mask) 30static inline int ima_file_check(struct file *file, int mask, int opened)
31{ 31{
32 return 0; 32 return 0;
33} 33}
diff --git a/include/linux/security.h b/include/linux/security.h
index 623f90e5f38d..3b3aeb1b74cb 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -2108,7 +2108,7 @@ static inline int security_dentry_init_security(struct dentry *dentry,
2108static inline int security_inode_init_security(struct inode *inode, 2108static inline int security_inode_init_security(struct inode *inode,
2109 struct inode *dir, 2109 struct inode *dir,
2110 const struct qstr *qstr, 2110 const struct qstr *qstr,
2111 const initxattrs initxattrs, 2111 const initxattrs xattrs,
2112 void *fs_data) 2112 void *fs_data)
2113{ 2113{
2114 return 0; 2114 return 0;
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 245c6d92065b..b76235ae4786 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -1,11 +1,23 @@
1# 1#
2config INTEGRITY 2config INTEGRITY
3 def_bool y 3 bool "Integrity subsystem"
4 depends on IMA || EVM 4 depends on SECURITY
5 default y
6 help
7 This option enables the integrity subsystem, which is comprised
8 of a number of different components including the Integrity
9 Measurement Architecture (IMA), Extended Verification Module
10 (EVM), IMA-appraisal extension, digital signature verification
11 extension and audit measurement log support.
12
13 Each of these components can be enabled/disabled separately.
14 Refer to the individual components for additional details.
15
16if INTEGRITY
5 17
6config INTEGRITY_SIGNATURE 18config INTEGRITY_SIGNATURE
7 boolean "Digital signature verification using multiple keyrings" 19 boolean "Digital signature verification using multiple keyrings"
8 depends on INTEGRITY && KEYS 20 depends on KEYS
9 default n 21 default n
10 select SIGNATURE 22 select SIGNATURE
11 help 23 help
@@ -17,9 +29,21 @@ config INTEGRITY_SIGNATURE
17 This is useful for evm and module keyrings, when keys are 29 This is useful for evm and module keyrings, when keys are
18 usually only added from initramfs. 30 usually only added from initramfs.
19 31
32config INTEGRITY_ASYMMETRIC_KEYS
33 boolean "Enable asymmetric keys support"
34 depends on INTEGRITY_SIGNATURE
35 default n
36 select ASYMMETRIC_KEY_TYPE
37 select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
38 select PUBLIC_KEY_ALGO_RSA
39 select X509_CERTIFICATE_PARSER
40 help
41 This option enables digital signature verification using
42 asymmetric keys.
43
20config INTEGRITY_AUDIT 44config INTEGRITY_AUDIT
21 bool "Enables integrity auditing support " 45 bool "Enables integrity auditing support "
22 depends on INTEGRITY && AUDIT 46 depends on AUDIT
23 default y 47 default y
24 help 48 help
25 In addition to enabling integrity auditing support, this 49 In addition to enabling integrity auditing support, this
@@ -32,17 +56,7 @@ config INTEGRITY_AUDIT
32 be enabled by specifying 'integrity_audit=1' on the kernel 56 be enabled by specifying 'integrity_audit=1' on the kernel
33 command line. 57 command line.
34 58
35config INTEGRITY_ASYMMETRIC_KEYS
36 boolean "Enable asymmetric keys support"
37 depends on INTEGRITY_SIGNATURE
38 default n
39 select ASYMMETRIC_KEY_TYPE
40 select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
41 select PUBLIC_KEY_ALGO_RSA
42 select X509_CERTIFICATE_PARSER
43 help
44 This option enables digital signature verification using
45 asymmetric keys.
46
47source security/integrity/ima/Kconfig 59source security/integrity/ima/Kconfig
48source security/integrity/evm/Kconfig 60source security/integrity/evm/Kconfig
61
62endif # if INTEGRITY
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index 0793f4811cb7..8d1f4bf51087 100644
--- a/security/integrity/Makefile
+++ b/security/integrity/Makefile
@@ -3,11 +3,11 @@
3# 3#
4 4
5obj-$(CONFIG_INTEGRITY) += integrity.o 5obj-$(CONFIG_INTEGRITY) += integrity.o
6obj-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
7obj-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
8obj-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
9 6
10integrity-y := iint.o 7integrity-y := iint.o
8integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
9integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
10integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
11 11
12subdir-$(CONFIG_IMA) += ima 12subdir-$(CONFIG_IMA) += ima
13obj-$(CONFIG_IMA) += ima/ 13obj-$(CONFIG_IMA) += ima/
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index 9eae4809006b..37e0d98517a8 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -13,6 +13,7 @@
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 14
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/ratelimit.h>
16#include <linux/key-type.h> 17#include <linux/key-type.h>
17#include <crypto/public_key.h> 18#include <crypto/public_key.h>
18#include <keys/asymmetric-type.h> 19#include <keys/asymmetric-type.h>
@@ -45,8 +46,8 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
45 } 46 }
46 47
47 if (IS_ERR(key)) { 48 if (IS_ERR(key)) {
48 pr_warn("Request for unknown key '%s' err %ld\n", 49 pr_err_ratelimited("Request for unknown key '%s' err %ld\n",
49 name, PTR_ERR(key)); 50 name, PTR_ERR(key));
50 switch (PTR_ERR(key)) { 51 switch (PTR_ERR(key)) {
51 /* Hide some search errors */ 52 /* Hide some search errors */
52 case -EACCES: 53 case -EACCES:
diff --git a/security/integrity/evm/Kconfig b/security/integrity/evm/Kconfig
index d606f3d12d6b..df586fa00ef1 100644
--- a/security/integrity/evm/Kconfig
+++ b/security/integrity/evm/Kconfig
@@ -1,6 +1,5 @@
1config EVM 1config EVM
2 boolean "EVM support" 2 boolean "EVM support"
3 depends on SECURITY
4 select KEYS 3 select KEYS
5 select ENCRYPTED_KEYS 4 select ENCRYPTED_KEYS
6 select CRYPTO_HMAC 5 select CRYPTO_HMAC
@@ -12,10 +11,6 @@ config EVM
12 11
13 If you are unsure how to answer this question, answer N. 12 If you are unsure how to answer this question, answer N.
14 13
15if EVM
16
17menu "EVM options"
18
19config EVM_ATTR_FSUUID 14config EVM_ATTR_FSUUID
20 bool "FSUUID (version 2)" 15 bool "FSUUID (version 2)"
21 default y 16 default y
@@ -47,6 +42,3 @@ config EVM_EXTRA_SMACK_XATTRS
47 additional info to the calculation, requires existing EVM 42 additional info to the calculation, requires existing EVM
48 labeled file systems to be relabeled. 43 labeled file systems to be relabeled.
49 44
50endmenu
51
52endif
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 3bcb80df4d01..9685af330de5 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -126,14 +126,15 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
126 rc = vfs_getxattr_alloc(dentry, XATTR_NAME_EVM, (char **)&xattr_data, 0, 126 rc = vfs_getxattr_alloc(dentry, XATTR_NAME_EVM, (char **)&xattr_data, 0,
127 GFP_NOFS); 127 GFP_NOFS);
128 if (rc <= 0) { 128 if (rc <= 0) {
129 if (rc == 0) 129 evm_status = INTEGRITY_FAIL;
130 evm_status = INTEGRITY_FAIL; /* empty */ 130 if (rc == -ENODATA) {
131 else if (rc == -ENODATA) {
132 rc = evm_find_protected_xattrs(dentry); 131 rc = evm_find_protected_xattrs(dentry);
133 if (rc > 0) 132 if (rc > 0)
134 evm_status = INTEGRITY_NOLABEL; 133 evm_status = INTEGRITY_NOLABEL;
135 else if (rc == 0) 134 else if (rc == 0)
136 evm_status = INTEGRITY_NOXATTRS; /* new file */ 135 evm_status = INTEGRITY_NOXATTRS; /* new file */
136 } else if (rc == -EOPNOTSUPP) {
137 evm_status = INTEGRITY_UNKNOWN;
137 } 138 }
138 goto out; 139 goto out;
139 } 140 }
@@ -284,6 +285,13 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
284 goto out; 285 goto out;
285 } 286 }
286 evm_status = evm_verify_current_integrity(dentry); 287 evm_status = evm_verify_current_integrity(dentry);
288 if (evm_status == INTEGRITY_NOXATTRS) {
289 struct integrity_iint_cache *iint;
290
291 iint = integrity_iint_find(dentry->d_inode);
292 if (iint && (iint->flags & IMA_NEW_FILE))
293 return 0;
294 }
287out: 295out:
288 if (evm_status != INTEGRITY_PASS) 296 if (evm_status != INTEGRITY_PASS)
289 integrity_audit_msg(AUDIT_INTEGRITY_METADATA, dentry->d_inode, 297 integrity_audit_msg(AUDIT_INTEGRITY_METADATA, dentry->d_inode,
@@ -352,7 +360,6 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
352 return; 360 return;
353 361
354 evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len); 362 evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
355 return;
356} 363}
357 364
358/** 365/**
@@ -372,7 +379,6 @@ void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
372 mutex_lock(&inode->i_mutex); 379 mutex_lock(&inode->i_mutex);
373 evm_update_evmxattr(dentry, xattr_name, NULL, 0); 380 evm_update_evmxattr(dentry, xattr_name, NULL, 0);
374 mutex_unlock(&inode->i_mutex); 381 mutex_unlock(&inode->i_mutex);
375 return;
376} 382}
377 383
378/** 384/**
@@ -414,7 +420,6 @@ void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
414 420
415 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)) 421 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
416 evm_update_evmxattr(dentry, NULL, NULL, 0); 422 evm_update_evmxattr(dentry, NULL, NULL, 0);
417 return;
418} 423}
419 424
420/* 425/*
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 08758fbd496f..e099875643c5 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -2,8 +2,6 @@
2# 2#
3config IMA 3config IMA
4 bool "Integrity Measurement Architecture(IMA)" 4 bool "Integrity Measurement Architecture(IMA)"
5 depends on SECURITY
6 select INTEGRITY
7 select SECURITYFS 5 select SECURITYFS
8 select CRYPTO 6 select CRYPTO
9 select CRYPTO_HMAC 7 select CRYPTO_HMAC
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 57da4bd7ba0c..8e4bb883fc13 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -90,10 +90,7 @@ extern struct list_head ima_measurements; /* list of all measurements */
90 90
91/* Internal IMA function definitions */ 91/* Internal IMA function definitions */
92int ima_init(void); 92int ima_init(void);
93void ima_cleanup(void);
94int ima_fs_init(void); 93int ima_fs_init(void);
95void ima_fs_cleanup(void);
96int ima_inode_alloc(struct inode *inode);
97int ima_add_template_entry(struct ima_template_entry *entry, int violation, 94int ima_add_template_entry(struct ima_template_entry *entry, int violation,
98 const char *op, struct inode *inode, 95 const char *op, struct inode *inode,
99 const unsigned char *filename); 96 const unsigned char *filename);
@@ -110,8 +107,6 @@ void ima_print_digest(struct seq_file *m, u8 *digest, int size);
110struct ima_template_desc *ima_template_desc_current(void); 107struct ima_template_desc *ima_template_desc_current(void);
111int ima_init_template(void); 108int ima_init_template(void);
112 109
113int ima_init_template(void);
114
115/* 110/*
116 * used to protect h_table and sha_table 111 * used to protect h_table and sha_table
117 */ 112 */
@@ -151,12 +146,6 @@ int ima_store_template(struct ima_template_entry *entry, int violation,
151void ima_free_template_entry(struct ima_template_entry *entry); 146void ima_free_template_entry(struct ima_template_entry *entry);
152const char *ima_d_path(struct path *path, char **pathbuf); 147const char *ima_d_path(struct path *path, char **pathbuf);
153 148
154/* rbtree tree calls to lookup, insert, delete
155 * integrity data associated with an inode.
156 */
157struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
158struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
159
160/* IMA policy related functions */ 149/* IMA policy related functions */
161enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR }; 150enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR };
162 151
@@ -177,7 +166,7 @@ void ima_delete_rules(void);
177int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, 166int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
178 struct file *file, const unsigned char *filename, 167 struct file *file, const unsigned char *filename,
179 struct evm_ima_xattr_data *xattr_value, 168 struct evm_ima_xattr_data *xattr_value,
180 int xattr_len); 169 int xattr_len, int opened);
181int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); 170int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
182void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); 171void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
183enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, 172enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
@@ -193,7 +182,7 @@ static inline int ima_appraise_measurement(int func,
193 struct file *file, 182 struct file *file,
194 const unsigned char *filename, 183 const unsigned char *filename,
195 struct evm_ima_xattr_data *xattr_value, 184 struct evm_ima_xattr_data *xattr_value,
196 int xattr_len) 185 int xattr_len, int opened)
197{ 186{
198 return INTEGRITY_UNKNOWN; 187 return INTEGRITY_UNKNOWN;
199} 188}
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index d9cd5ce14d2b..65c41a968cc1 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -330,10 +330,9 @@ const char *ima_d_path(struct path *path, char **pathbuf)
330{ 330{
331 char *pathname = NULL; 331 char *pathname = NULL;
332 332
333 /* We will allow 11 spaces for ' (deleted)' to be appended */ 333 *pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
334 *pathbuf = kmalloc(PATH_MAX + 11, GFP_KERNEL);
335 if (*pathbuf) { 334 if (*pathbuf) {
336 pathname = d_path(path, *pathbuf, PATH_MAX + 11); 335 pathname = d_absolute_path(path, *pathbuf, PATH_MAX);
337 if (IS_ERR(pathname)) { 336 if (IS_ERR(pathname)) {
338 kfree(*pathbuf); 337 kfree(*pathbuf);
339 *pathbuf = NULL; 338 *pathbuf = NULL;
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 86bfd5c5df85..013ec3f0e42d 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -183,7 +183,7 @@ int ima_read_xattr(struct dentry *dentry,
183int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, 183int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
184 struct file *file, const unsigned char *filename, 184 struct file *file, const unsigned char *filename,
185 struct evm_ima_xattr_data *xattr_value, 185 struct evm_ima_xattr_data *xattr_value,
186 int xattr_len) 186 int xattr_len, int opened)
187{ 187{
188 static const char op[] = "appraise_data"; 188 static const char op[] = "appraise_data";
189 char *cause = "unknown"; 189 char *cause = "unknown";
@@ -192,8 +192,6 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
192 enum integrity_status status = INTEGRITY_UNKNOWN; 192 enum integrity_status status = INTEGRITY_UNKNOWN;
193 int rc = xattr_len, hash_start = 0; 193 int rc = xattr_len, hash_start = 0;
194 194
195 if (!ima_appraise)
196 return 0;
197 if (!inode->i_op->getxattr) 195 if (!inode->i_op->getxattr)
198 return INTEGRITY_UNKNOWN; 196 return INTEGRITY_UNKNOWN;
199 197
@@ -202,8 +200,11 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
202 goto out; 200 goto out;
203 201
204 cause = "missing-hash"; 202 cause = "missing-hash";
205 status = 203 status = INTEGRITY_NOLABEL;
206 (inode->i_size == 0) ? INTEGRITY_PASS : INTEGRITY_NOLABEL; 204 if (opened & FILE_CREATED) {
205 iint->flags |= IMA_NEW_FILE;
206 status = INTEGRITY_PASS;
207 }
207 goto out; 208 goto out;
208 } 209 }
209 210
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 0bd732843fe7..d34e7dfc1118 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -80,24 +80,24 @@ static int ima_kernel_read(struct file *file, loff_t offset,
80{ 80{
81 mm_segment_t old_fs; 81 mm_segment_t old_fs;
82 char __user *buf = addr; 82 char __user *buf = addr;
83 ssize_t ret; 83 ssize_t ret = -EINVAL;
84 84
85 if (!(file->f_mode & FMODE_READ)) 85 if (!(file->f_mode & FMODE_READ))
86 return -EBADF; 86 return -EBADF;
87 if (!file->f_op->read && !file->f_op->aio_read)
88 return -EINVAL;
89 87
90 old_fs = get_fs(); 88 old_fs = get_fs();
91 set_fs(get_ds()); 89 set_fs(get_ds());
92 if (file->f_op->read) 90 if (file->f_op->read)
93 ret = file->f_op->read(file, buf, count, &offset); 91 ret = file->f_op->read(file, buf, count, &offset);
94 else 92 else if (file->f_op->aio_read)
95 ret = do_sync_read(file, buf, count, &offset); 93 ret = do_sync_read(file, buf, count, &offset);
94 else if (file->f_op->read_iter)
95 ret = new_sync_read(file, buf, count, &offset);
96 set_fs(old_fs); 96 set_fs(old_fs);
97 return ret; 97 return ret;
98} 98}
99 99
100int ima_init_crypto(void) 100int __init ima_init_crypto(void)
101{ 101{
102 long rc; 102 long rc;
103 103
@@ -116,7 +116,10 @@ static struct crypto_shash *ima_alloc_tfm(enum hash_algo algo)
116 struct crypto_shash *tfm = ima_shash_tfm; 116 struct crypto_shash *tfm = ima_shash_tfm;
117 int rc; 117 int rc;
118 118
119 if (algo != ima_hash_algo && algo < HASH_ALGO__LAST) { 119 if (algo < 0 || algo >= HASH_ALGO__LAST)
120 algo = ima_hash_algo;
121
122 if (algo != ima_hash_algo) {
120 tfm = crypto_alloc_shash(hash_algo_name[algo], 0, 0); 123 tfm = crypto_alloc_shash(hash_algo_name[algo], 0, 0);
121 if (IS_ERR(tfm)) { 124 if (IS_ERR(tfm)) {
122 rc = PTR_ERR(tfm); 125 rc = PTR_ERR(tfm);
@@ -200,7 +203,10 @@ static struct crypto_ahash *ima_alloc_atfm(enum hash_algo algo)
200 struct crypto_ahash *tfm = ima_ahash_tfm; 203 struct crypto_ahash *tfm = ima_ahash_tfm;
201 int rc; 204 int rc;
202 205
203 if ((algo != ima_hash_algo && algo < HASH_ALGO__LAST) || !tfm) { 206 if (algo < 0 || algo >= HASH_ALGO__LAST)
207 algo = ima_hash_algo;
208
209 if (algo != ima_hash_algo || !tfm) {
204 tfm = crypto_alloc_ahash(hash_algo_name[algo], 0, 0); 210 tfm = crypto_alloc_ahash(hash_algo_name[algo], 0, 0);
205 if (!IS_ERR(tfm)) { 211 if (!IS_ERR(tfm)) {
206 if (algo == ima_hash_algo) 212 if (algo == ima_hash_algo)
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 2917f980bf30..673a37e92ba3 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -124,11 +124,13 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
124 return; 124 return;
125 125
126 mutex_lock(&inode->i_mutex); 126 mutex_lock(&inode->i_mutex);
127 if (atomic_read(&inode->i_writecount) == 1 && 127 if (atomic_read(&inode->i_writecount) == 1) {
128 iint->version != inode->i_version) { 128 if ((iint->version != inode->i_version) ||
129 iint->flags &= ~IMA_DONE_MASK; 129 (iint->flags & IMA_NEW_FILE)) {
130 if (iint->flags & IMA_APPRAISE) 130 iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE);
131 ima_update_xattr(iint, file); 131 if (iint->flags & IMA_APPRAISE)
132 ima_update_xattr(iint, file);
133 }
132 } 134 }
133 mutex_unlock(&inode->i_mutex); 135 mutex_unlock(&inode->i_mutex);
134} 136}
@@ -154,15 +156,15 @@ void ima_file_free(struct file *file)
154 ima_check_last_writer(iint, inode, file); 156 ima_check_last_writer(iint, inode, file);
155} 157}
156 158
157static int process_measurement(struct file *file, const char *filename, 159static int process_measurement(struct file *file, int mask, int function,
158 int mask, int function) 160 int opened)
159{ 161{
160 struct inode *inode = file_inode(file); 162 struct inode *inode = file_inode(file);
161 struct integrity_iint_cache *iint; 163 struct integrity_iint_cache *iint;
162 struct ima_template_desc *template_desc; 164 struct ima_template_desc *template_desc;
163 char *pathbuf = NULL; 165 char *pathbuf = NULL;
164 const char *pathname = NULL; 166 const char *pathname = NULL;
165 int rc = -ENOMEM, action, must_appraise, _func; 167 int rc = -ENOMEM, action, must_appraise;
166 struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL; 168 struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL;
167 int xattr_len = 0; 169 int xattr_len = 0;
168 170
@@ -180,7 +182,8 @@ static int process_measurement(struct file *file, const char *filename,
180 must_appraise = action & IMA_APPRAISE; 182 must_appraise = action & IMA_APPRAISE;
181 183
182 /* Is the appraise rule hook specific? */ 184 /* Is the appraise rule hook specific? */
183 _func = (action & IMA_FILE_APPRAISE) ? FILE_CHECK : function; 185 if (action & IMA_FILE_APPRAISE)
186 function = FILE_CHECK;
184 187
185 mutex_lock(&inode->i_mutex); 188 mutex_lock(&inode->i_mutex);
186 189
@@ -199,15 +202,13 @@ static int process_measurement(struct file *file, const char *filename,
199 /* Nothing to do, just return existing appraised status */ 202 /* Nothing to do, just return existing appraised status */
200 if (!action) { 203 if (!action) {
201 if (must_appraise) 204 if (must_appraise)
202 rc = ima_get_cache_status(iint, _func); 205 rc = ima_get_cache_status(iint, function);
203 goto out_digsig; 206 goto out_digsig;
204 } 207 }
205 208
206 template_desc = ima_template_desc_current(); 209 template_desc = ima_template_desc_current();
207 if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) { 210 if ((action & IMA_APPRAISE_SUBMASK) ||
208 if (action & IMA_APPRAISE_SUBMASK) 211 strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0)
209 xattr_ptr = &xattr_value;
210 } else
211 xattr_ptr = &xattr_value; 212 xattr_ptr = &xattr_value;
212 213
213 rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len); 214 rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len);
@@ -217,14 +218,14 @@ static int process_measurement(struct file *file, const char *filename,
217 goto out_digsig; 218 goto out_digsig;
218 } 219 }
219 220
220 pathname = filename ?: ima_d_path(&file->f_path, &pathbuf); 221 pathname = ima_d_path(&file->f_path, &pathbuf);
221 222
222 if (action & IMA_MEASURE) 223 if (action & IMA_MEASURE)
223 ima_store_measurement(iint, file, pathname, 224 ima_store_measurement(iint, file, pathname,
224 xattr_value, xattr_len); 225 xattr_value, xattr_len);
225 if (action & IMA_APPRAISE_SUBMASK) 226 if (action & IMA_APPRAISE_SUBMASK)
226 rc = ima_appraise_measurement(_func, iint, file, pathname, 227 rc = ima_appraise_measurement(function, iint, file, pathname,
227 xattr_value, xattr_len); 228 xattr_value, xattr_len, opened);
228 if (action & IMA_AUDIT) 229 if (action & IMA_AUDIT)
229 ima_audit_measurement(iint, pathname); 230 ima_audit_measurement(iint, pathname);
230 kfree(pathbuf); 231 kfree(pathbuf);
@@ -253,7 +254,7 @@ out:
253int ima_file_mmap(struct file *file, unsigned long prot) 254int ima_file_mmap(struct file *file, unsigned long prot)
254{ 255{
255 if (file && (prot & PROT_EXEC)) 256 if (file && (prot & PROT_EXEC))
256 return process_measurement(file, NULL, MAY_EXEC, MMAP_CHECK); 257 return process_measurement(file, MAY_EXEC, MMAP_CHECK, 0);
257 return 0; 258 return 0;
258} 259}
259 260
@@ -272,10 +273,7 @@ int ima_file_mmap(struct file *file, unsigned long prot)
272 */ 273 */
273int ima_bprm_check(struct linux_binprm *bprm) 274int ima_bprm_check(struct linux_binprm *bprm)
274{ 275{
275 return process_measurement(bprm->file, 276 return process_measurement(bprm->file, MAY_EXEC, BPRM_CHECK, 0);
276 (strcmp(bprm->filename, bprm->interp) == 0) ?
277 bprm->filename : bprm->interp,
278 MAY_EXEC, BPRM_CHECK);
279} 277}
280 278
281/** 279/**
@@ -288,12 +286,12 @@ int ima_bprm_check(struct linux_binprm *bprm)
288 * On success return 0. On integrity appraisal error, assuming the file 286 * On success return 0. On integrity appraisal error, assuming the file
289 * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. 287 * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
290 */ 288 */
291int ima_file_check(struct file *file, int mask) 289int ima_file_check(struct file *file, int mask, int opened)
292{ 290{
293 ima_rdwr_violation_check(file); 291 ima_rdwr_violation_check(file);
294 return process_measurement(file, NULL, 292 return process_measurement(file,
295 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 293 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
296 FILE_CHECK); 294 FILE_CHECK, opened);
297} 295}
298EXPORT_SYMBOL_GPL(ima_file_check); 296EXPORT_SYMBOL_GPL(ima_file_check);
299 297
@@ -316,7 +314,7 @@ int ima_module_check(struct file *file)
316#endif 314#endif
317 return 0; /* We rely on module signature checking */ 315 return 0; /* We rely on module signature checking */
318 } 316 }
319 return process_measurement(file, NULL, MAY_EXEC, MODULE_CHECK); 317 return process_measurement(file, MAY_EXEC, MODULE_CHECK, 0);
320} 318}
321 319
322int ima_fw_from_file(struct file *file, char *buf, size_t size) 320int ima_fw_from_file(struct file *file, char *buf, size_t size)
@@ -327,7 +325,7 @@ int ima_fw_from_file(struct file *file, char *buf, size_t size)
327 return -EACCES; /* INTEGRITY_UNKNOWN */ 325 return -EACCES; /* INTEGRITY_UNKNOWN */
328 return 0; 326 return 0;
329 } 327 }
330 return process_measurement(file, NULL, MAY_EXEC, FIRMWARE_CHECK); 328 return process_measurement(file, MAY_EXEC, FIRMWARE_CHECK, 0);
331} 329}
332 330
333static int __init init_ima(void) 331static int __init init_ima(void)
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index a076a967ec47..e854862c9337 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -152,24 +152,6 @@ out:
152 return result; 152 return result;
153} 153}
154 154
155static int init_defined_templates(void)
156{
157 int i = 0;
158 int result = 0;
159
160 /* Init defined templates. */
161 for (i = 0; i < ARRAY_SIZE(defined_templates); i++) {
162 struct ima_template_desc *template = &defined_templates[i];
163
164 result = template_desc_init_fields(template->fmt,
165 &(template->fields),
166 &(template->num_fields));
167 if (result < 0)
168 return result;
169 }
170 return result;
171}
172
173struct ima_template_desc *ima_template_desc_current(void) 155struct ima_template_desc *ima_template_desc_current(void)
174{ 156{
175 if (!ima_template) 157 if (!ima_template)
@@ -178,13 +160,11 @@ struct ima_template_desc *ima_template_desc_current(void)
178 return ima_template; 160 return ima_template;
179} 161}
180 162
181int ima_init_template(void) 163int __init ima_init_template(void)
182{ 164{
183 int result; 165 struct ima_template_desc *template = ima_template_desc_current();
184
185 result = init_defined_templates();
186 if (result < 0)
187 return result;
188 166
189 return 0; 167 return template_desc_init_fields(template->fmt,
168 &(template->fields),
169 &(template->num_fields));
190} 170}
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 19b8e314ca96..c0379d13dbe1 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -31,6 +31,7 @@
31#define IMA_DIGSIG 0x01000000 31#define IMA_DIGSIG 0x01000000
32#define IMA_DIGSIG_REQUIRED 0x02000000 32#define IMA_DIGSIG_REQUIRED 0x02000000
33#define IMA_PERMIT_DIRECTIO 0x04000000 33#define IMA_PERMIT_DIRECTIO 0x04000000
34#define IMA_NEW_FILE 0x08000000
34 35
35#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \ 36#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
36 IMA_APPRAISE_SUBMASK) 37 IMA_APPRAISE_SUBMASK)
@@ -116,7 +117,6 @@ struct integrity_iint_cache {
116/* rbtree tree calls to lookup, insert, delete 117/* rbtree tree calls to lookup, insert, delete
117 * integrity data associated with an inode. 118 * integrity data associated with an inode.
118 */ 119 */
119struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
120struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 120struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
121 121
122#define INTEGRITY_KEYRING_EVM 0 122#define INTEGRITY_KEYRING_EVM 0