Re: [PATCH v3] riscv: Fix a NULL pointer dereference in machine_kexec_prepare

Pratyush Yadav <[email protected]>
Newsgroups org.infradead.lists.kexec,org.infradead.lists.linux-riscv,org.kernel.vger.kernel-janitors,org.kernel.vger.linux-integrity,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Wed, Jul 01 2026, Tao Liu wrote:

> Hi Jarkko,
>
> On Wed, Jul 1, 2026 at 3:50 PM Jarkko Sakkinen <[email protected]> wrote:
>>
>> On Wed, Jul 01, 2026 at 02:57:33PM +1200, Tao Liu wrote:
>> > A NULL pointer dereference issue is noticed in riscv's machine_kexec_prepare,
>> > where image->segment[i].buf might be NULL and copied unchecked.
>> >
>> > The NULL buf comes from security/integrity/ima/ima_kexec.c:
>> > ima_add_kexec_buffer(), where kbuf is added by kexec_add_buffer(),
>> > but kbuf.buffer is NULL
>>
>> This should have a proper call sequence. Now the root cause is
>> obfuscated.
>
> Sure, I will attach the stack trace in v4. Here is the one:
>
> [   62.867540] kexec_file(Image): Loaded kernel at 0x80200000
> bufsz=0x34ed800 memsz=0x35d0000
> [   62.879983] Unable to handle kernel access to user memory without
> uaccess routines at virtual address 0000000000000000
> [   62.880736] Current kexec pgtable: 4K pagesize, 57-bit VAs,
> pgdp=0x00000001062eb000
> [   62.881185] [0000000000000000] pgd=00000000413b4401,
> p4d=000000004151bc01, pud=00000000415b7801, pmd=0000000040af5801,
> pte=0000000000000000
> [   62.881969] Oops [#1]
> [   62.882077] Modules linked in:
> [   62.882717] CPU: 1 UID: 0 PID: 894 Comm: kexec Not tainted 7.1.1 #4
> PREEMPT(lazy)
> [   62.883037] Hardware name: QEMU QEMU Virtual Machine, BIOS
> edk2-20260508-2.fc44 05/08/2026
> [   62.883365] epc : __memcpy+0xd4/0xf8
> [   62.883685]  ra : machine_kexec_prepare+0x8a/0x298
> [   62.883914] epc : ffffffff81393ee8 ra : ffffffff800366ca sp :
> ff20000004a83d10
> [   62.884214]  gp : ffffffff83258db8 tp : ff6000008573db80 t0 :
> ffffffff80033640
> [   62.884433]  t1 : 2152ffffffffffc0 t2 : 0000000003000000 s0 :
> ff20000004a83d80
> [   62.884710]  s1 : 0000000000000000 a0 : ff20000004a83d10 a1 :
> 0000000000000000
> [   62.884987]  a2 : 0000000000000028 a3 : 0000000000000028 a4 :
> 0000000000000000
> [   62.885208]  a5 : 0000000000000000 a6 : 0000000104e33fff a7 :
> 0000000000000000
> [   62.885486]  s2 : ff60000082a35800 s3 : 0000000000000000 s4 :
> 0000000000000010
> [   62.885774]  s5 : 0000000000000028 s6 : ff20000004a83d10 s7 :
> 0000000000000005
> [   62.886005]  s8 : 00000000000000c0 s9 : 000000000ac0d220 s10:
> ffffffff835420e8
> [   62.886218]  s11: 0000000000000000 t3 : ffffff800000007c t4 :
> ff1c000002138d00
> [   62.886515]  t5 : ffffffffffffffff t6 : ff20000004a83d10 ssp :
> 0000000000000000
> [   62.886860] status: 0000000200000120 badaddr: 0000000000000000
> cause: 000000000000000d
> [   62.887162] [<ffffffff81393ee8>] __memcpy+0xd4/0xf8
> [   62.887388] [<ffffffff801b253a>] __do_sys_kexec_file_load+0x1b2/0x338
> [   62.887612] [<ffffffff801b26e4>] __riscv_sys_kexec_file_load+0x24/0x40
> [   62.887855] [<ffffffff81395ea4>] do_trap_ecall_u+0x1a4/0x5a8
> [   62.888134] [<ffffffff813a9eec>] handle_exception+0x16c/0x178
> [   62.888445] Code: 7613 07f6 ca05 86b3 00c5 e7b3 01f5 8fd5 8b8d eb89
> (4198) 0591
> [   62.889223] ---[ end trace 0000000000000000 ]---
> Segmentation fault         kexec -l /boot/vmlinuz-7.1.1
> --initrd=/boot/initramfs-7.1.1.img --reuse-cmdline
>
> (gdb) p image->segment[0]
> $3 = {{buf = 0x0, kbuf = 0x0}, bufsz = 0, mem = 10737586176, memsz = 4096}
>
> The buf = 0x0 and bufsz = 0 comes from ima_add_kexec_buffer(), thought
> I'm not sure why it added a NULL segment, but it is no harm to add a
> NULL checker here in case any other scenarios similar as IMA.

From my reading of the IMA code, I think they do so because they don't
want to add a buffer to the kimage just yet. This is because there can
be IMA measurements between kexec load and kexec reboot. So they use
kexec_add_buffer() to reserve the physical address space, then they vmap
the destination pages in ima_kexec_post_load(), and then update the
destination pages directly via a reboot notifier. So they do not have a
buffer copied to the destination pages at the time of
kexec_add_buffer().

Now all that is fairly convoluted and not very obvious, but I am not
sure if there is a better way of doing this off the top of my head.

>
>>
>> >
>> > Fix this by simply adding a check before copy.
>> >
>> > Fixes: b7fb4d78a6ad ("RISC-V: use memcpy for kexec_file mode")
>> > Acked-by: Baoquan He <[email protected]>
>> > Acked-by: Pratyush Yadav <[email protected]>
>> > Signed-off-by: Tao Liu <[email protected]>
[...]

-- 
Regards,
Pratyush Yadav
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.