* [PATCH 6.12.y 1/2] ima: kexec: skip IMA segment validation after kexec soft reboot
2026-06-09 21:58 [PATCH 6.12.y 0/2] ima: kexec: fix kexec_file_load panic with IMA_KEXEC Sherry Yang
@ 2026-06-09 21:58 ` Sherry Yang
2026-06-09 21:58 ` [PATCH 6.12.y 2/2] ima: kexec: move IMA log copy from kexec load to execute Sherry Yang
2026-06-11 0:45 ` [PATCH 6.12.y 0/2] ima: kexec: fix kexec_file_load panic with IMA_KEXEC Sasha Levin
2 siblings, 0 replies; 4+ messages in thread
From: Sherry Yang @ 2026-06-09 21:58 UTC (permalink / raw)
To: stable
Cc: sashal, chenste, sherry.yang, ebiederm, tusharsu, zohar,
roberto.sassu, dmitry.kasatkin, eric.snowberg
From: Steven Chen <chenste@linux.microsoft.com>
[ Upstream commit 9ee8888a80fe2bd20ce929ffbc1dedd57607a778 ]
Currently, the function kexec_calculate_store_digests() calculates and
stores the digest of the segment during the kexec_file_load syscall,
where the IMA segment is also allocated.
Later, the IMA segment will be updated with the measurement log at the
kexec execute stage when a kexec reboot is initiated. Therefore, the
digests should be updated for the IMA segment in the normal case. The
problem is that the content of memory segments carried over to the new
kernel during the kexec systemcall can be changed at kexec 'execute'
stage, but the size and the location of the memory segments cannot be
changed at kexec 'execute' stage.
To address this, skip the calculation and storage of the digest for the
IMA segment in kexec_calculate_store_digests() so that it is not added
to the purgatory_sha_regions.
With this change, the IMA segment is not included in the digest
calculation, storage, and verification.
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: Dave Young <dyoung@redhat.com>
Co-developed-by: Tushar Sugandhi <tusharsu@linux.microsoft.com>
Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com>
Signed-off-by: Steven Chen <chenste@linux.microsoft.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Acked-by: Baoquan He <bhe@redhat.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com> # ppc64/kvm
[zohar@linux.ibm.com: Fixed Signed-off-by tag to match author's email ]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
(cherry picked from commit 9ee8888a80fe2bd20ce929ffbc1dedd57607a778)
Signed-off-by: Sherry Yang <sherry.yang@oracle.com>
---
include/linux/kexec.h | 3 +++
kernel/kexec_file.c | 22 ++++++++++++++++++++++
security/integrity/ima/ima_kexec.c | 3 +++
3 files changed, 28 insertions(+)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 7d6b12f8b8d05..107e726f2ef3f 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -362,6 +362,9 @@ struct kimage {
phys_addr_t ima_buffer_addr;
size_t ima_buffer_size;
+
+ unsigned long ima_segment_index;
+ bool is_ima_segment_index_set;
#endif
/* Core ELF header buffer */
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index f852528bdc246..a20ceb4d27ccc 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -38,6 +38,21 @@ void set_kexec_sig_enforced(void)
}
#endif
+#ifdef CONFIG_IMA_KEXEC
+static bool check_ima_segment_index(struct kimage *image, int i)
+{
+ if (image->is_ima_segment_index_set && i == image->ima_segment_index)
+ return true;
+ else
+ return false;
+}
+#else
+static bool check_ima_segment_index(struct kimage *image, int i)
+{
+ return false;
+}
+#endif
+
static int kexec_calculate_store_digests(struct kimage *image);
/* Maximum size in bytes for kernel/initrd files. */
@@ -764,6 +779,13 @@ static int kexec_calculate_store_digests(struct kimage *image)
if (ksegment->kbuf == pi->purgatory_buf)
continue;
+ /*
+ * Skip the segment if ima_segment_index is set and matches
+ * the current index
+ */
+ if (check_ima_segment_index(image, i))
+ continue;
+
ret = crypto_shash_update(desc, ksegment->kbuf,
ksegment->bufsz);
if (ret)
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index 501b952b36981..4de9834c3e133 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -164,6 +164,7 @@ void ima_add_kexec_buffer(struct kimage *image)
kbuf.buffer = kexec_buffer;
kbuf.bufsz = kexec_buffer_size;
kbuf.memsz = kexec_segment_size;
+ image->is_ima_segment_index_set = false;
ret = kexec_add_buffer(&kbuf);
if (ret) {
pr_err("Error passing over kexec measurement buffer.\n");
@@ -174,6 +175,8 @@ void ima_add_kexec_buffer(struct kimage *image)
image->ima_buffer_addr = kbuf.mem;
image->ima_buffer_size = kexec_segment_size;
image->ima_buffer = kexec_buffer;
+ image->ima_segment_index = image->nr_segments - 1;
+ image->is_ima_segment_index_set = true;
kexec_dprintk("kexec measurement buffer for the loaded kernel at 0x%lx.\n",
kbuf.mem);
--
2.50.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 6.12.y 2/2] ima: kexec: move IMA log copy from kexec load to execute
2026-06-09 21:58 [PATCH 6.12.y 0/2] ima: kexec: fix kexec_file_load panic with IMA_KEXEC Sherry Yang
2026-06-09 21:58 ` [PATCH 6.12.y 1/2] ima: kexec: skip IMA segment validation after kexec soft reboot Sherry Yang
@ 2026-06-09 21:58 ` Sherry Yang
2026-06-11 0:45 ` [PATCH 6.12.y 0/2] ima: kexec: fix kexec_file_load panic with IMA_KEXEC Sasha Levin
2 siblings, 0 replies; 4+ messages in thread
From: Sherry Yang @ 2026-06-09 21:58 UTC (permalink / raw)
To: stable
Cc: sashal, chenste, sherry.yang, ebiederm, tusharsu, zohar,
roberto.sassu, dmitry.kasatkin, eric.snowberg
From: Steven Chen <chenste@linux.microsoft.com>
[ Upstream commit 9f0ec4b16f2b41d663f688a8012e9e52b2657eba ]
The IMA log is currently copied to the new kernel during kexec 'load' using
ima_dump_measurement_list(). However, the IMA measurement list copied at
kexec 'load' may result in loss of IMA measurements records that only
occurred after the kexec 'load'. Move the IMA measurement list log copy
from kexec 'load' to 'execute'
Make the kexec_segment_size variable a local static variable within the
file, so it can be accessed during both kexec 'load' and 'execute'.
Define kexec_post_load() as a wrapper for calling ima_kexec_post_load() and
machine_kexec_post_load(). Replace the existing direct call to
machine_kexec_post_load() with kexec_post_load().
When there is insufficient memory to copy all the measurement logs, copy as
much of the measurement list as possible.
Co-developed-by: Tushar Sugandhi <tusharsu@linux.microsoft.com>
Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: Dave Young <dyoung@redhat.com>
Signed-off-by: Steven Chen <chenste@linux.microsoft.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com> # ppc64/kvm
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
(cherry picked from commit 9f0ec4b16f2b41d663f688a8012e9e52b2657eba)
Signed-off-by: Sherry Yang <sherry.yang@oracle.com>
---
kernel/kexec_file.c | 11 +++++++-
security/integrity/ima/ima_kexec.c | 43 ++++++++++++++++++++----------
2 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index a20ceb4d27ccc..909432e804be1 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -201,6 +201,15 @@ kimage_validate_signature(struct kimage *image)
}
#endif
+static int kexec_post_load(struct kimage *image, unsigned long flags)
+{
+#ifdef CONFIG_IMA_KEXEC
+ if (!(flags & KEXEC_FILE_ON_CRASH))
+ ima_kexec_post_load(image);
+#endif
+ return machine_kexec_post_load(image);
+}
+
/*
* In file mode list of segments is prepared by kernel. Copy relevant
* data from user space, do error checking, prepare segment list
@@ -428,7 +437,7 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
kimage_terminate(image);
- ret = machine_kexec_post_load(image);
+ ret = kexec_post_load(image, flags);
if (ret)
goto out;
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index 4de9834c3e133..48fe9a7e1f456 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -21,6 +21,7 @@
#ifdef CONFIG_IMA_KEXEC
static bool ima_kexec_update_registered;
static struct seq_file ima_kexec_file;
+static size_t kexec_segment_size;
static void *ima_kexec_buffer;
static void ima_free_kexec_file_buf(struct seq_file *sf)
@@ -84,9 +85,6 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
}
}
- if (ret < 0)
- goto out;
-
/*
* fill in reserved space with some buffer details
* (eg. version, buffer size, number of measurements)
@@ -106,7 +104,7 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
*buffer_size = ima_kexec_file.count;
*buffer = ima_kexec_file.buf;
-out:
+
return ret;
}
@@ -124,9 +122,8 @@ void ima_add_kexec_buffer(struct kimage *image)
unsigned long binary_runtime_size;
/* use more understandable variable names than defined in kbuf */
+ size_t kexec_buffer_size = 0;
void *kexec_buffer = NULL;
- size_t kexec_buffer_size;
- size_t kexec_segment_size;
int ret;
if (image->type == KEXEC_TYPE_CRASH)
@@ -154,13 +151,6 @@ void ima_add_kexec_buffer(struct kimage *image)
return;
}
- ima_dump_measurement_list(&kexec_buffer_size, &kexec_buffer,
- kexec_segment_size);
- if (!kexec_buffer) {
- pr_err("Not enough memory for the kexec measurement buffer.\n");
- return;
- }
-
kbuf.buffer = kexec_buffer;
kbuf.bufsz = kexec_buffer_size;
kbuf.memsz = kexec_segment_size;
@@ -188,7 +178,32 @@ void ima_add_kexec_buffer(struct kimage *image)
static int ima_update_kexec_buffer(struct notifier_block *self,
unsigned long action, void *data)
{
- return NOTIFY_OK;
+ size_t buf_size = 0;
+ int ret = NOTIFY_OK;
+ void *buf = NULL;
+
+ if (!kexec_in_progress) {
+ pr_info("No kexec in progress.\n");
+ return ret;
+ }
+
+ if (!ima_kexec_buffer) {
+ pr_err("Kexec buffer not set.\n");
+ return ret;
+ }
+
+ ret = ima_dump_measurement_list(&buf_size, &buf, kexec_segment_size);
+
+ if (ret)
+ pr_err("Dump measurements failed. Error:%d\n", ret);
+
+ if (buf_size != 0)
+ memcpy(ima_kexec_buffer, buf, buf_size);
+
+ kimage_unmap_segment(ima_kexec_buffer);
+ ima_kexec_buffer = NULL;
+
+ return ret;
}
static struct notifier_block update_buffer_nb = {
--
2.50.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH 6.12.y 0/2] ima: kexec: fix kexec_file_load panic with IMA_KEXEC
2026-06-09 21:58 [PATCH 6.12.y 0/2] ima: kexec: fix kexec_file_load panic with IMA_KEXEC Sherry Yang
2026-06-09 21:58 ` [PATCH 6.12.y 1/2] ima: kexec: skip IMA segment validation after kexec soft reboot Sherry Yang
2026-06-09 21:58 ` [PATCH 6.12.y 2/2] ima: kexec: move IMA log copy from kexec load to execute Sherry Yang
@ 2026-06-11 0:45 ` Sasha Levin
2 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-06-11 0:45 UTC (permalink / raw)
To: stable
Cc: Sasha Levin, chenste, sherry.yang, ebiederm, tusharsu, zohar,
roberto.sassu, dmitry.kasatkin, eric.snowberg
On Mon, Jun 09, 2026 at 02:58:42PM -0700, Sherry Yang wrote:
> This series backports two upstream IMA/kexec commits to 6.12.y to fix
> a kexec_file_load panic with IMA_KEXEC:
> [PATCH 1/2] ima: kexec: skip IMA segment validation after kexec soft reboot
> [PATCH 2/2] ima: kexec: move IMA log copy from kexec load to execute
Both queued for 6.12, thanks.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 4+ messages in thread