lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250530211422.784415-1-cmirabil@redhat.com>
Date: Fri, 30 May 2025 17:14:21 -0400
From: Charles Mirabile <cmirabil@...hat.com>
To: linux-kernel@...r.kernel.org
Cc: Paul Walmsley <paul.walmsley@...ive.com>,
	Palmer Dabbelt <palmer@...belt.com>,
	Albert Ou <aou@...s.berkeley.edu>,
	Alexandre Ghiti <alex@...ti.fr>,
	Charlie Jenkins <charlie@...osinc.com>,
	linux-riscv@...ts.infradead.org (open list:RISC-V ARCHITECTURE),
	Charles Mirabile <cmirabil@...hat.com>
Subject: [PATCH v1 0/1] fix riscv runtime constant support

I discovered that something broke basic booting on riscv64 for a nommu
kernel with a minimal configuration running on qemu between 6.13 and
current master. The symptom was that the kernel would hang and print
nothing instead of booting normally. I bisected my way to:

commit a44fb5722199 ("riscv: Add runtime constant support")

Analyzing in a debugger, I was able to conclude that the bug was occurring
due to an invalid pointer dereference in `__d_lookup_rcu` trying to access
`dentry_cache`. That variable was at 0x8040f480 but the upper half of the
actual pointer value it was trying to access was filled with garbage.

Looking at the disassembly I saw that in the patched instructions that a
`nop` instruction had replaced both the `lui` and the `addiw` that were
supposed to create the upper half of the pointer so the register was not
initialized. The code responsible for patching does not ensure that at
least one instruction is not replaced with a `nop` if `val` is zero.

To reproduce the bug the following minimal config and initrd can be used:

$ cat ../minimal.config
CONFIG_EXPERT=y
CONFIG_NONPORTABLE=y
CONFIG_KERNEL_UNCOMPRESSED=y
CONFIG_RISCV_M_MODE=y
CONFIG_PRINTK=y
CONFIG_TTY=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_BINFMT_ELF_FDPIC=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
CONFIG_DEBUG_INFO_DWARF5=y
$ cat ../init.s
.text
.global _start
_start:
	li a0, 1
	la a1, .Lmsg
	lui a2, %hi(.Lmsglen)
	addi a2, a2, %lo(.Lmsglen)
	li a7, 64	  # __NR_write
	ecall
	li a0, 0xfee1dead
	li a1, 0x28121969
	li a2, 0x4321fedc # CMD_HALT
	li a7, 142	  # __NR_reboot
	ecall
	unimp
.data
.Lmsg:
.ascii "Hello!\n"
.Lmsglen = . - .Lmsg
$ mkdir ../rootfs
$ riscv64-linux-gnu-gcc -static -shared \
 -ffreestanding -nostdlib -march=rv64i -mabi=lp64 \
 ../init.s -o ../rootfs/init
$ cd ../rootfs && find . | cpio -co > ../rootfs.cpio && cd - >/dev/null
13 blocks
$ export CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv
$ make KCONFIG_ALLCONFIG=../minimal.config allnoconfig
$ make -j $(nproc)
...
  Kernel: arch/riscv/boot/Image is ready
$ qemu-system-riscv64 -cpu rv64,mmu=off -machine virt -bios none \
 -nographic -no-reboot -net none \
 -kernel arch/riscv/boot/Image -initrd ../rootfs.cpio
...
Run /init as init process
Hello!
reboot: Power down

On current master, nothing will be printed and the qemu command will just
hang (kill with control+a x), but with this patch it will boot normally.

Signed-off-by: Charles Mirabile <cmirabil@...hat.com>

Charles Mirabile (1):
  riscv: fix runtime constant support for nommu kernels

 arch/riscv/include/asm/runtime-const.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

-- 
2.49.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ