ima: reject a kexec buffer whose declared size exceeds the buffer

ima_restore_measurement_list() parses the measurement list persisted across
kexec.  It computes the parse end directly from the blob:

	bufendp = buf + khdr->buffer_size;

khdr->buffer_size is a u64 read straight from the persisted buffer.  The
only length checks in the function are size >= sizeof(*khdr), version == 1
and count -- none relates buffer_size to size, the actual buffer size the
caller (ima_load_kexec_buffer()) obtained from the ima-kexec-buffer region.
ima_parse_buf() bounds every field read to bufendp, so a blob whose
internal buffer_size exceeds the real size makes the parse loop read past
the end of the buffer (CWE-125).

The buffer's memory range is validated against addressable RAM by
commit cbf9c4b961 ("of: check previous kernel's ima-kexec-buffer
against memory bounds") and commit c5489d0433 ("x86/kexec: add a
sanity check on previous kernel's ima kexec buffer"), but the blob's
own declared size is never clamped to it.  Reject a buffer_size larger
than size before the loop.

This is on the boot-time kexec-restore path (__init) and the buffer comes
from the previous kernel, so triggering it requires control of the
persisted buffer; it is an out-of-bounds read only.

Fixes: 94c3aac567 ("ima: on soft reboot, restore the measurement list")
Assisted-by: copilot-cli:claude-opus-4-6 frama-c
Signed-off-by: Fabrice Derepas <fabrice.derepas@canonical.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
This commit is contained in:
Fabrice Derepas 2026-08-12 16:18:40 +02:00 committed by Mimi Zohar
parent e8386a3360
commit ceb24c7052

View File

@ -450,6 +450,11 @@ int ima_restore_measurement_list(loff_t size, void *buf)
return -EINVAL;
}
if (khdr->buffer_size > size) {
pr_err("attempting to restore a corrupted measurement list");
return -EINVAL;
}
bitmap_zero(hdr_mask, HDR__LAST);
bitmap_set(hdr_mask, HDR_PCR, 1);
bitmap_set(hdr_mask, HDR_DIGEST, 1);