Skip to content

沙箱系统 — 练习

练习 1:分析 Landlock 规则配置

阅读 codex-rs/sandboxing/src/ 中的 Landlock 相关代码,分析文件系统权限规则的定义方式。

参考答案

Landlock 的规则配置在 sandboxing/src/ 目录中分为几个层次:

  1. 规则定义:在 landlock 模块中,文件系统权限通过 Landlock LSM 的 landlock_rules 定义。核心是区分三类访问:

    • 可读写access-fs):仅 workspace 目录及其子目录,代理可在此创建、修改、删除文件
    • 只读access-fs read-only):系统目录(/usr/lib/bin)、Cargo 缓存等,代理可读取但不能修改
    • 完全禁止:敏感路径(~/.ssh~/.gnupg~/.aws),代理完全无法访问
  2. Bubblewrap 集成bwrap 模块使用 Bubblewrap 创建新的 mount namespace,将上述 Landlock 规则映射为 --bind(读写)、--ro-bind(只读)、--tmpfs(临时文件系统)等挂载参数。

  3. 辅助二进制linux-sandbox/src/lib.rsrun_main() 是独立的沙箱入口,它首先在进程内应用 seccomp 限制,然后执行被包装的命令。launcher 模块负责启动这个辅助二进制。

  4. 权限配置SandboxTransformRequest 中的 sandbox_policy_cwd 字段指定 workspace 根目录,additional_permissions 列表包含用户审批后临时授予的额外权限。

这个设计确保了即使代理生成了恶意命令,也无法越出 workspace 目录的边界。

练习 2:对比 Landlock 和 Seatbelt 实现

对比 Linux 和 macOS 两个平台的沙箱实现,总结共性和差异。

参考答案

共性

  • 两者都通过 SandboxManager::transform() 统一接口调用,对外暴露相同的 SandboxExecRequest
  • 都支持 additional_permissions 动态扩展权限
  • 都通过 ExecPolicy 策略层在命令执行前评估权限(Allow/Prompt/Forbidden)
  • 都限制了文件系统访问范围,确保代理只能操作 workspace 目录

差异

维度Landlock (Linux)Seatbelt (macOS)
底层机制LSM 内核模块 + seccompsandbox-exec 系统调用
隔离方式Bubblewrap 命名空间 + Landlock 文件规则plist 声明式规则
辅助二进制需要 codex-linux-sandbox 独立进程不需要辅助进程
网络隔离通过 NetworkSandboxPolicy 控制通过 Seatbelt 规则控制
配置格式Rust 代码中的规则构建动态生成的 plist
错误处理SandboxTransformError::MissingLinuxSandboxExecutableSandboxTransformError::SeatbeltUnavailable

核心洞察:SandboxManager 的设计让平台差异对上层透明。select_initial() 根据 SandboxablePreference(Auto/Require/Forbid)和当前平台自动选择合适的沙箱类型,调用者无需关心底层实现。

练习 3:测试沙箱边界

分析代理在沙箱限制下的行为边界,哪些操作被允许、哪些被拒绝。

参考答案

沙箱边界由 ExecPolicy 和平台沙箱共同定义,形成两层过滤:

第一层:ExecPolicy 策略评估Policy::check()

  • 自动允许(Allow):常见的只读命令(lscatgrepgit status)、构建工具(cargo buildnpm install 在 workspace 内)、测试运行
  • 需要审批(Prompt):文件删除(rm)、系统包安装(apt-getbrew)、网络请求(curlwget
  • 直接拒绝(Forbidden):明确的危险操作、覆盖关键系统文件

第二层:平台沙箱隔离

  • 文件系统:代理只能读写 workspace 目录内的文件;系统目录只读;敏感目录(~/.ssh~/.gnupg)完全不可见
  • 网络:通过 NetworkRule 控制可访问的域名,默认限制为必要的 API 端点
  • 进程:Linux 上通过 PID namespace 隔离,子进程继承限制

边界测试场景

  • cat /etc/passwd → ExecPolicy Allow + 沙箱只读 → ✅ 成功
  • echo test > ~/outside.txt → ExecPolicy Allow + 沙箱文件系统拒绝 → ❌ 失败
  • rm -rf / → ExecPolicy Forbidden → ❌ 直接拒绝
  • ssh user@host → 沙箱阻止 ~/.ssh 访问 → ❌ 无法认证

这种双重防御确保了即使某一层被绕过,另一层仍然提供保护。

拓展挑战

  • 阅读 SandboxManager::transform() 的完整实现,理解命令包装的具体步骤
  • 分析 linux-sandbox/src/lib.rs 中 seccomp 规则的定义
  • 对比 SandboxablePreference::Auto 在不同平台上的默认选择逻辑
  • 追踪 additional_permissions 从用户审批到沙箱应用的完整路径