Skip to content

[Bug] block: devfs ioctl copies partition data to an unvalidated user-supplied kernel pointer #11952

Open

Description

@XueDugu

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:

  1. Build the audited 32-bit RT-Smart vexpress kernel and an SD image containing /dev/sd0.
  2. Run this unprivileged user program as /sbin/init:
fd = open("/dev/sd0", O_RDWR);
ioctl(fd, RT_DEVICE_CTRL_BLK_PARTITION, KERNEL_ADDRESS);
  1. 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
  1. A second variant targeted rt_memcpy itself. 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

Activity

  1. github-actions commented on Oct 29, 2026

    @github-actions

    如需认领并处理此 Issue,请评论 /claim。

    To claim and work on this issue, comment /claim.

  2. liangzhan5 commented on Oct 30, 2026

    @liangzhan5

    /claim

  3. github-actions commented on Oct 30, 2026

    @github-actions

    @liangzhan5 has claimed this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions