Skip to content

沙箱系统 — 代码走读

codex-rs/sandboxing/src/manager.rs — 沙箱管理器

SandboxManager 是无状态的平台沙箱抽象层,提供两个核心方法:

rust
pub struct SandboxManager;  // 无状态,Default

impl SandboxManager {
    /// 根据 preference 和当前平台选择沙箱类型
    pub fn select_initial(preference: SandboxablePreference) -> Result<SandboxType, SandboxTransformError> {
        match preference {
            SandboxablePreference::Auto => Ok(get_platform_sandbox()),
            SandboxablePreference::Require => Ok(get_platform_sandbox()),
            SandboxablePreference::Forbid => Ok(SandboxType::None),
        }
    }

    /// 将原始命令包装为沙箱执行请求
    pub fn transform(req: SandboxTransformRequest) -> Result<SandboxExecRequest, SandboxTransformError>
}

核心类型定义:

类型说明
SandboxTypeNone / MacosSeatbelt / LinuxSeccomp / WindowsRestrictedToken
SandboxablePreferenceAuto(默认)/ Require(强制)/ Forbid(禁用)
SandboxCommand{ program, args, cwd, env, additional_permissions }
SandboxExecRequest{ command, cwd, env, network, sandbox, ... }
SandboxTransformRequest{ command, permissions, sandbox, enforce_managed_network, ... }
SandboxTransformErrorMissingLinuxSandboxExecutable / Wsl1UnsupportedForBubblewrap / SeatbeltUnavailable

get_platform_sandbox() 函数根据编译目标返回平台默认沙箱类型:

rust
fn get_platform_sandbox() -> SandboxType {
    #[cfg(target_os = "macos")] { SandboxType::MacosSeatbelt }
    #[cfg(target_os = "linux")] { SandboxType::LinuxSeccomp }
    #[cfg(target_os = "windows")] { SandboxType::WindowsRestrictedToken }
}

codex-rs/sandboxing/src/seatbelt/ — macOS Seatbelt 实现

Seatbelt 模块将 SandboxCommand 转换为 sandbox-exec 调用:

原始命令 → 生成 plist 规则 → sandbox-exec -p <rules> <command>

关键实现步骤:

  1. 根据 workspace 路径和 additional_permissions 生成 plist 规则
  2. 允许 workspace 目录读写,系统目录只读
  3. 禁止访问敏感路径(~/.ssh~/.gnupg 等)
  4. 通过 sandbox-exec 命令在沙箱中执行原始命令
  5. 子进程自动继承沙箱限制

codex-rs/sandboxing/src/bwrap/ — Linux Bubblewrap 实现

bwrap 模块构建 Bubblewrap 命令行参数:

原始命令 → 构建 bwrap 参数 → codex-linux-sandbox --bwrap-args ... -- <command>

关键 bwrap 参数:

  • --bind <workspace> <workspace>:workspace 目录读写挂载
  • --ro-bind /usr /usr:系统目录只读挂载
  • --dev /dev:设备目录
  • --proc /proc:proc 文件系统
  • --tmpfs /tmp:临时文件系统
  • --unshare-pid:PID namespace 隔离
  • --die-with-parent:父进程退出时子进程自动终止

codex-rs/linux-sandbox/src/lib.rs — Linux 沙箱辅助二进制

codex-linux-sandbox 是一个独立的二进制,在沙箱内执行:

rust
pub fn run_main() -> ! {
    // 1. 应用 seccomp 过滤器
    // 2. 执行被包装的命令
    // 3. 传递退出码
}

内部模块:

  • landlock:Landlock LSM 规则应用
  • bwrap:Bubblewrap 命令构建
  • launcher:沙箱进程启动器
  • exec_util:执行工具函数
  • proxy_routing:网络代理路由

codex-rs/execpolicy/src/policy.rs — 执行策略引擎

Policy struct 实现命令权限评估:

rust
pub struct Policy {
    rules_by_program: MultiMap<String, RuleRef>,     // 按程序名索引的规则
    network_rules: Vec<NetworkRule>,                  // 网络规则
    host_executables_by_name: HashMap<String, Arc<[AbsolutePathBuf]>>,
}

impl Policy {
    pub fn check(&self, cmd: &str, heuristics_fallback: bool) -> Evaluation
    pub fn add_prefix_rule(&mut self, rule: PrefixRule)
    pub fn add_network_rule(&mut self, rule: NetworkRule)
    pub fn merge_overlay(&mut self, other: &Policy)
    pub fn get_allowed_prefixes(&self) -> Vec<&str>
}

pub struct Evaluation {
    pub decision: Decision,
    pub matched_rules: Vec<RuleMatch>,
}

pub enum Decision { Allow, Forbidden, Prompt }

评估流程:

  1. check() 接收命令字符串
  2. rules_by_program 中查找匹配的规则
  3. 对所有匹配规则取最高权限(Decision 的偏序:Forbidden > Prompt > Allow)
  4. 返回 Evaluation 包含最终决策和匹配的规则列表

codex-rs/sandboxing/src/lib.rs — 模块导出

rust
pub mod bwrap;
pub mod landlock;
pub mod manager;
pub mod policy_transforms;
pub mod seatbelt;

pub use manager::*;
pub use policy_transforms::*;

导出的核心 API:

  • SandboxCommandSandboxExecRequestSandboxManagerSandboxType
  • compatibility_sandbox_policy_for_permission_profile()
  • get_platform_sandbox()
  • find_system_bwrap_in_path()system_bwrap_warning()

关键函数索引

函数/模块文件路径说明
SandboxManager::transform()sandboxing/src/manager.rs命令包装为沙箱执行
SandboxManager::select_initial()sandboxing/src/manager.rs选择平台沙箱类型
get_platform_sandbox()sandboxing/src/manager.rs获取当前平台默认沙箱
Policy::check()execpolicy/src/policy.rs命令权限评估
Policy::add_prefix_rule()execpolicy/src/policy.rs添加前缀规则
Policy::merge_overlay()execpolicy/src/policy.rs合并策略覆盖
run_main()linux-sandbox/src/lib.rsLinux 沙箱辅助入口
seatbelt 模块sandboxing/src/seatbelt/macOS Seatbelt 实现
bwrap 模块sandboxing/src/bwrap/Linux Bubblewrap 实现
landlock 模块sandboxing/src/landlock/Landlock LSM 规则
load_exec_policy()core/src/lib.rs从配置加载执行策略