Repository navigation
[Bug] block: devfs ioctl copies partition data to an unvalidated user-supplied kernel pointer #11952
Description
RT-Thread Version
master (v5.4.0-dev), and releases v5.2.0 through v5.3.0 (introduced with the common block layer in c424cb818695).
Affected area
- Device drivers (block layer / DFS devfs fops)
Hardware-BSP vendor
Other (verified on QEMU vexpress-a9; applies to RT-Smart targets exposing block partitions)
Architecture
- ARM / ARMv7-A
- Other (RT-Smart MMU configurations using the common block layer)
Board and hardware details
RT-Smart ARMv7-A QEMU vexpress-a9, 32-bit, with an SD image. The kernel creates /dev/sd0.
Develop Toolchain
Official RT-Thread musl ARM toolchain, GCC 7.3.0; QEMU 9.2.3 and gdb-multiarch.
Describe the bug
An unprivileged RT-Smart process can pass a kernel pointer to a block-device ioctl. sys_ioctl() and blk_fops_ioctl() forward the raw argument without copy-in/out, and blk_dev_control() handles RT_DEVICE_CTRL_BLK_PARTITION by doing:
rt_memcpy(args, &blk->partition, sizeof(blk->partition));args is therefore an attacker-selected kernel destination for a 24-byte write. The branch also leaves err as -RT_EINVAL, so the syscall returns -1 even after the write succeeds.
Reproduction:
- Build the audited 32-bit RT-Smart vexpress kernel and an SD image containing
/dev/sd0. - Run this unprivileged user program as
/sbin/init:
fd = open("/dev/sd0", O_RDWR);
ioctl(fd, RT_DEVICE_CTRL_BLK_PARTITION, KERNEL_ADDRESS);- GDB captured
rt_memcpy(dst=0xc00fa484, src=0xc0124cb0, count=24)through:
blk_dev_control -> rt_device_control -> dfs_devfs_ioctl
-> dfs_file_ioctl -> ioctl -> sys_ioctl -> vector_swi
The target changed from all zeros to:
00000000 00000000 00000000 00000000 00020000 c0124bf4
- A second variant targeted
rt_memcpyitself. GDB showed its first 24 bytes replaced by the same partition data; the next invocation stopped running.
The control group used a normal RT_DEVICE_CTRL_BLK_GETGEOME with a user buffer, returned sector_count=0x20000, bytes_per_sector=0x200, block_size=0x200, and the kernel remained alive.
Expected result: reject kernel pointers and copy user ioctl arguments through bounded kernel buffers. RT_DEVICE_CTRL_BLK_PARTITION must not write directly to the raw caller pointer.
Actual result: an unprivileged local process can write a kernel partition structure to an arbitrary kernel address, including writable kernel text, causing integrity violation or kernel death.
Other additional context
- CVSS 3.1:
AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H= 7.1 High - CWE-787 / CWE-668
- Attack premise: unprivileged local RT-Smart user process; no special privileges. The target must expose a block partition through devfs.
- This is an incomplete-fix sibling of [Bug] [Smart] terminal tty: ioctl passes raw user pointer into kernel dereference — arbitrary kernel read/write from unprivileged user process #11937. [Bug] [Smart] terminal tty: ioctl passes raw user pointer into kernel dereference — arbitrary kernel read/write from unprivileged user process #11937 fixes the tty sink of the raw
sys_ioctlpointer path; this block sink remains unfixed. - Distinguished from [Bug] integer overflow in GPT entry allocation causes OOB read on 32-bit targets #11260/[Bug] malformed GPT entry with ending_lba < starting_lba creates an underflowed partition size #11271/[Bug] DFS partition probing accepts out-of-range MBR partition geometry and may forward out-of-bounds I/O to the parent block device #11286, which concern GPT/MBR partition geometry parsing rather than the ioctl pointer boundary.
- Full QEMU logs and GDB transcripts are available on request.
Activity
github-actions commentedon Oct 29, 2026
如需认领并处理此 Issue,请评论
/claim。To claim and work on this issue, comment
/claim.liangzhan5 commentedon Oct 30, 2026
/claim
github-actions commentedon Oct 30, 2026
@liangzhan5 has claimed this issue.