aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2016-02-29 19:52:05 -0500
committerMimi Zohar <zohar@linux.vnet.ibm.com>2016-05-01 09:23:52 -0400
commit05d1a717ec0430c916a749b94eb90ab74bbfa356 (patch)
treed5283278e18669da5c76e41d1d33d58787dc61bc /security/integrity
parent42a4c603198f0d45b7aa936d3ac6ba1b8bd14a1b (diff)
ima: add support for creating files using the mknodat syscall
Commit 3034a14 "ima: pass 'opened' flag to identify newly created files" stopped identifying empty files as new files. However new empty files can be created using the mknodat syscall. On systems with IMA-appraisal enabled, these empty files are not labeled with security.ima extended attributes properly, preventing them from subsequently being opened in order to write the file data contents. This patch defines a new hook named ima_post_path_mknod() to mark these empty files, created using mknodat, as new in order to allow the file data contents to be written. In addition, files with security.ima xattrs containing a file signature are considered "immutable" and can not be modified. The file contents need to be written, before signing the file. This patch relaxes this requirement for new files, allowing the file signature to be written before the file contents. Changelog: - defer identifying files with signatures stored as security.ima (based on Dmitry Rozhkov's comments) - removing tests (eg. dentry, dentry->d_inode, inode->i_size == 0) (based on Al's review) Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Cc: Al Viro <<viro@zeniv.linux.org.uk> Tested-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
Diffstat (limited to 'security/integrity')
-rw-r--r--security/integrity/ima/ima_appraise.c5
-rw-r--r--security/integrity/ima/ima_main.c25
2 files changed, 29 insertions, 1 deletions
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index d2f28a0c8614..1bcbc12e03d9 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -275,6 +275,11 @@ out:
275 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) { 275 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) {
276 if (!ima_fix_xattr(dentry, iint)) 276 if (!ima_fix_xattr(dentry, iint))
277 status = INTEGRITY_PASS; 277 status = INTEGRITY_PASS;
278 } else if ((inode->i_size == 0) &&
279 (iint->flags & IMA_NEW_FILE) &&
280 (xattr_value &&
281 xattr_value->type == EVM_IMA_XATTR_DIGSIG)) {
282 status = INTEGRITY_PASS;
278 } 283 }
279 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename, 284 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename,
280 op, cause, rc, 0); 285 op, cause, rc, 0);
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 391f41751021..68b26c340acd 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -246,7 +246,8 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
246 ima_audit_measurement(iint, pathname); 246 ima_audit_measurement(iint, pathname);
247 247
248out_digsig: 248out_digsig:
249 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG)) 249 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG) &&
250 !(iint->flags & IMA_NEW_FILE))
250 rc = -EACCES; 251 rc = -EACCES;
251 kfree(xattr_value); 252 kfree(xattr_value);
252out_free: 253out_free:
@@ -316,6 +317,28 @@ int ima_file_check(struct file *file, int mask, int opened)
316EXPORT_SYMBOL_GPL(ima_file_check); 317EXPORT_SYMBOL_GPL(ima_file_check);
317 318
318/** 319/**
320 * ima_post_path_mknod - mark as a new inode
321 * @dentry: newly created dentry
322 *
323 * Mark files created via the mknodat syscall as new, so that the
324 * file data can be written later.
325 */
326void ima_post_path_mknod(struct dentry *dentry)
327{
328 struct integrity_iint_cache *iint;
329 struct inode *inode = dentry->d_inode;
330 int must_appraise;
331
332 must_appraise = ima_must_appraise(inode, MAY_ACCESS, FILE_CHECK);
333 if (!must_appraise)
334 return;
335
336 iint = integrity_inode_get(inode);
337 if (iint)
338 iint->flags |= IMA_NEW_FILE;
339}
340
341/**
319 * ima_read_file - pre-measure/appraise hook decision based on policy 342 * ima_read_file - pre-measure/appraise hook decision based on policy
320 * @file: pointer to the file to be measured/appraised/audit 343 * @file: pointer to the file to be measured/appraised/audit
321 * @read_id: caller identifier 344 * @read_id: caller identifier