riscv: mm: Proper page permissions after initmem free
authorBjörn Töpel <bjorn@rivosinc.com>
Tue, 15 Nov 2022 09:06:40 +0000 (10:06 +0100)
committerPalmer Dabbelt <palmer@rivosinc.com>
Wed, 30 Nov 2022 02:54:30 +0000 (18:54 -0800)
commit6fdd5d2f8c2f54b7fad4ff4df2a19542aeaf6102
tree4528ce538bb426e6bfc1db9ca5cdcedaf31f9140
parent74f6bb55c834da6d4bac24f44868202743189b2b
riscv: mm: Proper page permissions after initmem free

64-bit RISC-V kernels have the kernel image mapped separately to alias
the linear map. The linear map and the kernel image map are documented
as "direct mapping" and "kernel" respectively in [1].

At image load time, the linear map corresponding to the kernel image
is set to PAGE_READ permission, and the kernel image map is set to
PAGE_READ|PAGE_EXEC.

When the initmem is freed, the pages in the linear map should be
restored to PAGE_READ|PAGE_WRITE, whereas the corresponding pages in
the kernel image map should be restored to PAGE_READ, by removing the
PAGE_EXEC permission.

This is not the case. For 64-bit kernels, only the linear map is
restored to its proper page permissions at initmem free, and not the
kernel image map.

In practise this results in that the kernel can potentially jump to
dead __init code, and start executing invalid instructions, without
getting an exception.

Restore the freed initmem properly, by setting both the kernel image
map to the correct permissions.

[1] Documentation/riscv/vm-layout.rst

Fixes: e5c35fa04019 ("riscv: Map the kernel with correct permissions the first time")
Signed-off-by: Björn Töpel <bjorn@rivosinc.com>
Reviewed-by: Alexandre Ghiti <alex@ghiti.fr>
Tested-by: Alexandre Ghiti <alex@ghiti.fr>
Link: https://lore.kernel.org/r/20221115090641.258476-1-bjorn@kernel.org
Cc: stable@vger.kernel.org
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/kernel/setup.c