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: <20240905152512.3781098-7-roberto.sassu@huaweicloud.com>
Date: Thu,  5 Sep 2024 17:25:08 +0200
From: Roberto Sassu <roberto.sassu@...weicloud.com>
To: corbet@....net,
	zohar@...ux.ibm.com,
	dmitry.kasatkin@...il.com,
	eric.snowberg@...cle.com,
	paul@...l-moore.com,
	jmorris@...ei.org,
	serge@...lyn.com
Cc: linux-kernel@...r.kernel.org,
	linux-doc@...r.kernel.org,
	linux-integrity@...r.kernel.org,
	linux-security-module@...r.kernel.org,
	wufan@...ux.microsoft.com,
	pbrobinson@...il.com,
	zbyszek@...waw.pl,
	hch@....de,
	mjg59@...f.ucam.org,
	pmatilai@...hat.com,
	jannh@...gle.com,
	dhowells@...hat.com,
	jikos@...nel.org,
	mkoutny@...e.com,
	ppavlu@...e.com,
	petr.vorel@...il.com,
	mzerqung@...inter.de,
	kgold@...ux.ibm.com,
	Roberto Sassu <roberto.sassu@...wei.com>
Subject: [RFC][PATCH v3 06/10] ima: Retrieve digest cache and check if changed

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

Add a digest cache pointer to the ima_iint_cache structure and introduce
ima_digest_cache_get_check() to retrieve a fresh digest cache and compare
with the pointer stored in the previous calls (if digest cache was enabled
in the IMA policy).

If the pointers don't match, reset the integrity status since the digest
cache used for the previous verification might have changed.

Also, initialize and put the digest cache respectively in
ima_iint_init_always() and ima_iint_free().

Signed-off-by: Roberto Sassu <roberto.sassu@...wei.com>
---
 security/integrity/ima/Makefile           |  1 +
 security/integrity/ima/ima.h              |  1 +
 security/integrity/ima/ima_digest_cache.c | 49 +++++++++++++++++++++++
 security/integrity/ima/ima_digest_cache.h | 22 ++++++++++
 security/integrity/ima/ima_iint.c         |  4 ++
 security/integrity/ima/ima_main.c         | 10 ++++-
 6 files changed, 86 insertions(+), 1 deletion(-)
 create mode 100644 security/integrity/ima/ima_digest_cache.c
 create mode 100644 security/integrity/ima/ima_digest_cache.h

diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index b376d38b4ee6..b4a284634a07 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -14,6 +14,7 @@ ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
 ima-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
 ima-$(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) += ima_asymmetric_keys.o
 ima-$(CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS) += ima_queue_keys.o
+ima-$(CONFIG_INTEGRITY_DIGEST_CACHE) += ima_digest_cache.o
 
 ifeq ($(CONFIG_EFI),y)
 ima-$(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) += ima_efi.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 736fe014afbc..b2ef37a11b65 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -198,6 +198,7 @@ struct ima_iint_cache {
 	enum integrity_status ima_read_status:4;
 	enum integrity_status ima_creds_status:4;
 	struct ima_digest_data *ima_hash;
+	struct digest_cache *digest_cache;
 };
 
 extern struct lsm_blob_sizes ima_blob_sizes;
diff --git a/security/integrity/ima/ima_digest_cache.c b/security/integrity/ima/ima_digest_cache.c
new file mode 100644
index 000000000000..bf720684b7b1
--- /dev/null
+++ b/security/integrity/ima/ima_digest_cache.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Huawei Technologies Duesseldorf GmbH
+ *
+ * Author: Roberto Sassu <roberto.sassu@...wei.com>
+ *
+ * Integrate with the Integrity Digest Cache.
+ */
+
+#include <linux/digest_cache.h>
+
+#include "ima_digest_cache.h"
+
+/**
+ * ima_digest_cache_get_check - Get digest cache and check if changed
+ * @dentry: Dentry of the inode for which the digest cache will be used
+ * @iint: Inode integrity metadata
+ *
+ * Get a digest cache for the dentry parameter and compare with the digest
+ * cache stored in the inode integrity metadata.
+ *
+ * It must be called with the iint->mutex held.
+ *
+ * Return: True if the digest cache pointer changed, false otherwise.
+ */
+bool ima_digest_cache_get_check(struct dentry *dentry,
+				struct ima_iint_cache *iint)
+{
+	struct digest_cache *digest_cache;
+
+	digest_cache = digest_cache_get(dentry);
+
+	/* There was no digest cache before, not changed. */
+	if (!iint->digest_cache) {
+		iint->digest_cache = digest_cache;
+		return false;
+	}
+
+	/* New digest cache not available, or digest cache changed. */
+	if (!digest_cache || iint->digest_cache != digest_cache) {
+		digest_cache_put(iint->digest_cache);
+		iint->digest_cache = digest_cache;
+		return true;
+	}
+
+	/* Digest cache not changed. */
+	digest_cache_put(digest_cache);
+	return false;
+}
diff --git a/security/integrity/ima/ima_digest_cache.h b/security/integrity/ima/ima_digest_cache.h
new file mode 100644
index 000000000000..75b6ac8732d3
--- /dev/null
+++ b/security/integrity/ima/ima_digest_cache.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2024 Huawei Technologies Duesseldorf GmbH
+ *
+ * Author: Roberto Sassu <roberto.sassu@...wei.com>
+ *
+ * Header file of ima_digest_cache.c.
+ */
+
+#include "ima.h"
+
+#ifdef CONFIG_INTEGRITY_DIGEST_CACHE
+bool ima_digest_cache_get_check(struct dentry *dentry,
+				struct ima_iint_cache *iint);
+#else
+static inline bool ima_digest_cache_get_check(struct dentry *dentry,
+					      struct ima_iint_cache *iint)
+{
+	return false;
+}
+
+#endif /* CONFIG_INTEGRITY_DIGEST_CACHE */
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
index e23412a2c56b..d6946cd4fa91 100644
--- a/security/integrity/ima/ima_iint.c
+++ b/security/integrity/ima/ima_iint.c
@@ -68,12 +68,16 @@ static void ima_iint_init_always(struct ima_iint_cache *iint,
 	iint->ima_read_status = INTEGRITY_UNKNOWN;
 	iint->ima_creds_status = INTEGRITY_UNKNOWN;
 	iint->measured_pcrs = 0;
+	iint->digest_cache = NULL;
 	mutex_init(&iint->mutex);
 	ima_iint_lockdep_annotate(iint, inode);
 }
 
 static void ima_iint_free(struct ima_iint_cache *iint)
 {
+	if (iint->digest_cache)
+		digest_cache_put(iint->digest_cache);
+
 	kfree(iint->ima_hash);
 	mutex_destroy(&iint->mutex);
 	kmem_cache_free(ima_iint_cache, iint);
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index ebf233664194..ae106f1fe144 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -224,6 +224,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
 	bool violation_check;
 	enum hash_algo hash_algo;
 	unsigned int allowed_algos = 0;
+	u64 policy_usage = 0ULL;
 
 	if (!ima_policy_flag || !S_ISREG(inode->i_mode))
 		return 0;
@@ -234,7 +235,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
 	 */
 	action = ima_get_action(file_mnt_idmap(file), inode, cred, secid,
 				mask, func, &pcr, &template_desc, NULL,
-				&allowed_algos, NULL);
+				&allowed_algos, &policy_usage);
 	violation_check = ((func == FILE_CHECK || func == MMAP_CHECK ||
 			    func == MMAP_CHECK_REQPROT) &&
 			   (ima_policy_flag & IMA_MEASURE));
@@ -287,6 +288,13 @@ static int process_measurement(struct file *file, const struct cred *cred,
 		iint->measured_pcrs = 0;
 	}
 
+	/* Digest cache changed, reset integrity status. */
+	if (policy_usage &&
+	    ima_digest_cache_get_check(file_dentry(file), iint)) {
+		iint->flags &= ~IMA_DONE_MASK;
+		iint->measured_pcrs = 0;
+	}
+
 	/*
 	 * On stacked filesystems, detect and re-evaluate file data and
 	 * metadata changes.
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ