aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity/ima
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2016-01-14 17:57:47 -0500
committerMimi Zohar <zohar@linux.vnet.ibm.com>2016-02-20 22:35:08 -0500
commitcf2222178645e545e96717b2825601321ce4745c (patch)
treec13092b85aaf3207e2626c7da1102da0b5dfab36 /security/integrity/ima
parent98304bcf71845e97c0b5c800ae619311156b66c1 (diff)
ima: define a new hook to measure and appraise a file already in memory
This patch defines a new IMA hook ima_post_read_file() for measuring and appraising files read by the kernel. The caller loads the file into memory before calling this function, which calculates the hash followed by the normal IMA policy based processing. Changelog v5: - fail ima_post_read_file() if either file or buf is NULL v3: - rename ima_hash_and_process_file() to ima_post_read_file() v1: - split patch Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Acked-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
Diffstat (limited to 'security/integrity/ima')
-rw-r--r--security/integrity/ima/ima.h4
-rw-r--r--security/integrity/ima/ima_api.c6
-rw-r--r--security/integrity/ima/ima_appraise.c2
-rw-r--r--security/integrity/ima/ima_main.c45
-rw-r--r--security/integrity/ima/ima_policy.c1
5 files changed, 46 insertions, 12 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 2c5262f2823f..0b7134c04165 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -19,6 +19,7 @@
19 19
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/crypto.h> 21#include <linux/crypto.h>
22#include <linux/fs.h>
22#include <linux/security.h> 23#include <linux/security.h>
23#include <linux/hash.h> 24#include <linux/hash.h>
24#include <linux/tpm.h> 25#include <linux/tpm.h>
@@ -152,7 +153,8 @@ enum ima_hooks {
152int ima_get_action(struct inode *inode, int mask, enum ima_hooks func); 153int ima_get_action(struct inode *inode, int mask, enum ima_hooks func);
153int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func); 154int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
154int ima_collect_measurement(struct integrity_iint_cache *iint, 155int ima_collect_measurement(struct integrity_iint_cache *iint,
155 struct file *file, enum hash_algo algo); 156 struct file *file, void *buf, loff_t size,
157 enum hash_algo algo);
156void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, 158void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
157 const unsigned char *filename, 159 const unsigned char *filename,
158 struct evm_ima_xattr_data *xattr_value, 160 struct evm_ima_xattr_data *xattr_value,
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 8750254506a9..370e42dfc5c5 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -188,7 +188,8 @@ int ima_get_action(struct inode *inode, int mask, enum ima_hooks func)
188 * Return 0 on success, error code otherwise 188 * Return 0 on success, error code otherwise
189 */ 189 */
190int ima_collect_measurement(struct integrity_iint_cache *iint, 190int ima_collect_measurement(struct integrity_iint_cache *iint,
191 struct file *file, enum hash_algo algo) 191 struct file *file, void *buf, loff_t size,
192 enum hash_algo algo)
192{ 193{
193 const char *audit_cause = "failed"; 194 const char *audit_cause = "failed";
194 struct inode *inode = file_inode(file); 195 struct inode *inode = file_inode(file);
@@ -210,7 +211,8 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
210 211
211 hash.hdr.algo = algo; 212 hash.hdr.algo = algo;
212 213
213 result = ima_calc_file_hash(file, &hash.hdr); 214 result = (!buf) ? ima_calc_file_hash(file, &hash.hdr) :
215 ima_calc_buffer_hash(buf, size, &hash.hdr);
214 if (!result) { 216 if (!result) {
215 int length = sizeof(hash.hdr) + hash.hdr.length; 217 int length = sizeof(hash.hdr) + hash.hdr.length;
216 void *tmpbuf = krealloc(iint->ima_hash, length, 218 void *tmpbuf = krealloc(iint->ima_hash, length,
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 288844908788..cb0d0ff1137b 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -300,7 +300,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
300 if (iint->flags & IMA_DIGSIG) 300 if (iint->flags & IMA_DIGSIG)
301 return; 301 return;
302 302
303 rc = ima_collect_measurement(iint, file, ima_hash_algo); 303 rc = ima_collect_measurement(iint, file, NULL, 0, ima_hash_algo);
304 if (rc < 0) 304 if (rc < 0)
305 return; 305 return;
306 306
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 1be99a27a7f3..757765354158 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -153,8 +153,8 @@ void ima_file_free(struct file *file)
153 ima_check_last_writer(iint, inode, file); 153 ima_check_last_writer(iint, inode, file);
154} 154}
155 155
156static int process_measurement(struct file *file, int mask, 156static int process_measurement(struct file *file, char *buf, loff_t size,
157 enum ima_hooks func, int opened) 157 int mask, enum ima_hooks func, int opened)
158{ 158{
159 struct inode *inode = file_inode(file); 159 struct inode *inode = file_inode(file);
160 struct integrity_iint_cache *iint = NULL; 160 struct integrity_iint_cache *iint = NULL;
@@ -226,7 +226,7 @@ static int process_measurement(struct file *file, int mask,
226 226
227 hash_algo = ima_get_hash_algo(xattr_value, xattr_len); 227 hash_algo = ima_get_hash_algo(xattr_value, xattr_len);
228 228
229 rc = ima_collect_measurement(iint, file, hash_algo); 229 rc = ima_collect_measurement(iint, file, buf, size, hash_algo);
230 if (rc != 0) { 230 if (rc != 0) {
231 if (file->f_flags & O_DIRECT) 231 if (file->f_flags & O_DIRECT)
232 rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES; 232 rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES;
@@ -273,7 +273,8 @@ out:
273int ima_file_mmap(struct file *file, unsigned long prot) 273int ima_file_mmap(struct file *file, unsigned long prot)
274{ 274{
275 if (file && (prot & PROT_EXEC)) 275 if (file && (prot & PROT_EXEC))
276 return process_measurement(file, MAY_EXEC, MMAP_CHECK, 0); 276 return process_measurement(file, NULL, 0, MAY_EXEC,
277 MMAP_CHECK, 0);
277 return 0; 278 return 0;
278} 279}
279 280
@@ -292,7 +293,8 @@ int ima_file_mmap(struct file *file, unsigned long prot)
292 */ 293 */
293int ima_bprm_check(struct linux_binprm *bprm) 294int ima_bprm_check(struct linux_binprm *bprm)
294{ 295{
295 return process_measurement(bprm->file, MAY_EXEC, BPRM_CHECK, 0); 296 return process_measurement(bprm->file, NULL, 0, MAY_EXEC,
297 BPRM_CHECK, 0);
296} 298}
297 299
298/** 300/**
@@ -307,7 +309,7 @@ int ima_bprm_check(struct linux_binprm *bprm)
307 */ 309 */
308int ima_file_check(struct file *file, int mask, int opened) 310int ima_file_check(struct file *file, int mask, int opened)
309{ 311{
310 return process_measurement(file, 312 return process_measurement(file, NULL, 0,
311 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 313 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
312 FILE_CHECK, opened); 314 FILE_CHECK, opened);
313} 315}
@@ -332,7 +334,7 @@ int ima_module_check(struct file *file)
332#endif 334#endif
333 return 0; /* We rely on module signature checking */ 335 return 0; /* We rely on module signature checking */
334 } 336 }
335 return process_measurement(file, MAY_EXEC, MODULE_CHECK, 0); 337 return process_measurement(file, NULL, 0, MAY_EXEC, MODULE_CHECK, 0);
336} 338}
337 339
338int ima_fw_from_file(struct file *file, char *buf, size_t size) 340int ima_fw_from_file(struct file *file, char *buf, size_t size)
@@ -343,7 +345,34 @@ int ima_fw_from_file(struct file *file, char *buf, size_t size)
343 return -EACCES; /* INTEGRITY_UNKNOWN */ 345 return -EACCES; /* INTEGRITY_UNKNOWN */
344 return 0; 346 return 0;
345 } 347 }
346 return process_measurement(file, MAY_EXEC, FIRMWARE_CHECK, 0); 348 return process_measurement(file, NULL, 0, MAY_EXEC, FIRMWARE_CHECK, 0);
349}
350
351/**
352 * ima_post_read_file - in memory collect/appraise/audit measurement
353 * @file: pointer to the file to be measured/appraised/audit
354 * @buf: pointer to in memory file contents
355 * @size: size of in memory file contents
356 * @read_id: caller identifier
357 *
358 * Measure/appraise/audit in memory file based on policy. Policy rules
359 * are written in terms of a policy identifier.
360 *
361 * On success return 0. On integrity appraisal error, assuming the file
362 * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
363 */
364int ima_post_read_file(struct file *file, void *buf, loff_t size,
365 enum kernel_read_file_id read_id)
366{
367 enum ima_hooks func = FILE_CHECK;
368
369 if (!file || !buf || size == 0) { /* should never happen */
370 if (ima_appraise & IMA_APPRAISE_ENFORCE)
371 return -EACCES;
372 return 0;
373 }
374
375 return process_measurement(file, buf, size, MAY_READ, func, 0);
347} 376}
348 377
349static int __init init_ima(void) 378static int __init init_ima(void)
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index b089ebef6648..cfbe86f476d0 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -12,6 +12,7 @@
12 */ 12 */
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/list.h> 14#include <linux/list.h>
15#include <linux/fs.h>
15#include <linux/security.h> 16#include <linux/security.h>
16#include <linux/magic.h> 17#include <linux/magic.h>
17#include <linux/parser.h> 18#include <linux/parser.h>