[PATCH v5 12/13] ima: Return error on deleting measurements already copied during kexec
Roberto Sassu
roberto.sassu at huaweicloud.com
Wed Apr 29 16:03:18 UTC 2026
From: Roberto Sassu <roberto.sassu at huawei.com>
Refuse to delete staged or active list measurements, if a kexec racing with
the deletion already copied those measurements in the kexec buffer. In this
way, user space becomes aware that those measurements are going to appear
in the secondary kernel, and thus they don't have to be saved twice.
Link: https://github.com/linux-integrity/linux/issues/1
Signed-off-by: Roberto Sassu <roberto.sassu at huawei.com>
---
security/integrity/ima/ima.h | 5 +++++
security/integrity/ima/ima_kexec.c | 6 ++++++
security/integrity/ima/ima_queue.c | 17 +++++++++++++++++
3 files changed, 28 insertions(+)
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 9a741b33d524..9be4c35d7ec1 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -344,6 +344,11 @@ extern struct hlist_head __rcu *ima_htable;
extern struct mutex ima_extend_list_mutex;
extern bool ima_flush_htable;
+#define IMA_MEASUREMENTS_STAGED_COPIED 1
+#define IMA_MEASUREMENTS_COPIED 2
+
+extern u8 ima_copied_flags;
+
static inline unsigned int ima_hash_key(u8 *digest)
{
/* there is no point in taking a hash of part of a digest */
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index e7bde3d917b2..5c7abde114f2 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -119,6 +119,9 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
break;
}
+ if (!list_empty(&ima_measurements_staged))
+ ima_copied_flags |= IMA_MEASUREMENTS_STAGED_COPIED;
+
list_for_each_entry_rcu(qe, &ima_measurements, later,
lockdep_is_held(&ima_extend_list_mutex)) {
if (!ret)
@@ -127,6 +130,9 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
break;
}
+ if (!list_empty(&ima_measurements))
+ ima_copied_flags |= IMA_MEASUREMENTS_COPIED;
+
mutex_unlock(&ima_extend_list_mutex);
/*
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index 64c4fe73dd5f..7f09cce53772 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -72,6 +72,13 @@ DEFINE_MUTEX(ima_extend_list_mutex);
*/
static bool ima_measurements_suspended;
+/*
+ * Used to determine if staged or active list measurements were copied during
+ * kexec, so that an error can be sent to user space during deletion, and they
+ * don't store those measurements twice.
+ */
+u8 ima_copied_flags;
+
/* Callers must call synchronize_rcu() and free the hash table. */
static struct hlist_head *ima_alloc_replace_htable(void)
{
@@ -344,6 +351,11 @@ int ima_queue_staged_delete_all(void)
return -ENOENT;
}
+ if (ima_copied_flags & IMA_MEASUREMENTS_STAGED_COPIED) {
+ mutex_unlock(&ima_extend_list_mutex);
+ return -ESTALE;
+ }
+
list_replace(&ima_measurements_staged, &ima_measurements_trim);
INIT_LIST_HEAD(&ima_measurements_staged);
@@ -397,6 +409,11 @@ int ima_queue_delete_partial(unsigned long req_value)
return -ENOENT;
mutex_lock(&ima_extend_list_mutex);
+ if (ima_copied_flags & IMA_MEASUREMENTS_COPIED) {
+ mutex_unlock(&ima_extend_list_mutex);
+ return -ESTALE;
+ }
+
/*
* qe remains valid because ima_fs.c enforces single-writer exclusion.
*/
--
2.43.0
More information about the Linux-security-module-archive
mailing list