Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

[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)

未關閉
#11,868 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

@cms19859230182-lang 已經在處理了。

開始於 2026年10月17日。

  • #11876 來自 @cms19859230182-lang —— 未關閉

評估

難度
3/5
預估耗時
半天
新手友好度
58/100
Issue 類型
缺陷
描述清晰度
基本清楚
活躍度
活躍
技術堆疊
c

研究方向

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.

由索引模型根據 Issue 內容生成。

描述

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.
主要語言
C
星號
12.3k
分支
5.5k
平均合併
7 天 9 小時
30 天內合併 PR
34

環境準備

在 Codespaces 中開啟

在瀏覽器裡用你自己的 GitHub 帳號啟動這個專案的開發容器。

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

RT-Thread/rt-thread 的其他 Issue

查看 RT-Thread/rt-thread 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。