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 for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20240415161044.2572438-10-roberto.sassu@huaweicloud.com>
Date: Mon, 15 Apr 2024 18:10:44 +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 v2 9/9] ima: Register to the digest_cache LSM notifier and process events

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

A digest cache used for measurement/appraisal might change over the time
(due to file modification, directory changes). When that happens, IMA
should invalidate the cached integrity result for affected inodes and
evaluate those inodes again.

Implement ima_digest_cache_change(), to be invoked at every notification by
the digest_cache LSM, and register it as a callback with
digest_cache_register_notifier().

For every notification, and if the type of event is DIGEST_CACHE_RESET,
retrieve the inode integrity metadata (if any), and set the
IMA_CHANGE_XATTR atomic flag, so that IMA fully reevaluates the inode in
process_measurement().

Signed-off-by: Roberto Sassu <roberto.sassu@...wei.com>
---
 security/integrity/ima/ima_digest_cache.c | 31 +++++++++++++++++++++++
 security/integrity/ima/ima_digest_cache.h |  6 +++++
 security/integrity/ima/ima_main.c         | 11 +++++++-
 3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/security/integrity/ima/ima_digest_cache.c b/security/integrity/ima/ima_digest_cache.c
index 013c69f265d8..0ab35575ff7c 100644
--- a/security/integrity/ima/ima_digest_cache.c
+++ b/security/integrity/ima/ima_digest_cache.c
@@ -90,3 +90,34 @@ void ima_digest_cache_update_allowed_usage(struct file *file,
 out:
 	digest_cache_put(digest_cache);
 }
+
+static int ima_digest_cache_change(struct notifier_block *nb,
+				   unsigned long event, void *data)
+{
+	struct ima_iint_cache *iint;
+	struct digest_cache_event_data *event_data = data;
+
+	if (event != DIGEST_CACHE_RESET)
+		return NOTIFY_DONE;
+
+	iint = ima_iint_find(event_data->inode);
+	if (!iint) {
+		pr_debug("Integrity metadata not found for inode %lu\n",
+			 event_data->inode->i_ino);
+		return NOTIFY_OK;
+	}
+
+	set_bit(IMA_CHANGE_XATTR, &iint->atomic_flags);
+	pr_debug("Integrity metadata of inode %lu successfully reset\n",
+		 event_data->inode->i_ino);
+	return NOTIFY_OK;
+}
+
+static struct notifier_block digest_cache_notifier = {
+	.notifier_call = ima_digest_cache_change,
+};
+
+int ima_digest_cache_register_notifier(void)
+{
+	return digest_cache_register_notifier(&digest_cache_notifier);
+}
diff --git a/security/integrity/ima/ima_digest_cache.h b/security/integrity/ima/ima_digest_cache.h
index cb47c15e975d..44c188c2fb93 100644
--- a/security/integrity/ima/ima_digest_cache.h
+++ b/security/integrity/ima/ima_digest_cache.h
@@ -15,6 +15,7 @@ void ima_digest_cache_store_allowed_usage(struct file *file,
 void ima_digest_cache_update_allowed_usage(struct file *file,
 					   struct ima_iint_cache *iint,
 					   u64 *allowed_usage);
+int ima_digest_cache_register_notifier(void);
 #else
 static inline void
 ima_digest_cache_store_allowed_usage(struct file *file,
@@ -27,4 +28,9 @@ ima_digest_cache_update_allowed_usage(struct file *file,
 				      u64 *allowed_usage)
 { }
 
+static inline int ima_digest_cache_register_notifier(void)
+{
+	return 0;
+}
+
 #endif /* CONFIG_SECURITY_DIGEST_CACHE */
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 7ae2bd888d41..fe826755acd1 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -1159,8 +1159,17 @@ static int __init init_ima(void)
 		return error;
 
 	error = register_blocking_lsm_notifier(&ima_lsm_policy_notifier);
-	if (error)
+	if (error) {
 		pr_warn("Couldn't register LSM notifier, error %d\n", error);
+		return error;
+	}
+
+	error = ima_digest_cache_register_notifier();
+	if (error) {
+		pr_warn("Couldn't register digest cache notifier, error %d\n",
+			error);
+		unregister_blocking_lsm_notifier(&ima_lsm_policy_notifier);
+	}
 
 	if (!error)
 		ima_update_policy_flags();
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ