* [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
2026-11-12 2:07 ` Mimi Zohar
0 siblings, 2 replies; 3+ 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] 3+ 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
2026-11-12 2:07 ` Mimi Zohar
1 sibling, 0 replies; 3+ 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] 3+ 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
@ 2026-11-12 2:07 ` Mimi Zohar
1 sibling, 0 replies; 3+ messages in thread
From: Mimi Zohar @ 2026-11-12 2:07 UTC (permalink / raw)
To: Jérémy Jean, Andrew Morton, Baoquan He, Mike Rapoport,
Pasha Tatashin, Pratyush Yadav, Roberto Sassu, Dmitry Kasatkin
Cc: Eric Snowberg, linux-integrity, linux-security-module,
linux-kernel, kexec, stable
On Sun, 2026-11-08 at 19:04 +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:
>
> 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>
Thank you for the report. I agree with Mike that the machine_kexec_post_load()
reordering should be a separate patch.
For the overflow, rather than clamping at execute time, how about not changing
ima_kexec_file.size for an image that isn't installed?
1. Set ima_kexec_file.size only in ima_kexec_post_load(), from
image->ima_buffer_size, and stop ima_free_kexec_file_buf() from
resetting it.
2. Reuse the buffer if size >= segment_size, instead of only if they
are equal, so the buffer is never smaller than size. The buffer no
longer tracks size, and with staging the list can shrink.
Please don't remove the "segment size can't change between kexec load and
execute" comments. They are still correct.
Mimi
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-12 2:09 UTC | newest]
Thread overview: 3+ 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
2026-11-12 2:07 ` Mimi Zohar
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®