[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)
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
- Lĩnh vực
- operating-systems, security
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ả
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, andrt_malloc()returns 8-aligned memory, soconn->rx_bufferis always≡ 4 (mod 8);P9_MSG_STAT_LEN == 42, so&rx_buffer[42]is always≡ 6 (mod 8);- therefore every
Tstatreply — including a completely normal, honest one — takes an alignment fault atdfs_9pfs_open()line 623 (fd->vnode->size = get_rx_value64_of(conn, P9_MSG_STAT_LEN)) and atdfs_9pfs_stat()line 1113 (st->st_size), crashing the kernel with a data abort.
Steps to reproduce (full chain under QEMU):
- Build
bsp/qemu-vexpress-a9withRT_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>")). - Run any 9P server that answers
Tversion/Tattachand a syntactically normalRstat(a fully honest server is sufficient — the fault does not depend on malformed content). - Guest: any 9p file operation that reaches a stat, e.g.
open("/<mount>/f")orlsof a directory containing the mount point (msh'slsstats 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 aboutcount/stat_sizevalidation), 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
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.
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của RT-Thread/rt-thread
-
[bsp][stm32][bluepill] README「快速上手」缺少重新生成 MDK 工程这一步,按文档操作无法编译通过Có thể đã có người làm @moment-NEW đã nhận 15 ngày trước. Đang mởin progress
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
RT-Thread/rt-thread#11818 · 4 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
BSP BSP: Loongson bug RT-Smart
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
RT-Thread/rt-thread#11717 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Arch: RISC-V BSP BSP: HPMicro bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
RT-Thread/rt-thread#11687 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Feature] rt_null.c 初始化顺序太低 无法作为默认的日志口Có thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
RT-Thread/rt-thread#11472 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 78/100
RT-Thread/rt-thread#11882 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của RT-Thread/rt-thread
Issue tương tự
-
mewencode: base256[] and base128[] are indexed out of bounds by a non-ASCII octetCó thể đã có người làm @kazu-yamamoto đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
kazu-yamamoto/Mew#276 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 91/100
FujiNetWIFI/fujinet-firmware#2045 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 75/100
gbdev/homebrewhub-submit#20 ·
-
pluto: extract.c logs cert nickname instead of ckaid when both *cert= and *ckaid= are specifiedCó thể đã có người làm @Yash990-bit đã nhận hôm nay. Đang mở
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 2 ngày