HTTP: a code route can mutate the live route table and static root from a worker thread — unsynchronized writes racing every other worker's lookups
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 48/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- c
调研方向
Start at http_conn_thread and the g_server/eigs_http_active handling, then inspect builtin_http_route, builtin_http_route_authed, builtin_http_static, and the existing serving guard used by http_response_header. Run tests/http_readiness.py and add the live mutation case described in the issue; done means mutation fails loudly, /injected remains 404, and the concurrent probe is race-free under the planned tsan-http lane.
由索引模型根据 Issue 内容生成。
描述
Observed (executed on main a18deac, make http)
A code route runs in a per-connection worker thread. The worker gets its own EigsState, but http_conn_thread then re-points the thread-local server accessor at the SPAWNING server so that handle_request reads the real route table:
/* register_http_builtins allocated a scratch Server on the worker state (so
* http_route/http_serve called inside a code route don't crash) ... Re-point
* at the spawning Server so handle_request reads the main route table. */
eigs_http_active = main_server;
The comment's intent (a scratch server absorbs config calls from a code route) is defeated two lines later: g_server is (*eigs_http_active), so http_route, http_route_authed and http_static invoked from a code route WRITE the main server's config while every other worker reads it lock-free.
Probe:
r is http_route of ["GET", "/", "page"]
c is http_route of ["GET", "/mutate", "code",
"http_route of [\"GET\", \"/injected\", \"INJECTED\"]\nhttp_static of [\"/static\", \"/tmp\"]\n\"mutated\""]
http_serve of 24911
before: GET /injected -> 404
GET /mutate -> mutated
after: GET /injected -> 200 INJECTED
One request permanently changed the routing table for the whole process.
Why it is a concurrency defect, not just a design oddity
builtin_http_routefillsroutes[route_count]'s four string fields, then doesg_server.route_count++— a plain non-atomic int with no release fence. A concurrent worker iteratingfor (i < route_count)can observe the incremented count before the slot's fields are visible and callstrcmpon NULL/garbage.builtin_http_staticswapsstatic_prefix/static_dirunder no lock while workers dereference them (the old strings are leaked rather than freed, so no UAF today — by accident).- The
route_count >= MAX_ROUTEScheck is check-then-act across threads. - Exploitation needs a trusted code route that calls these builtins, so this is a correctness/robustness issue, not a remote hole — but it is a genuine data race in the runtime's most concurrent code, and it lives in the same file that #1137 just cleaned up.
Suggested fix
Freeze configuration at http_serve, the way http_response_header already does: builtin_http_route, builtin_http_route_authed and builtin_http_static check g_server.serving (under response_mu, or make it atomic) and raise a loud error once serving. Every lock-free read of routes/static config is then reading immutable data, which is the property the current code silently assumes.
Gate
tests/http_readiness.py: a live case with a code route that callshttp_route/http_static— the request must fail loudly (500 with the error text) and/injectedmust remain 404 afterwards; plant: revert the freeze → red.- Once #1139 lands a
tsan-httplane, a probe hammering/mutateand/concurrently should report the race on today's tree and be silent after the fix.
Found during the concurrency review that followed PR #1138 (2026-09-14). The rest of the file's threading — init responder, response builder, shared store, per-IP table, config caches — reviewed sound.
- 主要语言
- C
- 星标
- 3
- 派生
- 7
- 平均合并
- 4 小时 15 分钟
- 30 天内合并 PR
- 106
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 提供 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
InauguralSystems/EigenScript 的其他 Issue
-
area:lint-tooling bug
难度 2/5 1-3 小时 新手友好度 88/100
InauguralSystems/EigenScript#1340 ·
维护者通常 1 天内回复
-
area:stdlib found-by:code-review kind:silent-wrong
难度 2/5 1-3 小时 新手友好度 88/100
InauguralSystems/EigenScript#1338 ·
维护者通常 1 天内回复
-
area:lint-tooling found-by:critic kind:docs-drift
难度 2/5 1-3 小时 新手友好度 76/100
InauguralSystems/EigenScript#1335 ·
维护者通常 1 天内回复
-
area:ci found-by:critic kind:gate-defect
难度 2/5 1-3 小时 新手友好度 86/100
InauguralSystems/EigenScript#1311 ·
维护者通常 1 天内回复
-
enrolment: decide test_gc_runner_controls.py (exempt vs enrol) and whether floors need a ratchet未关闭area:gates found-by:critic kind:decision
难度 2/5 1-3 小时 新手友好度 65/100
InauguralSystems/EigenScript#1280 · 1 条评论 ·
维护者通常 1 天内回复
查看 InauguralSystems/EigenScript 的全部 Issue
相似的 Issue
-
难度 1/5 1 小时以内 新手友好度 92/100
sandialabs/seacas#945 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 88/100
ARM-software/sysarch-acs#556 · 1 条评论 ·
-
难度 2/5 1-3 小时 新手友好度 68/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
bug needs triage
难度 2/5 1-3 小时 新手友好度 78/100
netdata/netdata#24062 · 1 条评论 ·
维护者通常 1 天内回复