openinterpreter 仓库中的 bubblewrap 源码:NEWS 版本演进、setuid 弃用与在 Linux 沙箱中的编译集成
本文以 codex-rs/vendor/bubblewrap/NEWS.md 这份 vendored 变更日志为主线,梳理 bubblewrap 0.11.0 → 0.11.2 三个版本的完整改动(安全修复、-Dsupport_setuid 构建开关、overlay 支持等),并结合本仓库的实际构建代码(Cargo 构建脚本、Bazel 规则)与 codex-linux-sandbox 的运行机制,说明这份 vendored 源码是如何被直接编译进项目的 Linux 沙箱执行链路的。读完后,你将能准确理解各版本条目的技术含义、setuid 模式为何被默认关闭,以及当系统未安装 bwrap 时 bundled 二进制从哪里来。
NEWS.md:vendored bubblewrap 的完整变更日志
bubblewrap(命令名 bwrap)是 Linux 下基于命名空间与 seccomp 的轻量沙箱工具,在仓库中它以完整 C 源码的形式被 vendor 到 codex-rs/vendor/bubblewrap/ 目录下(含 bubblewrap.c、bind-mount.c、network.c、utils.c 及头文件、测试、shell 补全脚本等)。codex-rs/vendor/bubblewrap/NEWS.md 就是这份 vendored 源码的版本变更记录,覆盖 0.11.0 至 0.11.2 三个发布版本。文档末尾的 "See also" 指向上游 releases 页面(外部链接,此处按规范不输出),版本事实以本仓库内文件为准。
0.11.2(2026-04-23):setuid 漏洞修复与 -Dsupport_setuid 构建开关
这是 vendored 版本中的最新版本,包含一项安全修复和一项构建增强:
Bug fix:CVE-2026-41163(setuid 模式下的 ptrace 问题)
在 setuid 模式下,bubblewrap 会先以高权限完成部分 setup,再降权执行其余部分。0.11.2 之前的实现会让低权限阶段的进程保持 dumpable 状态,这意味着该进程仍可被 ptrace,从而带来安全隐患(由 François Diakhate 报告,编号 CVE-2026-41163)。修复方式是让 setuid 模式的低权限部分不再以 dumpable 身份运行,直接消除这条被 ptrace 的路径。
Enhancement:新的 Meson 选项 -Dsupport_setuid(默认 false)
当该选项设为 false(默认值)时,编译出的二进制将完全禁用 setuid 支持,并且如果被人为设置为 setuid 权限会直接拒绝运行。NEWS 原文明确推荐:普通用户就应该用这种方式构建 bubblewrap,这样可以把只影响 setuid 模式的安全问题安全地排除在威胁模型之外。
这一点在本仓库中有直接的代码印证:codex-rs/vendor/bubblewrap/meson_options.txt 第 44–49 行定义了该选项:
option(
'support_setuid',
type : 'boolean',
description : 'Support setuid mode (deprecated)',
value : false,
)
可以看到 support_setuid 被标注为 deprecated 且默认 false,与 NEWS 条目完全一致。这也解释了本仓库整体策略——codex-linux-sandbox 走的是用户命名空间(--unshare-user)而非 setuid 的路径(详见下文),因此 setuid 相关漏洞面与本项目的运行时风险基本解耦。
0.11.1(2026-03-21):SIGCHLD 处置恢复与命名空间 fd 参数修复
Bug fix:重置 SIGCHLD 的处置(#705)
当 bwrap 从一个正在忽略 SIGCHLD 的父进程(例如 Erlang 运行时、volumeicon 这类常驻 GUI 进程)内部启动时,之前不会恢复该信号的标准处置,导致容器内子进程管理行为异常。0.11.1 会显式重置 SIGCHLD disposition,恢复正常的子进程管理语义。对于任何在忽略 SIGCHLD 的宿主进程中派生沙箱命令的场景,这是一项重要的行为修复。
Bug fix:不再忽略显式传入的 --userns 0 / --userns2 0 / --pidns 0(#731)
此前把 fd 号 0 传给 --userns/--userns2/--pidns 会被当作"未指定"而忽略。修复后这些参数会被如实处理。NEWS 同时保留了实用提示:由于 stdin/stdout/stderr(fd 0–2)会被容器内命令继承,给这类选项传 fd ≥ 3 仍是推荐做法,以避免歧义。
其他修复:错误信息语法修正(#694)、文档中的失效链接修复(#729)。
Internal:CI 中启用 user namespaces(#728)
在 GitHub Actions 配置里显式启用 user namespaces,修复了新版 Ubuntu 上的 CI 回归。这条内部改动对下游使用者也有参考意义:bubblewrap 的用户命名空间路径依赖内核与发行版配置,CI 环境需要主动开启 userns 支持(本仓库 vendor 目录下的 codex-rs/vendor/bubblewrap/ci/enable-userns.sh 正是配套的启用脚本)。
0.11.0(2024-10-30):Meson 独占构建、overlay 挂载与 --level-prefix
这是三个版本中改动量最大的一版,横跨构建系统、功能增强与修复:
Dependencies:Autotools 移除,Meson ≥ 0.49.0 成为构建期硬性要求(#625)
Autotools 构建系统被彻底删除,构建只走 Meson。对 bash 补全用户的额外要求:推荐 bash-completion ≥ 2.10;更老的 bash-completion 版本可能把补全脚本安装到 ${prefix} 之外,此时可用 -Dbash_completion_dir=… 覆盖安装目录。codex-rs/vendor/bubblewrap/meson_options.txt 中的 bash_completion / bash_completion_dir / zsh_completion / zsh_completion_dir 等选项定义与这条说明一一对应。
Enhancement:overlay 挂载四件套(#412、#663)
新增 --overlay、--tmp-overlay、--ro-overlay、--overlay-src 四个选项,用于创建 overlay 挂载。NEWS 明确注明:当 bubblewrap 以 setuid 方式安装时该功能不可用——这与 0.11.2 推进的"默认关闭 setuid"方向相互呼应:overlay 能力只在非 setuid(用户命名空间)路径下提供。
Enhancement:--level-prefix 选项(#646)
输出可被 logger --prio-prefix 与 systemd-cat --level-prefix=1 等工具解析的带级别前缀的日志,方便把 bwrap 日志接入 systemd/journald 体系。
Bug fixes 一览
- 对文件与套接字的 I/O 处理
EINTR(#657):被信号中断的读写不再直接失败,改善长 I/O 场景的健壮性; - 不再假设 socket 控制消息(
recvmsgcmsg)数据的对齐方式(#637):提升跨架构可移植性; - 消除部分 Meson 弃用警告(#647);
- 文档 URL 全部升级为 https(#566);
- 提升测试对 busybox 的兼容性(#627);
- 改进对 Meson < 1.3.0 的兼容(#664)。
Internal changes:统一使用 <stdbool.h> 表示布尔值(#660)、规避 -Wshadow 告警(#661)、更新 GitHub Actions 配置(#658)。
仓库如何编译这份 vendored 源码:双构建系统集成
NEWS 描述的只是上游 bubblewrap 的版本事实;真正让这些 C 文件在项目里生效的,是本仓库的两套构建集成。理解这一层,才能知道 0.11.2 的修复"确实进入了产物"。
1. Cargo 构建路径:codex-bwrap crate
codex-rs/bwrap/ 是一个独立的 crate(包名 codex-bwrap,产物二进制名 bwrap,见 Cargo.toml),它不在运行时调用外部 bubblewrap,而是在构建期直接编译 vendored 的 C 源码。核心逻辑在 build.rs:
- 源码目录解析优先级(
resolve_bwrap_source_dir,第 84–106 行):环境变量CODEX_BWRAP_SOURCE_DIR指向的现有 checkout 优先,否则回落到codex-rs/vendor/bubblewrap; - 通过
pkg-config探测 libcap(第 37–40 行),探测失败即构建失败——这与 NEWS 中 bubblewrap 依赖 libcap 的事实一致,main.rs里的降级提示也写明 "libcap headers must be available via pkg-config"; - 用
cc编译 4 个 C 文件(bubblewrap.c、bind-mount.c、network.c、utils.c),关键编译宏是-Dmain=bwrap_main(第 59–61 行):把 C 侧的main改名,让 Rust 侧的薄包装成为真正的程序入口; - 生成最小
config.h,内容即PACKAGE_STRING "bubblewrap built for Codex"(第 45–49 行),bwrap --version等输出因此能表明来源; - 非 Linux 目标或设置了
CODEX_SKIP_BWRAP_BUILD时直接跳过,仅输出cfg(bwrap_available)检查声明,不做编译。
Rust 入口 src/main.rs 只有约 45 行:Linux 且 bwrap_available 时声明 extern "C" fn bwrap_main(argc, argv),把 std::env::args_os() 转成 NUL 结尾的 argv 指针数组后调用(第 27 行),并用其返回值作为进程退出码;未启用时直接 panic 并打印三条排查提示(目标 OS 必须是 Linux、libcap 头文件须可被 pkg-config 发现、vendored 源码位置)。也就是说,cargo build 得到的 bwrap 二进制就是上游 C 实现的直接链接产物,版本行为与 NEWS 中 0.11.x 的描述严格对应。
2. Bazel 构建路径:cc_library + filegroup
Bazel 侧不走 Cargo 的 build.rs(build_script_enabled = False),而是用原生规则拼接,见 codex-rs/bwrap/BUILD.bazel:
cc_library(name = "bwrap-ffi")直接以//codex-rs/vendor:bubblewrap_c_sources为srcs(即 vendor/BUILD.bazel 中glob(["bubblewrap/*.c"])的 filegroup),copts为-D_GNU_SOURCE与-Dmain=bwrap_main,deps = ["@libcap"],且target_compatible_with = ["@platforms//os:linux"]——与 Cargo 路径的编译宏、平台限制完全对齐;codex_rust_crate通过select在 Linux 上追加:bwrap-ffi依赖并注入--cfg=bwrap_available,非 Linux 平台则该 cfg 不存在,main.rs自动落入 panic 分支。
两条路径殊途同归:同一个 vendored 源码树,同一套改名 main 的手法,同一份 libcap 依赖,保证 Cargo 与 Bazel 两种发行方式下 bwrap 的行为一致。
与运行时的关系:bundled bwrap 在 codex-linux-sandbox 中的角色
NEWS 里 0.11.1 的 userns/pidns fd 修复、0.11.0 的 EINTR 处理,最终都服务于一个事实:本仓库的沙箱层几乎全程通过 bwrap 的用户/ PID/网络命名空间能力工作。codex-rs/linux-sandbox/README.md 给出了选择策略与默认行为(引自原文要点):
- Bubblewrap 是默认的文件系统沙箱。优先使用
PATH上(当前工作目录之外)找到的系统bwrap;若版本过旧不支持--argv0,会走一条不含--argv0的内层 re-exec 兼容路径;若bwrap缺失,则回落到随产品分发的 bundledcodex-resources/bwrap——即上一节构建出的 vendored 二进制; - bwrap 缺失或无法创建 user namespace 时,启动阶段即给出警告,而不是等到运行时才失败。这与 0.11.1 在 CI 中主动启用 userns 的内部改动形成呼应:userns 支持是整条沙箱链路的先决条件;
- 具体挂载与隔离方式:默认以
--ro-bind / /让文件系统整体只读,可写根目录用--bind <root> <root>分层叠加;受保护子路径(如.git、.codex)再以--ro-bind恢复只读;显式--unshare-user与--unshare-pid隔离用户/PID 命名空间,网络受限且无代理路由时追加--unshare-net;默认--proc /proc挂载全新/proc(严格容器环境可用--no-proc跳过);bubblewrap 激活时在进程内施加PR_SET_NO_NEW_PRIVS与 seccomp 网络过滤器; - 平台边界:WSL2 走正常 Linux bubblewrap 路径;WSL1 因无法创建所需用户命名空间,Codex 会在进入 bubblewrap 路径前直接拒绝需要沙箱的 shell 命令。
此外 0.11.0 新增的 --overlay 系列选项在本仓库当前沙箱实现中未见直接使用(README 描述的挂载组合仍以 --ro-bind/--bind 为主),可视为上游提供的能力储备而非现有代码路径。
安全视角小结:为什么"默认无 setuid"对本仓库至关重要
把 NEWS 的三个版本串起来看,有一条清晰的主线:bubblewrap 0.11.x 系列持续收缩 setuid 攻击面——0.11.2 修复 setuid 模式下的 CVE-2026-41163、并让 -Dsupport_setuid=false(默认)构建出的二进制拒绝以 setuid 身份运行;0.11.0 的 overlay 功能也声明在 setuid 安装下不可用。而本仓库的运行时恰好只依赖用户命名空间路径(--unshare-user + userns 可用性检测 + WSL1 直接拒绝),构建侧又始终编译非 setuid 的二进制。可以推断:对于跟随本仓库构建产物的用户,NEWS 中所有"only affect setuid mode"的条目基本不构成实际风险,这正是 0.11.2 推荐构建方式与项目沙箱策略的天然契合。
延伸阅读(仓库内路径)
- 变更日志本体:codex-rs/vendor/bubblewrap/NEWS.md
- 构建选项定义:codex-rs/vendor/bubblewrap/meson_options.txt
- Cargo 构建脚本与 Rust 入口:codex-rs/bwrap/build.rs、codex-rs/bwrap/src/main.rs
- Bazel 集成:codex-rs/bwrap/BUILD.bazel、codex-rs/vendor/BUILD.bazel
- 沙箱运行机制:codex-rs/linux-sandbox/README.md
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00