Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

[Bug] 9PFS: unaligned 64-bit loads in Rstat parsing fault on ARMv7-A — any 9P server reply to Tstat causes a kernel data abort (remote DoS)

Đang mở
#11,868 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@cms19859230182-lang đang làm issue này rồi.

Từ ngày 17/10/2026.

  • #11876 của @cms19859230182-lang — đang mở

Đánh giá

Độ khó
3/5
Thời gian dự kiến
Nửa ngày
Mức phù hợp với người mới
58/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
c

Hướng nghiên cứu

Start with the P9_OF_OPS_GET macro and get_rx_value64_of() in components/dfs/dfs_v1/filesystems/9pfs/dfs_9pfs.c, then trace their callers at dfs_9pfs_open() and dfs_9pfs_stat(). The report suggests two fixes, a split 32-bit read or an aligned buffer, so pick one and confirm it on the QEMU vexpress-a9 build. Done means the Tstat path no longer faults on ARMv7-A and the 16/32-bit accessors are handled consistently.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Arch: ARM/AArch64 bug Component
RT-Thread Version

master ceef6e0ccd646aef61b907aeb9f29269d1caba50 (2026-10-11, RT-Thread 5.3.1). Also present in v5.3.0. Introduced by 2ffa4f3d60e2374fd06f20d82a7549c4c054a862 ("[DFS] Support 9PFS", merged 2025-12-04); the accessor macros are unchanged since.

Affected area

File systems (DFS)

Hardware/BSP vendor

Not applicable / Other

Architecture

ARM / AArch64

Board and hardware details

config: RT_USING_DFS_V1 + RT_USING_DFS_9PFS + lwIP; 9P over a TCP transport registered via dfs_9pfs_add_tag()

Develop Toolchain

GCC

Describe the bug

get_rx_value64_of() dereferences a plain pointer cast:

/* components/dfs/dfs_v1/filesystems/9pfs/dfs_9pfs.c:48-54 */
#define P9_OF_OPS_GET(width, dir) ... \
    rt_uint##width##_t *vp = (void *)&conn->dir##_buffer[idx]; \
    return rt_le##width##_to_cpu(*vp);

On ARMv7-A, GCC emits LDRD for this 64-bit load, which requires 8-byte alignment. The buffer layout makes the fault deterministic:

  • sizeof(struct p9_connection) == 292, and rt_malloc() returns 8-aligned memory, so conn->rx_buffer is always ≡ 4 (mod 8);
  • P9_MSG_STAT_LEN == 42, so &rx_buffer[42] is always ≡ 6 (mod 8);
  • therefore every Tstat reply — including a completely normal, honest one — takes an alignment fault at dfs_9pfs_open() line 623 (fd->vnode->size = get_rx_value64_of(conn, P9_MSG_STAT_LEN)) and at dfs_9pfs_stat() line 1113 (st->st_size), crashing the kernel with a data abort.

Steps to reproduce (full chain under QEMU):

  1. Build bsp/qemu-vexpress-a9 with RT_USING_DFS_V1=y, RT_USING_DFS_9PFS=y, lwIP enabled, and an application registering a 9p transport + mounting it (dfs_mount(NULL, "/", "9p", 0, "<tag>")).
  2. Run any 9P server that answers Tversion/Tattach and a syntactically normal Rstat (a fully honest server is sufficient — the fault does not depend on malformed content).
  3. Guest: any 9p file operation that reaches a stat, e.g. open("/<mount>/f") or ls of a directory containing the mount point (msh's ls stats every entry).

Expected behavior: 9P Rstat parsing works on 32-bit ARM targets; unaligned accesses performed safely.

Actual behavior — kernel data abort, thread dump, shutdown loop:

data abort:Execption:
r00:0x600f90f8 r01:0x0000002a r02:0x600f921c r03:0x600f9246   <- r03 = rx_buffer+42 (mod 8 = 6)
...
pc :0x6005a668

  6005a660:  e1c320d0  ldrd r2, [r3]        <- unaligned LDRD -> alignment fault

backtrace:
  get_rx_value64_of  components/dfs/dfs_v1/filesystems/9pfs/dfs_9pfs.c:84
  dfs_9pfs_open      components/dfs/dfs_v1/filesystems/9pfs/dfs_9pfs.c:623
  dfs_file_open / open / (caller)

(addr2line-verified; the faulting address r03 equals rx_buffer + 42.)

Control run: after mounting, without touching any 9p path (ps, version only) the system keeps running normally — the abort is caused exclusively by the 9pfs stat parsing path.

Other additional context
  • Severity: CVSS 3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (7.5 High, scoped to ARMv7-A + 9pfs deployments), CWE-704 / CWE-125-adjacent (unsafe type reinterpretation).
  • The same accessor is used with an attacker-walked index in dfs_9pfs_getdents() (see the companion report about count/stat_size validation), so the 16/32-bit variants should be hardened at the same time — odd offsets are reachable there.
  • Practical note: 9pfs on 32-bit ARMv7-A boards is therefore unusable today; on aarch64 the equivalent code silently proceeds, which is why this went unnoticed with qemu-virt64-* / virtio testing.
  • Suggested fix — read unaligned-safe (two 32-bit halves, or __builtin_assume_aligned-free memcpy):
rt_inline rt_uint64_t get_rx_value64_of(struct p9_connection *conn, unsigned idx)
{
    rt_uint32_t lo = rt_le32_to_cpu(*(volatile rt_uint32_t *)&conn->rx_buffer[idx]);
    rt_uint32_t hi = rt_le32_to_cpu(*(volatile rt_uint32_t *)&conn->rx_buffer[idx + 4]);
    return ((rt_uint64_t)hi << 32) | lo;
}

and/or declare rx_buffer/tx_buffer with explicit 8-byte alignment (rt_align(8)).

  • Affected versions: master since 2ffa4f3d60 (2025-12-04); all releases >= v5.3.0. No fix as of 2026-10-15.
Ngôn ngữ chính
C
Star
12.3k
Fork
5.5k
Merge trung bình
7 ngày 23 giờ
Pull request đã merge (30 ngày)
30

Chuẩn bị môi trường

Mở trong Codespaces

Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của RT-Thread/rt-thread

Tất cả issue của RT-Thread/rt-thread

Issue tương tự

Thêm issue về C

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.