Codex 源码解析 · 第 23 讲
Codex 源码解析系列 第 23 讲:Landlock + Seatbelt 双引擎 基于 OpenAI Codex 源码 · 2026-10-16 💡 本讲一句话: 第 22 讲的 bwrap 只负责"文件系统视图",真正锁死系统调用和文件权限的是两个内核级引擎——Linux 的 Landlock+seccomp、macOS 的 Seatbelt。读完你能看懂:为什么 seccomp 要留一个 recvfrom 例外、为什么 macOS 策略里 deny 必须放最后、以及 rename 是怎么被当成攻击向量防住的。 一、定位:sandboxing crate 里的两个"内核级"引擎 第 21 讲拆过 SandboxManager (决策层),第 22 讲拆过 bwrap (Linux 文件系统视图)。但"视图"只是把目录藏起来,真正在内核层面执行访问控制的是两套机制:Linux 侧的 Landlock + seccomp ( linux-sandbox/src/landlock.rs ,370 行),macOS 侧的 Seatbelt ( sandboxing/src/seatbelt.rs ,1075 行 + 4 个 .sbpl 策略文件)。先看 crate 的模块划分——平台差异在编译期就切掉了: 📄 codex-rs/sandboxing/src/lib.rs (第 1-14 行) #[cfg(target_os = "linux")] // 编译期开关:bwrap 模块只在 Linux 存在,其他平台连这段代码都看不到 mod bwrap; // bubblewrap 挂载命名空间沙箱——第 22 讲的主角 mod denial; // 从错误输出里识别"这是不是沙箱拒绝",喂给审批流做归因 pub mod landlock; // Landlock + seccomp 原语:Linux legacy/备用路径与网络锁(本讲主角之一) mod manager; // SandboxManager:按平台+策略决定用哪个后端——第 21 讲的主角 pub mod policy_transforms; // 把权限声明转换成具体沙箱参数 #[cfg(target_os = "macos")] // Seatbelt 是 macOS 专属,其他平台编译期直接剔除 pub mod seatbelt; // 生成 .sbpl 策略并用 sandbox-exec 包裹命令(本讲主角之二) mod spawn; // 统一的进程启动入口 mod terminal_queries; // 终端能力查询 mod violation; // 记录沙箱违规事件,反馈给 Guardian/审批流 mod windows; // Windows restricted token 沙箱 为什么这样设计: 注意 landlock 是 pub mod (跨平台可见),而 seatbelt / bwrap 都挂在 #[cfg] 后面——因为 landlock.rs 里除了 Landlock 文件系统规则,还装着 跨平台复用的 seccomp 网络过滤器 (seccomp 是 Linux 系统调用,但它的"模式决策逻辑"被 core 层引用)。用编译期 cfg 而不是运行时 if,意味着 macOS 二进制里根本不存在 bwrap 代码——攻击面在构建时就消失了。 二、Linux 侧:限制施加在"当前线程",让子进程继承 apply_permission_profile_to_current_thread 是整个 Linux 沙箱的"收口函数"——第 22 讲里 bwrap 内层重入后调用的就是它。它的核心决策逻辑值得逐行看: 📄 codex-rs/linux-sandbox/src/landlock.rs (第 49-77 行) let (file_system_sandbox_policy, network_sandbox_policy) = // 把统一权限档案拆成文件系统/网络两份运行时策略 permission_profile.to_runtime_permissions(); // 一次转换,后面所有分支都基于这两份策略 let networ…
阅读全文:Codex 源码解析 第 23 讲