aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-13 13:41:25 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-13 13:41:25 -0500
commitb33e3cc5c90b8293599318b68e61b93a89c127bb (patch)
treef61f315118d2b3e60e409c36e09fe06f8b6b6908
parent55b3a0cb5aeef0961ee18eac058e488f149a0053 (diff)
parente5729f86a2987c9404f9b2fb494b9a6fc4412baf (diff)
Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem integrity updates from James Morris: "There is a mixture of bug fixes, code cleanup, preparatory code for new functionality and new functionality. Commit 26ddabfe96bb ("evm: enable EVM when X509 certificate is loaded") enabled EVM without loading a symmetric key, but was limited to defining the x509 certificate pathname at build. Included in this set of patches is the ability of enabling EVM, without loading the EVM symmetric key, from userspace. New is the ability to prevent the loading of an EVM symmetric key." * 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: ima: Remove redundant conditional operator ima: Fix bool initialization/comparison ima: check signature enforcement against cmdline param instead of CONFIG module: export module signature enforcement status ima: fix hash algorithm initialization EVM: Only complain about a missing HMAC key once EVM: Allow userspace to signal an RSA key has been loaded EVM: Include security.apparmor in EVM measurements ima: call ima_file_free() prior to calling fasync integrity: use kernel_read_file_from_path() to read x509 certs ima: always measure and audit files in policy ima: don't remove the securityfs policy file vfs: fix mounting a filesystem with i_version
-rw-r--r--Documentation/ABI/testing/evm48
-rw-r--r--fs/file_table.c2
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/module.h7
-rw-r--r--include/uapi/linux/xattr.h3
-rw-r--r--kernel/module.c10
-rw-r--r--security/integrity/digsig.c14
-rw-r--r--security/integrity/evm/evm.h3
-rw-r--r--security/integrity/evm/evm_crypto.c2
-rw-r--r--security/integrity/evm/evm_main.c3
-rw-r--r--security/integrity/evm/evm_secfs.c29
-rw-r--r--security/integrity/iint.c49
-rw-r--r--security/integrity/ima/ima_api.c67
-rw-r--r--security/integrity/ima/ima_appraise.c4
-rw-r--r--security/integrity/ima/ima_crypto.c10
-rw-r--r--security/integrity/ima/ima_fs.c6
-rw-r--r--security/integrity/ima/ima_main.c23
-rw-r--r--security/integrity/ima/ima_policy.c6
-rw-r--r--security/integrity/integrity.h2
19 files changed, 164 insertions, 125 deletions
diff --git a/Documentation/ABI/testing/evm b/Documentation/ABI/testing/evm
index ca622c9aa24c..9578247e1792 100644
--- a/Documentation/ABI/testing/evm
+++ b/Documentation/ABI/testing/evm
@@ -7,17 +7,37 @@ Description:
7 HMAC-sha1 value across the extended attributes, storing the 7 HMAC-sha1 value across the extended attributes, storing the
8 value as the extended attribute 'security.evm'. 8 value as the extended attribute 'security.evm'.
9 9
10 EVM depends on the Kernel Key Retention System to provide it 10 EVM supports two classes of security.evm. The first is
11 with a trusted/encrypted key for the HMAC-sha1 operation. 11 an HMAC-sha1 generated locally with a
12 The key is loaded onto the root's keyring using keyctl. Until 12 trusted/encrypted key stored in the Kernel Key
13 EVM receives notification that the key has been successfully 13 Retention System. The second is a digital signature
14 loaded onto the keyring (echo 1 > <securityfs>/evm), EVM 14 generated either locally or remotely using an
15 can not create or validate the 'security.evm' xattr, but 15 asymmetric key. These keys are loaded onto root's
16 returns INTEGRITY_UNKNOWN. Loading the key and signaling EVM 16 keyring using keyctl, and EVM is then enabled by
17 should be done as early as possible. Normally this is done 17 echoing a value to <securityfs>/evm:
18 in the initramfs, which has already been measured as part 18
19 of the trusted boot. For more information on creating and 19 1: enable HMAC validation and creation
20 loading existing trusted/encrypted keys, refer to: 20 2: enable digital signature validation
21 Documentation/security/keys/trusted-encrypted.rst. (A sample 21 3: enable HMAC and digital signature validation and HMAC
22 dracut patch, which loads the trusted/encrypted key and enables 22 creation
23 EVM, is available from http://linux-ima.sourceforge.net/#EVM.) 23
24 Further writes will be blocked if HMAC support is enabled or
25 if bit 32 is set:
26
27 echo 0x80000002 ><securityfs>/evm
28
29 will enable digital signature validation and block
30 further writes to <securityfs>/evm.
31
32 Until this is done, EVM can not create or validate the
33 'security.evm' xattr, but returns INTEGRITY_UNKNOWN.
34 Loading keys and signaling EVM should be done as early
35 as possible. Normally this is done in the initramfs,
36 which has already been measured as part of the trusted
37 boot. For more information on creating and loading
38 existing trusted/encrypted keys, refer to:
39
40 Documentation/security/keys/trusted-encrypted.rst. Both dracut
41 (via 97masterkey and 98integrity) and systemd (via
42 core/ima-setup) have support for loading keys at boot
43 time.
diff --git a/fs/file_table.c b/fs/file_table.c
index 61517f57f8ef..49e1f2f1a4cb 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -201,11 +201,11 @@ static void __fput(struct file *file)
201 eventpoll_release(file); 201 eventpoll_release(file);
202 locks_remove_file(file); 202 locks_remove_file(file);
203 203
204 ima_file_free(file);
204 if (unlikely(file->f_flags & FASYNC)) { 205 if (unlikely(file->f_flags & FASYNC)) {
205 if (file->f_op->fasync) 206 if (file->f_op->fasync)
206 file->f_op->fasync(-1, file, 0); 207 file->f_op->fasync(-1, file, 0);
207 } 208 }
208 ima_file_free(file);
209 if (file->f_op->release) 209 if (file->f_op->release)
210 file->f_op->release(inode, file); 210 file->f_op->release(inode, file);
211 security_file_free(file); 211 security_file_free(file);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 885266aae2d7..e1f75a3b4af5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2793,6 +2793,7 @@ extern int do_pipe_flags(int *, int);
2793 id(KEXEC_IMAGE, kexec-image) \ 2793 id(KEXEC_IMAGE, kexec-image) \
2794 id(KEXEC_INITRAMFS, kexec-initramfs) \ 2794 id(KEXEC_INITRAMFS, kexec-initramfs) \
2795 id(POLICY, security-policy) \ 2795 id(POLICY, security-policy) \
2796 id(X509_CERTIFICATE, x509-certificate) \
2796 id(MAX_ID, ) 2797 id(MAX_ID, )
2797 2798
2798#define __fid_enumify(ENUM, dummy) READING_ ## ENUM, 2799#define __fid_enumify(ENUM, dummy) READING_ ## ENUM,
diff --git a/include/linux/module.h b/include/linux/module.h
index fe5aa3736707..c69b49abe877 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -639,6 +639,8 @@ static inline bool is_livepatch_module(struct module *mod)
639} 639}
640#endif /* CONFIG_LIVEPATCH */ 640#endif /* CONFIG_LIVEPATCH */
641 641
642bool is_module_sig_enforced(void);
643
642#else /* !CONFIG_MODULES... */ 644#else /* !CONFIG_MODULES... */
643 645
644static inline struct module *__module_address(unsigned long addr) 646static inline struct module *__module_address(unsigned long addr)
@@ -753,6 +755,11 @@ static inline bool module_requested_async_probing(struct module *module)
753 return false; 755 return false;
754} 756}
755 757
758static inline bool is_module_sig_enforced(void)
759{
760 return false;
761}
762
756#endif /* CONFIG_MODULES */ 763#endif /* CONFIG_MODULES */
757 764
758#ifdef CONFIG_SYSFS 765#ifdef CONFIG_SYSFS
diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h
index a92be0f492a9..c1395b5bd432 100644
--- a/include/uapi/linux/xattr.h
+++ b/include/uapi/linux/xattr.h
@@ -66,6 +66,9 @@
66#define XATTR_NAME_SMACKTRANSMUTE XATTR_SECURITY_PREFIX XATTR_SMACK_TRANSMUTE 66#define XATTR_NAME_SMACKTRANSMUTE XATTR_SECURITY_PREFIX XATTR_SMACK_TRANSMUTE
67#define XATTR_NAME_SMACKMMAP XATTR_SECURITY_PREFIX XATTR_SMACK_MMAP 67#define XATTR_NAME_SMACKMMAP XATTR_SECURITY_PREFIX XATTR_SMACK_MMAP
68 68
69#define XATTR_APPARMOR_SUFFIX "apparmor"
70#define XATTR_NAME_APPARMOR XATTR_SECURITY_PREFIX XATTR_APPARMOR_SUFFIX
71
69#define XATTR_CAPS_SUFFIX "capability" 72#define XATTR_CAPS_SUFFIX "capability"
70#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX 73#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
71 74
diff --git a/kernel/module.c b/kernel/module.c
index 0122747ba150..32c2cdaccd93 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -278,6 +278,16 @@ static bool sig_enforce = IS_ENABLED(CONFIG_MODULE_SIG_FORCE);
278module_param(sig_enforce, bool_enable_only, 0644); 278module_param(sig_enforce, bool_enable_only, 0644);
279#endif /* !CONFIG_MODULE_SIG_FORCE */ 279#endif /* !CONFIG_MODULE_SIG_FORCE */
280 280
281/*
282 * Export sig_enforce kernel cmdline parameter to allow other subsystems rely
283 * on that instead of directly to CONFIG_MODULE_SIG_FORCE config.
284 */
285bool is_module_sig_enforced(void)
286{
287 return sig_enforce;
288}
289EXPORT_SYMBOL(is_module_sig_enforced);
290
281/* Block module loading/unloading? */ 291/* Block module loading/unloading? */
282int modules_disabled = 0; 292int modules_disabled = 0;
283core_param(nomodule, modules_disabled, bint, 0); 293core_param(nomodule, modules_disabled, bint, 0);
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 06554c448dce..6f9e4ce568cd 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -112,21 +112,25 @@ int __init integrity_init_keyring(const unsigned int id)
112int __init integrity_load_x509(const unsigned int id, const char *path) 112int __init integrity_load_x509(const unsigned int id, const char *path)
113{ 113{
114 key_ref_t key; 114 key_ref_t key;
115 char *data; 115 void *data;
116 loff_t size;
116 int rc; 117 int rc;
117 118
118 if (!keyring[id]) 119 if (!keyring[id])
119 return -EINVAL; 120 return -EINVAL;
120 121
121 rc = integrity_read_file(path, &data); 122 rc = kernel_read_file_from_path(path, &data, &size, 0,
122 if (rc < 0) 123 READING_X509_CERTIFICATE);
124 if (rc < 0) {
125 pr_err("Unable to open file: %s (%d)", path, rc);
123 return rc; 126 return rc;
127 }
124 128
125 key = key_create_or_update(make_key_ref(keyring[id], 1), 129 key = key_create_or_update(make_key_ref(keyring[id], 1),
126 "asymmetric", 130 "asymmetric",
127 NULL, 131 NULL,
128 data, 132 data,
129 rc, 133 size,
130 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 134 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
131 KEY_USR_VIEW | KEY_USR_READ), 135 KEY_USR_VIEW | KEY_USR_READ),
132 KEY_ALLOC_NOT_IN_QUOTA); 136 KEY_ALLOC_NOT_IN_QUOTA);
@@ -139,6 +143,6 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
139 key_ref_to_ptr(key)->description, path); 143 key_ref_to_ptr(key)->description, path);
140 key_ref_put(key); 144 key_ref_put(key);
141 } 145 }
142 kfree(data); 146 vfree(data);
143 return 0; 147 return 0;
144} 148}
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index f5f12727771a..241aca315b0c 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -23,6 +23,9 @@
23 23
24#define EVM_INIT_HMAC 0x0001 24#define EVM_INIT_HMAC 0x0001
25#define EVM_INIT_X509 0x0002 25#define EVM_INIT_X509 0x0002
26#define EVM_SETUP 0x80000000 /* userland has signaled key load */
27
28#define EVM_INIT_MASK (EVM_INIT_HMAC | EVM_INIT_X509 | EVM_SETUP)
26 29
27extern int evm_initialized; 30extern int evm_initialized;
28extern char *evm_hmac; 31extern char *evm_hmac;
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 1d32cd20009a..bcd64baf8788 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -80,7 +80,7 @@ static struct shash_desc *init_desc(char type)
80 80
81 if (type == EVM_XATTR_HMAC) { 81 if (type == EVM_XATTR_HMAC) {
82 if (!(evm_initialized & EVM_INIT_HMAC)) { 82 if (!(evm_initialized & EVM_INIT_HMAC)) {
83 pr_err("HMAC key is not set\n"); 83 pr_err_once("HMAC key is not set\n");
84 return ERR_PTR(-ENOKEY); 84 return ERR_PTR(-ENOKEY);
85 } 85 }
86 tfm = &hmac_tfm; 86 tfm = &hmac_tfm;
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 063d38aef64e..9826c02e2db8 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -49,6 +49,9 @@ char *evm_config_xattrnames[] = {
49 XATTR_NAME_SMACKMMAP, 49 XATTR_NAME_SMACKMMAP,
50#endif 50#endif
51#endif 51#endif
52#ifdef CONFIG_SECURITY_APPARMOR
53 XATTR_NAME_APPARMOR,
54#endif
52#ifdef CONFIG_IMA_APPRAISE 55#ifdef CONFIG_IMA_APPRAISE
53 XATTR_NAME_IMA, 56 XATTR_NAME_IMA,
54#endif 57#endif
diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
index c8dccd54d501..319cf16d6603 100644
--- a/security/integrity/evm/evm_secfs.c
+++ b/security/integrity/evm/evm_secfs.c
@@ -40,7 +40,7 @@ static ssize_t evm_read_key(struct file *filp, char __user *buf,
40 if (*ppos != 0) 40 if (*ppos != 0)
41 return 0; 41 return 0;
42 42
43 sprintf(temp, "%d", evm_initialized); 43 sprintf(temp, "%d", (evm_initialized & ~EVM_SETUP));
44 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); 44 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
45 45
46 return rc; 46 return rc;
@@ -61,24 +61,29 @@ static ssize_t evm_read_key(struct file *filp, char __user *buf,
61static ssize_t evm_write_key(struct file *file, const char __user *buf, 61static ssize_t evm_write_key(struct file *file, const char __user *buf,
62 size_t count, loff_t *ppos) 62 size_t count, loff_t *ppos)
63{ 63{
64 char temp[80]; 64 int i, ret;
65 int i;
66 65
67 if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_INIT_HMAC)) 66 if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_SETUP))
68 return -EPERM; 67 return -EPERM;
69 68
70 if (count >= sizeof(temp) || count == 0) 69 ret = kstrtoint_from_user(buf, count, 0, &i);
71 return -EINVAL;
72
73 if (copy_from_user(temp, buf, count) != 0)
74 return -EFAULT;
75 70
76 temp[count] = '\0'; 71 if (ret)
72 return ret;
77 73
78 if ((sscanf(temp, "%d", &i) != 1) || (i != 1)) 74 /* Reject invalid values */
75 if (!i || (i & ~EVM_INIT_MASK) != 0)
79 return -EINVAL; 76 return -EINVAL;
80 77
81 evm_init_key(); 78 if (i & EVM_INIT_HMAC) {
79 ret = evm_init_key();
80 if (ret != 0)
81 return ret;
82 /* Forbid further writes after the symmetric key is loaded */
83 i |= EVM_SETUP;
84 }
85
86 evm_initialized |= i;
82 87
83 return count; 88 return count;
84} 89}
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 6fc888ca468e..c84e05866052 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -200,55 +200,6 @@ int integrity_kernel_read(struct file *file, loff_t offset,
200} 200}
201 201
202/* 202/*
203 * integrity_read_file - read entire file content into the buffer
204 *
205 * This is function opens a file, allocates the buffer of required
206 * size, read entire file content to the buffer and closes the file
207 *
208 * It is used only by init code.
209 *
210 */
211int __init integrity_read_file(const char *path, char **data)
212{
213 struct file *file;
214 loff_t size;
215 char *buf;
216 int rc = -EINVAL;
217
218 if (!path || !*path)
219 return -EINVAL;
220
221 file = filp_open(path, O_RDONLY, 0);
222 if (IS_ERR(file)) {
223 rc = PTR_ERR(file);
224 pr_err("Unable to open file: %s (%d)", path, rc);
225 return rc;
226 }
227
228 size = i_size_read(file_inode(file));
229 if (size <= 0)
230 goto out;
231
232 buf = kmalloc(size, GFP_KERNEL);
233 if (!buf) {
234 rc = -ENOMEM;
235 goto out;
236 }
237
238 rc = integrity_kernel_read(file, 0, buf, size);
239 if (rc == size) {
240 *data = buf;
241 } else {
242 kfree(buf);
243 if (rc >= 0)
244 rc = -EIO;
245 }
246out:
247 fput(file);
248 return rc;
249}
250
251/*
252 * integrity_load_keys - load integrity keys hook 203 * integrity_load_keys - load integrity keys hook
253 * 204 *
254 * Hooks is called from init/main.c:kernel_init_freeable() 205 * Hooks is called from init/main.c:kernel_init_freeable()
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index c2edba8de35e..c7e8db0ea4c0 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -199,42 +199,59 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
199 struct inode *inode = file_inode(file); 199 struct inode *inode = file_inode(file);
200 const char *filename = file->f_path.dentry->d_name.name; 200 const char *filename = file->f_path.dentry->d_name.name;
201 int result = 0; 201 int result = 0;
202 int length;
203 void *tmpbuf;
204 u64 i_version;
202 struct { 205 struct {
203 struct ima_digest_data hdr; 206 struct ima_digest_data hdr;
204 char digest[IMA_MAX_DIGEST_SIZE]; 207 char digest[IMA_MAX_DIGEST_SIZE];
205 } hash; 208 } hash;
206 209
207 if (!(iint->flags & IMA_COLLECTED)) { 210 if (iint->flags & IMA_COLLECTED)
208 u64 i_version = file_inode(file)->i_version; 211 goto out;
209 212
210 if (file->f_flags & O_DIRECT) { 213 /*
211 audit_cause = "failed(directio)"; 214 * Dectecting file change is based on i_version. On filesystems
212 result = -EACCES; 215 * which do not support i_version, support is limited to an initial
213 goto out; 216 * measurement/appraisal/audit.
214 } 217 */
218 i_version = file_inode(file)->i_version;
219 hash.hdr.algo = algo;
215 220
216 hash.hdr.algo = algo; 221 /* Initialize hash digest to 0's in case of failure */
217 222 memset(&hash.digest, 0, sizeof(hash.digest));
218 result = (!buf) ? ima_calc_file_hash(file, &hash.hdr) : 223
219 ima_calc_buffer_hash(buf, size, &hash.hdr); 224 if (buf)
220 if (!result) { 225 result = ima_calc_buffer_hash(buf, size, &hash.hdr);
221 int length = sizeof(hash.hdr) + hash.hdr.length; 226 else
222 void *tmpbuf = krealloc(iint->ima_hash, length, 227 result = ima_calc_file_hash(file, &hash.hdr);
223 GFP_NOFS); 228
224 if (tmpbuf) { 229 if (result && result != -EBADF && result != -EINVAL)
225 iint->ima_hash = tmpbuf; 230 goto out;
226 memcpy(iint->ima_hash, &hash, length); 231
227 iint->version = i_version; 232 length = sizeof(hash.hdr) + hash.hdr.length;
228 iint->flags |= IMA_COLLECTED; 233 tmpbuf = krealloc(iint->ima_hash, length, GFP_NOFS);
229 } else 234 if (!tmpbuf) {
230 result = -ENOMEM; 235 result = -ENOMEM;
231 } 236 goto out;
232 } 237 }
238
239 iint->ima_hash = tmpbuf;
240 memcpy(iint->ima_hash, &hash, length);
241 iint->version = i_version;
242
243 /* Possibly temporary failure due to type of read (eg. O_DIRECT) */
244 if (!result)
245 iint->flags |= IMA_COLLECTED;
233out: 246out:
234 if (result) 247 if (result) {
248 if (file->f_flags & O_DIRECT)
249 audit_cause = "failed(directio)";
250
235 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, 251 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
236 filename, "collect_data", audit_cause, 252 filename, "collect_data", audit_cause,
237 result, 0); 253 result, 0);
254 }
238 return result; 255 return result;
239} 256}
240 257
@@ -278,7 +295,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
278 } 295 }
279 296
280 result = ima_store_template(entry, violation, inode, filename, pcr); 297 result = ima_store_template(entry, violation, inode, filename, pcr);
281 if (!result || result == -EEXIST) { 298 if ((!result || result == -EEXIST) && !(file->f_flags & O_DIRECT)) {
282 iint->flags |= IMA_MEASURED; 299 iint->flags |= IMA_MEASURED;
283 iint->measured_pcrs |= (0x1 << pcr); 300 iint->measured_pcrs |= (0x1 << pcr);
284 } 301 }
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 809ba70fbbbf..ec7dfa02c051 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -40,7 +40,7 @@ __setup("ima_appraise=", default_appraise_setup);
40 */ 40 */
41bool is_ima_appraise_enabled(void) 41bool is_ima_appraise_enabled(void)
42{ 42{
43 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? 1 : 0; 43 return ima_appraise & IMA_APPRAISE_ENFORCE;
44} 44}
45 45
46/* 46/*
@@ -405,7 +405,7 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
405 if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST)) 405 if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST))
406 return -EINVAL; 406 return -EINVAL;
407 ima_reset_appraise_flags(d_backing_inode(dentry), 407 ima_reset_appraise_flags(d_backing_inode(dentry),
408 (xvalue->type == EVM_IMA_XATTR_DIGSIG) ? 1 : 0); 408 xvalue->type == EVM_IMA_XATTR_DIGSIG);
409 result = 0; 409 result = 0;
410 } 410 }
411 return result; 411 return result;
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 802d5d20f36f..a856d8c9c9f3 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -441,6 +441,16 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
441 loff_t i_size; 441 loff_t i_size;
442 int rc; 442 int rc;
443 443
444 /*
445 * For consistency, fail file's opened with the O_DIRECT flag on
446 * filesystems mounted with/without DAX option.
447 */
448 if (file->f_flags & O_DIRECT) {
449 hash->length = hash_digest_size[ima_hash_algo];
450 hash->algo = ima_hash_algo;
451 return -EINVAL;
452 }
453
444 i_size = i_size_read(file_inode(file)); 454 i_size = i_size_read(file_inode(file));
445 455
446 if (ima_ahash_minsize && i_size >= ima_ahash_minsize) { 456 if (ima_ahash_minsize && i_size >= ima_ahash_minsize) {
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index ad491c51e833..fa540c0469da 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -32,7 +32,7 @@ bool ima_canonical_fmt;
32static int __init default_canonical_fmt_setup(char *str) 32static int __init default_canonical_fmt_setup(char *str)
33{ 33{
34#ifdef __BIG_ENDIAN 34#ifdef __BIG_ENDIAN
35 ima_canonical_fmt = 1; 35 ima_canonical_fmt = true;
36#endif 36#endif
37 return 1; 37 return 1;
38} 38}
@@ -429,10 +429,10 @@ static int ima_release_policy(struct inode *inode, struct file *file)
429 } 429 }
430 430
431 ima_update_policy(); 431 ima_update_policy();
432#ifndef CONFIG_IMA_WRITE_POLICY 432#if !defined(CONFIG_IMA_WRITE_POLICY) && !defined(CONFIG_IMA_READ_POLICY)
433 securityfs_remove(ima_policy); 433 securityfs_remove(ima_policy);
434 ima_policy = NULL; 434 ima_policy = NULL;
435#else 435#elif defined(CONFIG_IMA_WRITE_POLICY)
436 clear_bit(IMA_FS_BUSY, &ima_fs_flags); 436 clear_bit(IMA_FS_BUSY, &ima_fs_flags);
437#endif 437#endif
438 return 0; 438 return 0;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 2aebb7984437..770654694efc 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -51,6 +51,8 @@ static int __init hash_setup(char *str)
51 ima_hash_algo = HASH_ALGO_SHA1; 51 ima_hash_algo = HASH_ALGO_SHA1;
52 else if (strncmp(str, "md5", 3) == 0) 52 else if (strncmp(str, "md5", 3) == 0)
53 ima_hash_algo = HASH_ALGO_MD5; 53 ima_hash_algo = HASH_ALGO_MD5;
54 else
55 return 1;
54 goto out; 56 goto out;
55 } 57 }
56 58
@@ -60,6 +62,8 @@ static int __init hash_setup(char *str)
60 break; 62 break;
61 } 63 }
62 } 64 }
65 if (i == HASH_ALGO__LAST)
66 return 1;
63out: 67out:
64 hash_setup_done = 1; 68 hash_setup_done = 1;
65 return 1; 69 return 1;
@@ -235,11 +239,8 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
235 hash_algo = ima_get_hash_algo(xattr_value, xattr_len); 239 hash_algo = ima_get_hash_algo(xattr_value, xattr_len);
236 240
237 rc = ima_collect_measurement(iint, file, buf, size, hash_algo); 241 rc = ima_collect_measurement(iint, file, buf, size, hash_algo);
238 if (rc != 0) { 242 if (rc != 0 && rc != -EBADF && rc != -EINVAL)
239 if (file->f_flags & O_DIRECT)
240 rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES;
241 goto out_digsig; 243 goto out_digsig;
242 }
243 244
244 if (!pathbuf) /* ima_rdwr_violation possibly pre-fetched */ 245 if (!pathbuf) /* ima_rdwr_violation possibly pre-fetched */
245 pathname = ima_d_path(&file->f_path, &pathbuf, filename); 246 pathname = ima_d_path(&file->f_path, &pathbuf, filename);
@@ -247,12 +248,14 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
247 if (action & IMA_MEASURE) 248 if (action & IMA_MEASURE)
248 ima_store_measurement(iint, file, pathname, 249 ima_store_measurement(iint, file, pathname,
249 xattr_value, xattr_len, pcr); 250 xattr_value, xattr_len, pcr);
250 if (action & IMA_APPRAISE_SUBMASK) 251 if (rc == 0 && (action & IMA_APPRAISE_SUBMASK))
251 rc = ima_appraise_measurement(func, iint, file, pathname, 252 rc = ima_appraise_measurement(func, iint, file, pathname,
252 xattr_value, xattr_len, opened); 253 xattr_value, xattr_len, opened);
253 if (action & IMA_AUDIT) 254 if (action & IMA_AUDIT)
254 ima_audit_measurement(iint, pathname); 255 ima_audit_measurement(iint, pathname);
255 256
257 if ((file->f_flags & O_DIRECT) && (iint->flags & IMA_PERMIT_DIRECTIO))
258 rc = 0;
256out_digsig: 259out_digsig:
257 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG) && 260 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG) &&
258 !(iint->flags & IMA_NEW_FILE)) 261 !(iint->flags & IMA_NEW_FILE))
@@ -359,12 +362,12 @@ void ima_post_path_mknod(struct dentry *dentry)
359 */ 362 */
360int ima_read_file(struct file *file, enum kernel_read_file_id read_id) 363int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
361{ 364{
365 bool sig_enforce = is_module_sig_enforced();
366
362 if (!file && read_id == READING_MODULE) { 367 if (!file && read_id == READING_MODULE) {
363#ifndef CONFIG_MODULE_SIG_FORCE 368 if (!sig_enforce && (ima_appraise & IMA_APPRAISE_MODULES) &&
364 if ((ima_appraise & IMA_APPRAISE_MODULES) &&
365 (ima_appraise & IMA_APPRAISE_ENFORCE)) 369 (ima_appraise & IMA_APPRAISE_ENFORCE))
366 return -EACCES; /* INTEGRITY_UNKNOWN */ 370 return -EACCES; /* INTEGRITY_UNKNOWN */
367#endif
368 return 0; /* We rely on module signature checking */ 371 return 0; /* We rely on module signature checking */
369 } 372 }
370 return 0; 373 return 0;
@@ -406,6 +409,10 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
406 if (!file && read_id == READING_MODULE) /* MODULE_SIG_FORCE enabled */ 409 if (!file && read_id == READING_MODULE) /* MODULE_SIG_FORCE enabled */
407 return 0; 410 return 0;
408 411
412 /* permit signed certs */
413 if (!file && read_id == READING_X509_CERTIFICATE)
414 return 0;
415
409 if (!file || !buf || size == 0) { /* should never happen */ 416 if (!file || !buf || size == 0) { /* should never happen */
410 if (ima_appraise & IMA_APPRAISE_ENFORCE) 417 if (ima_appraise & IMA_APPRAISE_ENFORCE)
411 return -EACCES; 418 return -EACCES;
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 95209a5f8595..ee4613fa5840 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -196,9 +196,9 @@ static int __init policy_setup(char *str)
196 if ((strcmp(p, "tcb") == 0) && !ima_policy) 196 if ((strcmp(p, "tcb") == 0) && !ima_policy)
197 ima_policy = DEFAULT_TCB; 197 ima_policy = DEFAULT_TCB;
198 else if (strcmp(p, "appraise_tcb") == 0) 198 else if (strcmp(p, "appraise_tcb") == 0)
199 ima_use_appraise_tcb = 1; 199 ima_use_appraise_tcb = true;
200 else if (strcmp(p, "secure_boot") == 0) 200 else if (strcmp(p, "secure_boot") == 0)
201 ima_use_secure_boot = 1; 201 ima_use_secure_boot = true;
202 } 202 }
203 203
204 return 1; 204 return 1;
@@ -207,7 +207,7 @@ __setup("ima_policy=", policy_setup);
207 207
208static int __init default_appraise_policy_setup(char *str) 208static int __init default_appraise_policy_setup(char *str)
209{ 209{
210 ima_use_appraise_tcb = 1; 210 ima_use_appraise_tcb = true;
211 return 1; 211 return 1;
212} 212}
213__setup("ima_appraise_tcb", default_appraise_policy_setup); 213__setup("ima_appraise_tcb", default_appraise_policy_setup);
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index a53e7e4ab06c..e1bf040fb110 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -120,8 +120,6 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
120int integrity_kernel_read(struct file *file, loff_t offset, 120int integrity_kernel_read(struct file *file, loff_t offset,
121 void *addr, unsigned long count); 121 void *addr, unsigned long count);
122 122
123int __init integrity_read_file(const char *path, char **data);
124
125#define INTEGRITY_KEYRING_EVM 0 123#define INTEGRITY_KEYRING_EVM 0
126#define INTEGRITY_KEYRING_IMA 1 124#define INTEGRITY_KEYRING_IMA 1
127#define INTEGRITY_KEYRING_MODULE 2 125#define INTEGRITY_KEYRING_MODULE 2