[RFC][PATCH v2 3/9] ima: preserve iint flags if security.ima update is successful

Roberto Sassu roberto.sassu at huawei.com
Thu Nov 30 10:56:04 UTC 2017


During the last file close, IMA clears the flags in the IMA_DONE_MASK, to
ensure that files are measured and audited after they have been modified.
However, if security.ima is correctly updated, it wouldn't be necessary to
clear also the appraisal flags, because in this case the appraisal status
is valid.

This patch modifies ima_update_xattr() to return the result of the
security.ima update. If the operation is done successfully,
ima_check_last_writer() preserves the IMA_APPRAISED and
IMA_APPRAISED_SUBMASK iint flags.

Signed-off-by: Roberto Sassu <roberto.sassu at huawei.com>
---
 security/integrity/ima/ima.h          |  6 +++---
 security/integrity/ima/ima_appraise.c | 10 +++++-----
 security/integrity/ima/ima_main.c     | 11 +++++++++--
 3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 0703a96072b5..2bdf10417125 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -241,7 +241,7 @@ int ima_appraise_measurement(enum ima_hooks func,
 			     struct evm_ima_xattr_data *xattr_value,
 			     int xattr_len, int opened);
 int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
-void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
+int ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
 enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
 					   enum ima_hooks func);
 enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
@@ -266,8 +266,8 @@ static inline int ima_must_appraise(struct inode *inode, int mask,
 	return 0;
 }
 
-static inline void ima_update_xattr(struct integrity_iint_cache *iint,
-				    struct file *file)
+static inline int ima_update_xattr(struct integrity_iint_cache *iint,
+				   struct file *file)
 {
 }
 
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index a54ad18affb1..23e025e86aed 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -319,23 +319,23 @@ int ima_appraise_measurement(enum ima_hooks func,
 /*
  * ima_update_xattr - update 'security.ima' hash value
  */
-void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
+int ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
 {
 	struct dentry *dentry = file_dentry(file);
 	int rc = 0;
 
 	/* do not collect and update hash for digital signatures */
 	if (iint->flags & IMA_DIGSIG)
-		return;
+		return -EPERM;
 
 	if (iint->ima_file_status != INTEGRITY_PASS)
-		return;
+		return -EPERM;
 
 	rc = ima_collect_measurement(iint, file, NULL, 0, ima_hash_algo);
 	if (rc < 0)
-		return;
+		return rc;
 
-	ima_fix_xattr(dentry, iint);
+	return ima_fix_xattr(dentry, iint);
 }
 
 /**
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 5a7321bc325c..fb144177a783 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -121,6 +121,8 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
 				  struct inode *inode, struct file *file)
 {
 	fmode_t mode = file->f_mode;
+	u64 appraise_flags;
+	int rc;
 
 	if (!(mode & FMODE_WRITE))
 		return;
@@ -129,10 +131,15 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
 	if (atomic_read(&inode->i_writecount) == 1) {
 		if ((iint->version != inode->i_version) ||
 		    (iint->flags & IMA_NEW_FILE)) {
+			appraise_flags = iint->flags & (IMA_APPRAISED |
+							IMA_APPRAISED_SUBMASK);
 			iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE);
 			iint->measured_pcrs = 0;
-			if (iint->flags & IMA_APPRAISE)
-				ima_update_xattr(iint, file);
+			if (iint->flags & IMA_APPRAISE) {
+				rc = ima_update_xattr(iint, file);
+				if (!rc)
+					iint->flags |= appraise_flags;
+			}
 		}
 	}
 	inode_unlock(inode);
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the Linux-security-module-archive mailing list