* [PATCH] ima: fix kexec measurement buffer overflow after failed loads
@ 2026-11-08 19:04 Jérémy Jean
2026-11-10 20:07 ` Mike Rapoport
0 siblings, 1 reply; 2+ messages in thread
From: Jérémy Jean @ 2026-11-08 19:04 UTC (permalink / raw)
To: Andrew Morton, Baoquan He, Mike Rapoport, Pasha Tatashin,
Pratyush Yadav, Mimi Zohar, Roberto Sassu, Dmitry Kasatkin
Cc: Eric Snowberg, linux-integrity, linux-security-module,
linux-kernel, kexec, Jérémy Jean, stable
When kexec_file_load() fails to install a new image, it can leave the
global IMA scratch buffer larger than the IMA segment of the current
image. When that image is executed, ima_update_kexec_buffer() copies
the larger log past the end of its reserved segment. In a test, KASAN
reports it as:
BUG: KASAN: vmalloc-out-of-bounds in ima_update_kexec_buffer+0x265/0x280
Write of size 868426 at addr ffffc9000004e000 by task init/1
...
Call Trace:
...
__asan_memcpy+0x3b/0x60
ima_update_kexec_buffer+0x265/0x280
...
blocking_notifier_call_chain+0x88/0xb0
kernel_restart_prepare+0x18/0x40
kernel_kexec+0xe4/0x130
Limit the dump to the smaller value between the scratch size and the
installed image segment size. Update the IMA mapping only after
machine_kexec_post_load() succeeds.
Fixes: 9f0ec4b16f2b ("ima: kexec: move IMA log copy from kexec load to execute")
Cc: stable@vger.kernel.org
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
---
kernel/kexec_file.c | 6 ++++--
security/integrity/ima/ima_kexec.c | 8 +++++---
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index b668ce8d68eed..0b3245389b758 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -206,11 +206,13 @@ kimage_validate_signature(struct kimage *image)
static int kexec_post_load(struct kimage *image, unsigned long flags)
{
+ int ret = machine_kexec_post_load(image);
+
#ifdef CONFIG_IMA_KEXEC
- if (!(flags & KEXEC_FILE_ON_CRASH))
+ if (!ret && !(flags & KEXEC_FILE_ON_CRASH))
ima_kexec_post_load(image);
#endif
- return machine_kexec_post_load(image);
+ return ret;
}
/*
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index 0d845693a1f78..f7be8d85bb9a7 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -65,7 +65,6 @@ static int ima_alloc_kexec_file_buf(size_t segment_size)
ima_free_kexec_file_buf(&ima_kexec_file);
- /* segment size can't change between kexec load and execute */
ima_kexec_file.buf = vmalloc(segment_size);
if (!ima_kexec_file.buf)
return -ENOMEM;
@@ -98,12 +97,14 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
struct ima_kexec_hdr khdr;
int ret = 0;
- /* segment size can't change between kexec load and execute */
if (!ima_kexec_file.buf) {
pr_err("Kexec file buf not allocated\n");
return -EINVAL;
}
+ /* A failed replacement load may have resized the scratch buffer. */
+ ima_kexec_file.size = min_t(size_t, ima_kexec_file.size, segment_size);
+
memset(&khdr, 0, sizeof(khdr));
khdr.version = 1;
/*
@@ -239,7 +240,8 @@ static int ima_update_kexec_buffer(struct notifier_block *self,
return ret;
}
- ret = ima_dump_measurement_list(&buf_size, &buf, kexec_segment_size);
+ ret = ima_dump_measurement_list(&buf_size, &buf,
+ kexec_image->ima_buffer_size);
if (ret)
pr_err("Dump measurements failed. Error:%d\n", ret);
--
2.47.3
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH] ima: fix kexec measurement buffer overflow after failed loads
2026-11-08 19:04 [PATCH] ima: fix kexec measurement buffer overflow after failed loads Jérémy Jean
@ 2026-11-10 20:07 ` Mike Rapoport
0 siblings, 0 replies; 2+ messages in thread
From: Mike Rapoport @ 2026-11-10 20:07 UTC (permalink / raw)
To: Jérémy Jean
Cc: Andrew Morton, Baoquan He, Pasha Tatashin, Pratyush Yadav,
Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
linux-integrity, linux-security-module, linux-kernel, kexec,
stable
On Sun, Nov 08, 2026 at 07:04:04PM +0000, Jérémy Jean wrote:
> When kexec_file_load() fails to install a new image, it can leave the
> global IMA scratch buffer larger than the IMA segment of the current
> image. When that image is executed, ima_update_kexec_buffer() copies
> the larger log past the end of its reserved segment. In a test, KASAN
> reports it as:
...
> Limit the dump to the smaller value between the scratch size and the
> installed image segment size. Update the IMA mapping only after
> machine_kexec_post_load() succeeds.
These are two different bugs and the changelog only explains the first.
The second one is that if machine_kexec_post_load() fails (e.g. -ENOMEM
in trans_pgd on arm64), ima_kexec_buffer is already switched to the
segment of the image that is about to be freed, so the installed image
loses the IMA update and kexec -e writes into freed pages.
Please spell this out, or better split it into a separate patch.
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -206,11 +206,13 @@ kimage_validate_signature(struct kimage *image)
>
> static int kexec_post_load(struct kimage *image, unsigned long flags)
> {
> + int ret = machine_kexec_post_load(image);
> +
> #ifdef CONFIG_IMA_KEXEC
> - if (!(flags & KEXEC_FILE_ON_CRASH))
> + if (!ret && !(flags & KEXEC_FILE_ON_CRASH))
> ima_kexec_post_load(image);
> #endif
> - return machine_kexec_post_load(image);
> + return ret;
Nit: an early "if (ret) return ret;" reads better than folding the error
into the IMA condition.
> diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
> --- a/security/integrity/ima/ima_kexec.c
> +++ b/security/integrity/ima/ima_kexec.c
> @@ -98,12 +97,14 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
> + /* A failed replacement load may have resized the scratch buffer. */
> + ima_kexec_file.size = min_t(size_t, ima_kexec_file.size, segment_size);
This prevents the overflow, but it treats the symptom at execute time.
The actual problem is that ima_add_kexec_buffer() updates global state
(ima_kexec_file and kexec_segment_size) for an image that may never be
installed.
When the failed load had a smaller measurement list (with staging the
list can shrink), the dump is still truncated to the failed image's
size and the next kernel gets an incomplete log. kexec_segment_size
reported in the "kexec_execute" event is also the failed image's one.
With the first hunk ima_kexec_post_load() runs only for an image that
is going to be installed, so wouldn't it be cleaner to (re)size the
scratch buffer and kexec_segment_size there, from image->ima_buffer_size?
Then the comment you removed would actually become true.
> @@ -239,7 +240,8 @@ static int ima_update_kexec_buffer(struct notifier_block *self,
> - ret = ima_dump_measurement_list(&buf_size, &buf, kexec_segment_size);
> + ret = ima_dump_measurement_list(&buf_size, &buf,
> + kexec_image->ima_buffer_size);
ima_kexec_buffer is not tied to kexec_image. After a successful
kexec_file_load() followed by KEXEC_FILE_UNLOAD or by a successful
kexec_load(), the old image is freed but ima_kexec_buffer still maps its
pages. kexec_image->ima_buffer_size is 0 for a kexec_load() image, so
with this patch the dump fails, but buf_size is still the header size
and memcpy() writes it into freed pages.
That's pre-existing and not a reason to hold this patch, but it's the
same class of bug and I think IMA should check that ima_kexec_buffer
belongs to kexec_image (or drop the mapping when the image is replaced)
rather than rely on sizes matching.
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-10 20:07 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-08 19:04 [PATCH] ima: fix kexec measurement buffer overflow after failed loads Jérémy Jean
2026-11-10 20:07 ` Mike Rapoport
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®