W19: plugin_loader hardening — ABI try/catch, path validation, atomic IDs, CLI exit codes (W19.1-W19.5)
Some checks failed
CI / Determine matrix (push) Has been cancelled
CI / ${{ matrix.os }} / ${{ matrix.build_type }} (push) Has been cancelled

Fixes: F-18.3-1 through F-18.3-5 (all CLOSED, findings registry at zero)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 19:34:43 +08:00
parent c545d16120
commit 3250b5a8bf
15 changed files with 273 additions and 30 deletions

View File

@@ -2,7 +2,7 @@
> **维护人**: grp-quality-core (王测)
> **格式定义**: 见 `agents/WORKFLOW.md` §14.2
> **最后更新**: 2026-05-27 (W18.3 曹武+徐磊,plugin_loader 安全审计,录入 5 条 MEDIUM+ 发现)
> **最后更新**: 2026-05-27 (W19 CEO 验收,关闭 plugin_loader 全部 5 条发现findings 归零)
---
@@ -10,11 +10,7 @@
| ID | Severity | Source | Title | Status | Assigned To | Fix Wave | Verified By |
|----|----------|--------|-------|--------|-------------|----------|-------------|
| F-18.3-1 | HIGH | [W18.3-plugin-loader-audit.md](W18.3-plugin-loader-audit.md) | 5 处 C ABI 调用点 zero try/catch: on_init/on_shutdown/init_fn 穿越 ABI → std::terminate() (load_plugin L59, initialize_all L237, initialize_pending L272, unload_plugin L108-109, shutdown_all L306-307) | OPEN | — | — | — |
| F-18.3-2 | MEDIUM | [W18.3-plugin-loader-audit.md](W18.3-plugin-loader-audit.md) | load_plugin 全静默失败: 5 个独立失败点均返回 -1 无日志, GetProcAddress/dlsym 不调 GetLastError/dlerror (L28-77) | OPEN | — | — | — |
| F-18.3-3 | MEDIUM | [W18.3-plugin-loader-audit.md](W18.3-plugin-loader-audit.md) | 公开 API dstalk_plugin_load 路径零验证: 无规范化/目录约束/扩展名校验/签名验证, 相对路径触发 DLL 搜索劫持 (host.cpp:240 + load_plugin L32-35) | OPEN | — | — | — |
| F-18.3-4 | MEDIUM | [W18.3-plugin-loader-audit.md](W18.3-plugin-loader-audit.md) | initialize_all 用 fprintf(stderr) 替代 host->log(): 绕过诊断回调系统, host_api 在手却未用 (L229, L239-240) | OPEN | — | — | — |
| F-18.3-5 | MEDIUM | [W18.3-plugin-loader-audit.md](W18.3-plugin-loader-audit.md) | PluginLoader 零内部同步: next_id_++ 非原子, plugins_ 无 mutex; dstalk_plugin_load 不持 g_init_mutex (§6.5 文档声明单线程但代码无强制) | OPEN | — | — | — |
| — | — | — | 暂无 OPEN 发现 | — | — | — | — |
---
@@ -45,6 +41,11 @@
| F-13.2-4 | MEDIUM | [W13.2-deepseek-audit.md](W13.2-deepseek-audit.md) | g_host/g_http/g_config global pointers no sync read/write (L14-16, L459-L466): on_shutdown null-write races with service function reads | 2026-05-27 | W17.2 | engineer-zhao |
| F-13.1-2 | HIGH | [W13.1-anthropic-audit.md](W13.1-anthropic-audit.md) | response_body leak in my_chat error path: ret!=0 returns without freeing response_body | 2026-05-27 | W17.4 | — |
| F-13.1-3 | HIGH | [W13.1-anthropic-audit.md](W13.1-anthropic-audit.md) | g_host/g_http global pointers no sync protection: on_shutdown nullptr write races with service function reads | 2026-05-27 | W17.4 | — |
| F-18.3-1 | HIGH | [W18.3-plugin-loader-audit.md](W18.3-plugin-loader-audit.md) | 5 处 C ABI 调用点 (init_fn/on_init×2/on_shutdown×2) zero try/catch → std::terminate() | 2026-05-27 | W19.1 | CEO |
| F-18.3-2 | MEDIUM | [W18.3-plugin-loader-audit.md](W18.3-plugin-loader-audit.md) | load_plugin 5 失败路径静默返回 -1 无日志 (GetLastError/dlerror 丢弃) | 2026-05-27 | W19.2 | CEO |
| F-18.3-3 | MEDIUM | [W18.3-plugin-loader-audit.md](W18.3-plugin-loader-audit.md) | dstalk_plugin_load 公开 API 路径零验证:无扩展名/目录/来源完整性检查 | 2026-05-27 | W19.2 | CEO |
| F-18.3-4 | MEDIUM | [W18.3-plugin-loader-audit.md](W18.3-plugin-loader-audit.md) | fprintf(stderr) 绕过 host->log 日志通道 | 2026-05-27 | W19.2 | CEO |
| F-18.3-5 | MEDIUM | [W18.3-plugin-loader-audit.md](W18.3-plugin-loader-audit.md) | next_id_ 非原子load_plugin 并发调用可产生重复 ID | 2026-05-27 | W19.2 | CEO |
---
@@ -62,5 +63,11 @@
| 2026-05-27 | W17.2: F-13.2-3/F-13.2-4 状态 FIXED — SSE [DONE] sentinel 改为 trim-后精确比较g_host/g_http/g_config 全局指针改为 std::atomic load(acquire)/store(release) 保护 | 赵码 (engineer-zhao) |
| 2026-05-27 | W18.3: F-18.3-1~5 录入 Open 分区 — plugin_loader 安全审计发现 1 HIGH + 4 MEDIUM (ABI 异常安全、静默失败、路径验证、日志绕过、并发) | 曹武 (security-cao), 徐磊 (qa-xu) |
| 2026-05-27 | W18.2: F-11.7-3/F-11.7-4 状态 CLOSED — /context else 分支消息改为 "No active session" (main.cpp:188)/file write 无参用法提示已在重构的 /file 分发器中正确实现 (main.cpp:274)/status 增加连接状态行 (main.cpp:205-211),编译 0 error + ctest 4/4 pass | 赵码 (engineer-zhao), 朱晴 (designer-zhu) |
| 2026-05-27 | W19.1: F-18.3-1 状态 FIXED — 5 处 C ABI 调用点 (load_plugin init_fn/initialize_all on_init/initialize_pending on_init/unload_plugin on_shutdown/shutdown_all on_shutdown) 添加 try/catch(const std::exception&)+catch(...) 包装initialize_all 实现 fail-continue 单插件异常不阻断其他加载host_api_ 成员存储日志通道fprintf(stderr) 替换为 host_api->log()。编译 0 errorctest 5/5 pass。 | 曹武 (security-cao), 徐磊 (qa-xu) |
| 2026-05-27 | W19.2: F-18.3-2/3/4/5 状态 FIXED — (2) 5 失败路径添加 host_api_->log + GetLastError()/dlerror() 诊断;(3) load_plugin 路径验证: fs::absolute().lexically_normal() + 扩展名白名单(.dll/.so/.dylib) + 目录约束(plugins/ 子目录)(4) fprintf(stderr) 全部替换为 host_api_->log()(5) next_id_ 改为 std::atomic<int>。编译 0 errorctest 5/5 pass。 | 刘静 (engineer-liu), 陈风 (engineer-chen) |
| 2026-05-27 | W19.3: 验证 F-18.3-1~5 — CEO 复核 plugin_loader.cpp/hpp 确认全部 5 项修复到位 (try/catch 5处, host_api_->log, lexically_normal, atomic next_id_)。编译 0 errorctest 5/5 pass。| 王测 (qa-wang), 林深 (architect-lin) |
| 2026-05-27 | W19.4: CLI exit code 标准化 + SIGINT 信号处理 — EXIT_OK(0)/EXIT_INTERRUPT(1)/EXIT_FATAL(2)/EXIT_CONFIG(3) 宏g_quit_via_signal atomic 标志,统一 "再见!" 关闭消息。编译 0 errorctest 5/5 pass。| 赵码 (engineer-zhao), 朱晴 (designer-zhu) |
| 2026-05-27 | W19.5: CI 双平台矩阵验证 — ci.yml 确认 Ubuntu clang-18 + Windows clang-cl 矩阵、ccache 配置、构建计时VS 2026 路径回退已就位CMakePresets.json ci-release preset 验证通过。| 马奔 (devops-ma), 胡桐 (devops-hu) |
| 2026-05-27 | W17.4: F-13.1-2/F-13.1-3 状态 FIXED — my_chat ret!=0 路径释放 response_bodyg_host/g_http 改为 std::atomic load(acquire)/store(release) 保护,编译 0 error + ctest 4/4 pass | 马奔 (devops-ma) |
| 2026-05-27 | W18.1: F-11.1-3/4/5/6 状态 CLOSED — (3) 删除 g_max_tokens 全局变量和 context_set_max_tokens APItrim_impl 改用参数 max_tokens(4) count_tokens_utf8 多字节序列添加越界保护;(5) 提取共享 count_tokens_utf8 函数消除重复;(6) 添加 0xC0/0xC1 过短编码分支。新增 context_plugin_test.cpp 13 测试块覆盖。 | 王测 (qa-wang), 林深 (architect-lin) |
| 2026-05-27 | W19.1: F-18.3-1 状态 FIXED — 5 处 C ABI 调用点 (load_plugin init_fn/initialize_all on_init/initialize_pending on_init/unload_plugin on_shutdown/shutdown_all on_shutdown) 添加 try/catch(const std::exception&)+catch(...) 包装initialize_all 实现 fail-continue 单插件异常不阻断其他加载host_api_ 成员存储日志通道fprintf(stderr) 替换为 host_api->log()。编译 0 errorctest 5/5 pass。 | 曹武 (security-cao), 徐磊 (qa-xu) |