CVE: CVE-2023-52506
Published: 2024-03-02
Description: In the Linux kernel, the following vulnerability has been resolved:

LoongArch: Set all reserved memblocks on Node#0 at initialization

After commit 61167ad5fecdea ("mm: pass nid to reserve_bootmem_region()")
we get a panic if DEFERRED_STRUCT_PAGE_INIT is enabled:

[    0.000000] CPU 0 Unable to handle kernel paging request at virtual address[PII_REDACTED]002b82, era ==[PII_REDACTED]0e3f28, ra ==[PII_REDACTED]0e3f18
[    0.000000] Oops[#1]:
[    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 6.5.0+ #733
[    0.000000] pc[PII_REDACTED]0e3f28 ra[PII_REDACTED]0e3f18 tp[PII_REDACTED]6f4000 sp[PII_REDACTED]6f7c90
[    0.000000] a0 [PII_REDACTED] a1 [PII_REDACTED] a2 [PII_REDACTED] a3[PII_REDACTED]6f7ca0
[    0.000000] a4[PII_REDACTED]6f7ca4 a5 [PII_REDACTED] a6[PII_REDACTED]6f7c38 a7 [PII_REDACTED]
[    0.000000] t0 [PII_REDACTED] t[PII_REDACTED]b00ac8 t2[PII_REDACTED]0e3f18 t3[PII_REDACTED]0f0800
[    0.000000] t4[PII_REDACTED]0f0000 t5 80000000ffffe07e t6 [PII_REDACTED] t7 900000047fff5e20
[    0.000000] t8 aaaaaaaaaaaaaaab u0 [PII_REDACTED] s9 [PII_REDACTED] s0 fffffefffe000000
[    0.000000] s1 [PII_REDACTED] s2 [PII_REDACTED] s3 [PII_REDACTED] s4 [PII_REDACTED]
[    0.000000] s5 [PII_REDACTED] s6 fffffefffe000000 s7[PII_REDACTED]70b740 s8[PII_REDACTED]ad4000
[    0.000000]    ra:[PII_REDACTED]0e3f18 reserve_bootmem_region+0xec/0x21c
[    0.000000]   ERA:[PII_REDACTED]0e3f28 reserve_bootmem_region+0xfc/0x21c
[    0.000000]  CRMD: 000000b0 (PLV0 -IE -DA +PG DACF=CC DACM=CC -WE)
[    0.000000]  PRMD: 00000000 (PPLV0 -PIE -PWE)
[    0.000000]  EUEN: 00000000 (-FPE -SXE -ASXE -BTE)
[    0.000000]  ECFG: 00070800 (LIE=11 VS=7)
[    0.000000] ESTAT: 00010800 [PIL] (IS=11 ECode=1 EsubCode=0)
[    0.000000]  BADV:[PII_REDACTED]002b82
[    0.000000]  PRID: 0014d000 (Loongson-64bit, Loongson-3A6000)
[    0.000000] Modules linked in:
[    0.000000] Process swapper (pid: 0, threadinfo=(____ptrval____), task=(____ptrval____))
[    0.000000] Stack : [PII_REDACTED][PII_REDACTED]eb5[PII_REDACTED]a00[PII_REDACTED]0000045ccd00
[    0.000000]        [PII_REDACTED]70e[PII_REDACTED]0002c1918 [PII_REDACTED] [PII_REDACTED]
[    0.000000]         00000000fe6c0000 [PII_REDACTED][PII_REDACTED]b4e368 [PII_REDACTED]
[    0.000000]         [PII_REDACTED][PII_REDACTED]21ca84 [PII_REDACTED] [PII_REDACTED]
[    0.000000]        [PII_REDACTED]6f7d78[PII_REDACTED]cc9f70[PII_REDACTED]2c[PII_REDACTED]00470e000
[    0.000000]         [PII_REDACTED][PII_REDACTED]0bc0e0[PII_REDACTED]6f7d78 [PII_REDACTED]
[    0.000000]         [PII_REDACTED][PII_REDACTED]5ccd00 [PII_REDACTED][PII_REDACTED]2c1918
[    0.000000]        [PII_REDACTED]2c[PII_REDACTED]00470b[PII_REDACTED]004b4df78 [PII_REDACTED]
[    0.000000]        [PII_REDACTED]6200a8[PII_REDACTED]6200a8 [PII_REDACTED][PII_REDACTED]218b2c
[    0.000000]         [PII_REDACTED] [PII_REDACTED] [PII_REDACTED][PII_REDACTED]5ccd00
[    0.000000]         ...
[    0.000000] Call Trace:
[    0.000000] [<[PII_REDACTED]0e3f28>] reserve_bootmem_region+0xfc/0x21c
[    0.000000] [<[PII_REDACTED]21ca84>] memblock_free_all+0x114/0x350
[    0.000000] [<[PII_REDACTED]218b2c>] mm_core_init+0x138/0x3cc
[    0.000000] [<[PII_REDACTED]200e38>] start_kernel+0x488/0x7a4
[    0.000000] [<[PII_REDACTED]0df0d8>] kernel_entry+0xd8/0xdc
[    0.000000]
[    0.000000] Code: 02eb21ad  00410f4c  380c31ac <262b818d> 6800b70d  02c1c196  0015001c  57fe4bb1  260002cd

The reason is early memblock_reserve() in memblock_init() set node id to
MAX_NUMNODES, making NODE_DATA(nid) a NULL dereference in the call chain
reserve_bootmem_region() -> init_reserved_page(). After memblock_init(),
those late calls of memblock_reserve() operate on subregions of memblock
.memory regions. As a result, these reserved regions will be set to the
correct node at the first iteration of memmap_init_reserved_pages().

So set all reserved memblocks on Node#0 at initialization can avoid this
panic.
CVSS Score: 5.5 (MEDIUM)
CWE: CWE-476
References: https://git.kernel.org/stable/c/19878758accf6b2788091a771d9f9fee7bab11ab; https://git.kernel.org/stable/c/b795fb9f5861ee256070d59e33130980a01fadd7; https://git.kernel.org/stable/c/f105e893a8edd48bdf4bef9fef845a9ff402f737