lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230721163326.4106089-10-roberto.sassu@huaweicloud.com>
Date:   Fri, 21 Jul 2023 18:33:23 +0200
From:   Roberto Sassu <roberto.sassu@...weicloud.com>
To:     zohar@...ux.ibm.com, dmitry.kasatkin@...il.com,
        paul@...l-moore.com, jmorris@...ei.org, serge@...lyn.com
Cc:     linux-kernel@...r.kernel.org, linux-integrity@...r.kernel.org,
        linux-security-module@...r.kernel.org, bpf@...r.kernel.org,
        jarkko@...nel.org, pbrobinson@...il.com, zbyszek@...waw.pl,
        hch@....de, mjg59@...f.ucam.org,
        Roberto Sassu <roberto.sassu@...wei.com>
Subject: [RFC][PATCH 09/12] ima: Use digest cache for appraisal

From: Roberto Sassu <roberto.sassu@...wei.com>

If the digest of the accessed file is found in the digest cache, pass the
ANDed masks from the IMA policy and from the digest cache to
ima_appraise_measurement().

If the DIGEST_CACHE_APPRAISE_CONTENT flag is set in the mask, security.ima
is not available, and the modsig method is disabled, grant access in
read-only mode (except for new files).

Since xattrs were not verified with EVM, writes need to be prevented to
avoid the HMAC to be updated from an unverified one.

Signed-off-by: Roberto Sassu <roberto.sassu@...wei.com>
---
 security/integrity/ima/ima.h          |  6 ++++--
 security/integrity/ima/ima_appraise.c | 14 +++++++++++++-
 security/integrity/ima/ima_main.c     |  3 ++-
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 4f40e07954d..385aaede15b 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -322,7 +322,8 @@ int ima_appraise_measurement(enum ima_hooks func,
 			     struct integrity_iint_cache *iint,
 			     struct file *file, const unsigned char *filename,
 			     struct evm_ima_xattr_data *xattr_value,
-			     int xattr_len, const struct modsig *modsig);
+			     int xattr_len, const struct modsig *modsig,
+			     u8 digest_cache_mask);
 int ima_must_appraise(struct mnt_idmap *idmap, struct inode *inode,
 		      int mask, enum ima_hooks func);
 void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
@@ -346,7 +347,8 @@ static inline int ima_appraise_measurement(enum ima_hooks func,
 					   const unsigned char *filename,
 					   struct evm_ima_xattr_data *xattr_value,
 					   int xattr_len,
-					   const struct modsig *modsig)
+					   const struct modsig *modsig,
+					   u8 digest_cache_mask)
 {
 	return INTEGRITY_UNKNOWN;
 }
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 10dbafdae3d..e6e0ac5e26a 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -479,7 +479,8 @@ int ima_appraise_measurement(enum ima_hooks func,
 			     struct integrity_iint_cache *iint,
 			     struct file *file, const unsigned char *filename,
 			     struct evm_ima_xattr_data *xattr_value,
-			     int xattr_len, const struct modsig *modsig)
+			     int xattr_len, const struct modsig *modsig,
+			     u8 digest_cache_mask)
 {
 	static const char op[] = "appraise_data";
 	const char *cause = "unknown";
@@ -514,6 +515,17 @@ int ima_appraise_measurement(enum ima_hooks func,
 		    (!(iint->flags & IMA_DIGSIG_REQUIRED) ||
 		     (inode->i_size == 0)))
 			status = INTEGRITY_PASS;
+		/*
+		 * Except for new files, use the digest cache to appraise the
+		 * file content and, at the same time, mark the file as
+		 * immutable to prevent file updates and transitioning from an
+		 * unverified HMAC to a valid HMAC.
+		 */
+		if (status != INTEGRITY_PASS &&
+		    (digest_cache_mask & DIGEST_CACHE_APPRAISE_CONTENT)) {
+			set_bit(IMA_DIGSIG, &iint->atomic_flags);
+			status = INTEGRITY_PASS;
+		}
 		goto out;
 	}
 
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 7a5148ac3af..9f745b473bc 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -381,7 +381,8 @@ static int process_measurement(struct file *file, const struct cred *cred,
 			inode_lock(inode);
 			rc = ima_appraise_measurement(func, iint, file,
 						      pathname, xattr_value,
-						      xattr_len, modsig);
+						      xattr_len, modsig,
+						      digest_cache_mask);
 			inode_unlock(inode);
 		}
 		if (!rc)
-- 
2.34.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ