Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le 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)

Aperta
#11,868 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@cms19859230182-lang ci sta già lavorando.

Dal 17/10/2026.

  • #11876 di @cms19859230182-lang — aperta

Valutazione

Difficoltà
3/5
Tempo stimato
Mezza giornata
Idoneità per principianti
58/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
c

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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.
Lingua principale
C
Stelle
12.3k
Fork
5.5k
Merge medio
7g 9h
PR unite (30g)
34

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di RT-Thread/rt-thread

Tutte le issue di RT-Thread/rt-thread

Issue simili

Altre issue su C

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.