提交 #844622: RT-Thread v5.0.2 Improper Handling of Parameters信息

标题RT-Thread v5.0.2 Improper Handling of Parameters
描述I have already reported this vulnerability in the project's GitHub issue tracker for review by the maintainers. The report is provided below. # sys_getaddrinfo trusts nested user pointer and can write outside validated user memory ## Summary I identified an insufficient user-pointer validation issue in the `sys_getaddrinfo` system call in RT-Thread Smart. When `ARCH_MM_MMU` is enabled, `sys_getaddrinfo()` validates that the outer `res` pointer is user-accessible. However, after a successful name lookup it reads `res->ai_addr` directly from that user-controlled structure and passes it to `sockaddr_tomusl()`. `sockaddr_tomusl()` then writes a `struct musl_sockaddr` result through that nested pointer without checking that the nested destination is valid user memory. This gives an unprivileged user process control over the kernel write destination used for the returned socket address. If the nested pointer targets mapped kernel or otherwise sensitive memory, the syscall can perform an unauthorized write. If it targets unmapped or faulting memory, the direct kernel write can crash the system, causing a denial of service. ## Vulnerable Code Location The vulnerable syscall is registered in the LWP syscall table: ```text components/lwp/lwp_syscall.c:11085 SYSCALL_NET(SYSCALL_SIGN(sys_getaddrinfo)), ``` The affected code is in: ```text components/lwp/lwp_syscall.c:7051 sys_getaddrinfo(...) components/lwp/lwp_syscall.c:7163 sockaddr_tomusl(k_res->ai_addr, res->ai_addr) components/lwp/lwp_syscall.c:314 sockaddr_tomusl(...) components/lwp/lwp_sys_socket.h:105 struct musl_sockaddr ``` The important data flow is: ```text user-controlled res -> sys_getaddrinfo(..., struct musl_addrinfo *res) -> lwp_user_accessable(res, sizeof(*res)) checks only the outer object -> res->ai_addr is read directly from user memory -> sockaddr_tomusl(k_res->ai_addr, res->ai_addr) -> std->sa_family write and memcpy(std->sa_data, ...) -> attacker-selected destination write or kernel fault ``` Relevant code: ```c struct musl_addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; socklen_t ai_addrlen; struct musl_sockaddr *ai_addr; char *ai_canonname; struct musl_addrinfo *ai_next; }; sysret_t sys_getaddrinfo(const char *nodename, const char *servname, const struct musl_addrinfo *hints, struct musl_addrinfo *res) { ... #ifdef ARCH_MM_MMU if (!lwp_user_accessable((void *)res, sizeof(*res))) { SET_ERRNO(EFAULT); goto exit; } #endif ... ret = sal_getaddrinfo(k_nodename, k_servname, k_hints, &k_res); if (ret == 0) { /* res is validated, but res->ai_addr is not. */ sockaddr_tomusl(k_res->ai_addr, res->ai_addr); res->ai_addrlen = k_res->ai_addrlen; res->ai_family = k_res->ai_family; res->ai_flags = k_res->ai_flags; res->ai_next = NULL; ... } ... } ``` `sockaddr_tomusl()` only checks for NULL. It does not validate that `std` points to writable user memory and it does not use `lwp_put_to_user()`: ```c static void sockaddr_tomusl(const struct sockaddr *lwip, struct musl_sockaddr *std) { if (std && lwip) { std->sa_family = (uint16_t) lwip->sa_family; memcpy(std->sa_data, lwip->sa_data, sizeof(std->sa_data)); } } ``` The destination type is 16 bytes: ```c struct musl_sockaddr { uint16_t sa_family; char sa_data[14]; }; ``` ## Vulnerability Description The syscall validates only the top-level `res` pointer: ```c lwp_user_accessable((void *)res, sizeof(*res)) ``` That check proves only that the `struct musl_addrinfo` object itself is in accessible user memory. It does not prove that the pointer stored inside `res->ai_addr` is safe to write to. After `sal_getaddrinfo()` succeeds, the kernel directly evaluates `res->ai_addr` and uses it as the output destination for the resolved socket address: ```c sockaddr_tomusl(k_res->ai_addr, res->ai_addr); ``` Because `res` is user-controlled, `res->ai_addr` is also user-controlled. A malicious process can set it to: 1. A kernel or sensitive memory address that should not be writable from user mode, causing an unauthorized kernel write. 2. An unmapped or invalid address, causing a kernel fault and denial of service. 3. Another user process's mapped memory, if such mappings are reachable in the current address-space configuration. The bug is similar in shape to other nested-pointer syscall bugs: checking the outer structure is not enough. Each user-supplied pointer contained inside that structure must be copied into kernel memory and validated before use, and writes back to user space should go through the kernel's user-copy helpers. ## Steps to Reproduce I have not reproduced this on physical RT-Thread Smart hardware. The issue is visible from source-level inspection of the syscall path. Required configuration: ```text RT_USING_SMART or RT_USING_LWP enabled ARCH_MM_MMU enabled RT_USING_SAL enabled SAL_USING_POSIX enabled ``` Several Smart/MMU board configurations in the checked tree enable the relevant pieces, including: ```text bsp/nxp/imx/imx6ull-smart/rtconfig.h bsp/k230/rtconfig.h bsp/cvitek/cv18xx_risc-v/rtconfig.h bsp/rockchip/rk3500/rtconfig.h bsp/raspberry-pi/raspi-dm2.0/rtconfig.h ``` Conceptual trigger from an unprivileged process: ```c struct musl_addrinfo res; memset(&res, 0, sizeof(res)); /* * The outer object &res is a valid user pointer, so sys_getaddrinfo() * accepts it. The nested pointer is attacker-controlled. */ res.ai_addr = (struct musl_sockaddr *)ATTACKER_CHOSEN_ADDRESS; sys_getaddrinfo("127.0.0.1", "80", NULL, &res); ``` If `ATTACKER_CHOSEN_ADDRESS` is writable kernel memory, the syscall writes the returned address family and 14 bytes of address data there. If it is invalid or unmapped, the same direct write can fault in kernel context. Expected safe behavior: ```text sys_getaddrinfo() should reject an inaccessible nested res->ai_addr pointer with EFAULT, or copy the result through a validated kernel temporary and lwp_put_to_user(). ``` Current behavior: ```text sys_getaddrinfo() validates only res, then writes through res->ai_addr directly. ``` ## Impact This vulnerability can allow an unprivileged process to influence where the kernel writes the resolved socket address returned by `sys_getaddrinfo()`. Potential impacts include: ```text Unauthorized memory write: The attacker controls res->ai_addr, and sockaddr_tomusl() writes a 16-byte musl_sockaddr result to that address. Denial of service: If res->ai_addr points to unmapped or otherwise faulting memory, the direct kernel write can crash or destabilize the system. Privilege escalation risk: On targets where user-controlled syscall writes can reach sensitive kernel state, the write may corrupt kernel objects or control data. ``` The exact exploitability depends on the target MMU mapping, kernel address exposure, and RT-Thread Smart memory protection configuration. The core issue is that the syscall crosses the user/kernel boundary with a nested attacker-controlled pointer and writes through it without validation. ## Suggested Fix Do not read or write nested user pointers directly from `res`. One safer pattern is: ```text 1. Copy the outer musl_addrinfo from user memory into a kernel temporary. 2. Validate copied_res.ai_addr with lwp_user_accessable(copied_res.ai_addr, sizeof(struct musl_sockaddr)). 3. Convert the kernel sockaddr into a kernel musl_sockaddr temporary. 4. Use lwp_put_to_user(copied_res.ai_addr, &tmp_sockaddr, sizeof(tmp_sockaddr)). 5. Use lwp_put_to_user(res, &tmp_addrinfo, sizeof(tmp_addrinfo)) for the outer result fields. ``` The same pattern should also be used for reading `hints`: copy it once with `lwp_get_from_user()` and use the kernel copy, instead of repeatedly reading fields from the user pointer. ## Environment ```text Initial RT-Thread commit checked: c39e92f4c1 Checked tree description: v5.0.2-2360-gc39e92f4c1-dirty Affected file: components/lwp/lwp_syscall.c Affected syscall: sys_getaddrinfo Affected configuration: RT-Thread Smart / LWP with ARCH_MM_MMU and SAL POSIX networking Target hardware: not tested on board yet Verification: source-level syscall data-flow review ```
来源⚠️ https://github.com/RT-Thread/rt-thread/issues/11428
用户
 Zephyr Saxon (UID 80853)
提交2026-06-01 08時54分 (1 月前)
管理2026-07-03 15時51分 (1 month later)
状态已接受
VulDB条目376115 [RT-Thread 直到 5.0.2 lwp_syscall.c sys_getaddrinfo ai_addr 内存损坏]
积分20

Do you need the next level of professionalism?

Upgrade your account now!