Gregory Price wrote:
walk_system_ram_res_rev() erroneously discards resource flags when passing the information to the callback.
This causes systems with IORESOURCE_SYSRAM_DRIVER_MANAGED memory to have these resources selected during kexec to store kexec buffers if that memory happens to be at placed above normal system ram.
This leads to undefined behavior after reboot. If the kexec buffer is never touched, nothing happens. If the kexec buffer is touched, it could lead to a crash (like below) or undefined behavior.
Tested on a system with CXL memory expanders with driver managed memory, TPM enabled, and CONFIG_IMA_KEXEC=y. Adding printk's showed the flags were being discarded and as a result the check for IORESOURCE_SYSRAM_DRIVER_MANAGED passes.
find_next_iomem_res: name(System RAM (kmem)) start(10000000000) end(1034fffffff) flags(83000200)
locate_mem_hole_top_down: start(10000000000) end(1034fffffff) flags(0)
[..]
Link: https://lore.kernel.org/all/20231114091658.228030-1-bhe@redhat.com/ Fixes: 7acf164b259d ("resource: add walk_system_ram_res_rev()") Cc: stable@vger.kernel.org Signed-off-by: Gregory Price gourry@gourry.net
kernel/resource.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/kernel/resource.c b/kernel/resource.c index b730bd28b422..4101016e8b20 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -459,9 +459,7 @@ int walk_system_ram_res_rev(u64 start, u64 end, void *arg, rams_size += 16; }
rams[i].start = res.start;
rams[i++].end = res.end;
start = res.end + 1;rams[i++] = res;
Looks good to me, makes it obvious that everything that find_next_iomem_res() would return for walk_system_ram_range() users is the same as what walk_system_ram_res_rev() returns.
Reviewed-by: Dan Williams dan.j.williams@intel.com