Repository navigation
Conversation
sys_poll() and sys_epoll_pwait() size a kernel buffer from a count that comes
straight from the user process:
if (!lwp_user_accessable((void *)fds, nfds * sizeof *fds)) /* wraps */
kfds = (struct pollfd *)kmem_get(nfds * sizeof *kfds); /* wraps */
ret = poll(kfds, nfds, timeout); /* full nfds */
On a 32-bit build nfds = 0x20000001 and sizeof(struct pollfd) = 8 make the
product 0x1_00000008, which wraps to 8. The access check and the allocation then
agree on an 8-byte block, but poll() walks all 536,870,913 entries: do_pollfd()
reads pollfd->fd and writes revents far outside that block. 64-bit builds are not
affected because the product is promoted to 64 bits and the oversized allocation
just fails.
sys_epoll_pwait() has the same shape, and its cnt is a signed int, so a negative
value has to be rejected as well.
Reject the counts that cannot be represented before anything is sized from them,
using the same SIZE_MAX / sizeof(...) form already used for msg_iovlen in
sys_sendmsg/sys_recvmsg.
The guard arithmetic was checked in isolation with 32-bit size_t semantics:
32-bit SIZE_MAX / sizeof(struct pollfd) = 536870911 (0x1FFFFFFF)
nfds 0x1FFFFFFF -> accepted
nfds 0x20000000 -> rejected
nfds 0x20000001 -> wraps to 8 without the guard, rejected with it
epoll cnt -1, 0x15555556 -> rejected, 0 and small values -> accepted
Note: the RT-Smart build itself was NOT compiled locally. lwp.h requires
RT_USING_MUSLLIBC, so an arm-linux-musleabi toolchain is needed and it was not
available here (the toolchain download could not be reached). A CI run on the
RT-Smart configuration is required before merging.
Refs RT-Thread#11925
📌 Code Review Assignment🏷️ Tag: componentsReviewers: @Maihuanyi Changed Files (Click to expand)
🏷️ Tag: components_lwpReviewers: @xu18838022837 Changed Files (Click to expand)
📊 Current Review Status (Last Updated: 2026-10-30 12:10 CST)
📝 Review Instructions
|
|
👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread! 为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流(如果格式化CI运行失败)。 🛠 操作步骤 | Steps
完成后,提交将自动更新至 如有问题欢迎联系我们,再次感谢您的贡献!💐 |
|
请基于拆分后的syscall进行提交PR,谢谢 |
拉取/合并请求描述:(PR description)
[
为什么提交这份PR (why to submit this PR)
修复 #11925(前半部分,见末尾说明)。
sys_poll()用用户进程给的数量算内核缓冲区大小,乘法在 32 位下回绕,但随后仍用未回绕的原始数量遍历:nfds = 0x20000001、sizeof(struct pollfd) = 8时乘积0x1_00000008截成 8,访问校验与分配都按 8 字节通过,而poll()会遍历全部 536,870,913 项,do_pollfd()里的pollfd->fd读与revents写都落在块外。64 位构建不受影响(乘积提升到 64 位,超大分配直接 ENOMEM)。sys_epoll_pwait()是同一形状,且它的cnt是int,负值也要一并拒绝。你的解决方案是什么 (what is your solution)
在拿这些数量算任何大小之前,先拒绝无法表示的组合,写法与
sys_sendmsg/sys_recvmsg里对msg_iovlen的校验保持一致:请提供验证的bsp和config (provide the config and bsp)
注意:本 PR 未能在本地完成 RT-Smart 编译验证,请勿在 CI 通过前合并。
原因:
components/lwp/lwp.h:92要求RT_USING_MUSLLIBC,即必须用 arm-linux-musleabi 工具链;本机只有arm-none-eabi,编到board.o就报:尝试下载 musl 工具链但网络不可达(GitHub API 请求超时)。
已完成的验证:把守卫算术用 32 位
size_t语义做了隔离测试(宿主 gcc),结果:这只证明了守卫逻辑与边界正确,不等于集成编译通过。合并前需要在 RT-Smart 配置上跑一次 CI(
bsp/qemu-vexpress-a9+.github/utest/configs/rtsmart/rtsmart.cfg)。]
当前拉取/合并请求的状态 Intent for your PR
必须选择一项 Choose one (Mandatory):
代码质量 Code Quality:
我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up