aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/fs.h1
-rw-r--r--security/integrity/digsig.c14
-rw-r--r--security/integrity/iint.c49
-rw-r--r--security/integrity/ima/ima_main.c4
-rw-r--r--security/integrity/integrity.h2
5 files changed, 14 insertions, 56 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 339e73742e73..456325084f1d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2792,6 +2792,7 @@ extern int do_pipe_flags(int *, int);
2792 id(KEXEC_IMAGE, kexec-image) \ 2792 id(KEXEC_IMAGE, kexec-image) \
2793 id(KEXEC_INITRAMFS, kexec-initramfs) \ 2793 id(KEXEC_INITRAMFS, kexec-initramfs) \
2794 id(POLICY, security-policy) \ 2794 id(POLICY, security-policy) \
2795 id(X509_CERTIFICATE, x509-certificate) \
2795 id(MAX_ID, ) 2796 id(MAX_ID, )
2796 2797
2797#define __fid_enumify(ENUM, dummy) READING_ ## ENUM, 2798#define __fid_enumify(ENUM, dummy) READING_ ## ENUM,
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/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_main.c b/security/integrity/ima/ima_main.c
index 12738c8f39c2..d47f92e97f80 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -405,6 +405,10 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
405 if (!file && read_id == READING_MODULE) /* MODULE_SIG_FORCE enabled */ 405 if (!file && read_id == READING_MODULE) /* MODULE_SIG_FORCE enabled */
406 return 0; 406 return 0;
407 407
408 /* permit signed certs */
409 if (!file && read_id == READING_X509_CERTIFICATE)
410 return 0;
411
408 if (!file || !buf || size == 0) { /* should never happen */ 412 if (!file || !buf || size == 0) { /* should never happen */
409 if (ima_appraise & IMA_APPRAISE_ENFORCE) 413 if (ima_appraise & IMA_APPRAISE_ENFORCE)
410 return -EACCES; 414 return -EACCES;
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