Skip to content

fix(extension-agent): fallback when bwrap is unusable#801

Merged
dingyi222666 merged 2 commits intoChatLunaLab:v1-devfrom
springtiming:fix/agent-local-bwrap-fallback
Mar 28, 2026
Merged

fix(extension-agent): fallback when bwrap is unusable#801
dingyi222666 merged 2 commits intoChatLunaLab:v1-devfrom
springtiming:fix/agent-local-bwrap-fallback

Conversation

@springtiming
Copy link
Copy Markdown
Contributor

Fixes #799

问题

在 Linux 环境下,chatluna-agent 的 local backend 只要检测到 bwrap 存在,就会无条件为命令套上 bubblewrap sandbox。

这在 Ubuntu 24.04 的 AppArmor / unprivileged user namespace 限制环境里会导致 local 命令整体失败,典型报错包括:

  • bwrap: Can't mount proc on /newroot/proc: Operation not permitted
  • bwrap: setting up uid map: Permission denied

根因

问题不在于 bwrap 是否安装,而在于 bwrap 在当前宿主环境中是否真的可用

Ubuntu 24.04 默认启用了对 unprivileged user namespace 的限制。此时即使系统里已经安装了 bwrap,它也可能因为 AppArmor / userns 限制而无法初始化 sandbox,最终把 local backend 的命令执行一并打死。

修改方式

本 PR 只修改了一个文件:

  • packages/extension-agent/src/computer/backends/local/sandbox.ts

修改内容:

  1. 保留现有行为:
    • Windows 不使用 bwrap
    • bwrap 不存在时直接返回原命令
  2. 新增一层最小 runtime probe:
    • 当检测到 bwrap 存在时,先执行一次最小 bwrap 探测
    • 探测成功才继续返回包装后的 sandbox 命令
    • 探测失败则回退到原命令
  3. 增加进程内缓存,避免每次执行都重复探测

也就是说,这个改动把原来的:

  • bwrap 不存在 => 裸跑

扩展为:

  • bwrap 不存在 => 裸跑
  • bwrap 存在但当前环境不可用 => 裸跑
  • bwrap 存在且可用 => 继续使用 sandbox

设计取舍

这是一个 runtime mitigation,不是系统级根治。

它不试图让 ChatLuna 管理宿主机的 AppArmor profile 或 sysctl,也不改变 bwrap 正常可用环境下的既有行为。目标只是避免 local backend 因为“检测到 bwrap 已安装,但实际上无法初始化”而直接失效。

验证方式

仓库当前没有自动化测试框架,因此本次验证为定向手工验证。

1. 本地函数级验证

  • 真实可用 bwrap
    • wrapCommandWithSandbox() 继续返回带 bwrap 的包装命令
  • 假失败 bwrap
    • 模拟返回 mount/proc 权限错误
    • wrapCommandWithSandbox() 返回原始命令

2. LocalComputerSession.execute() 验证

  • 假失败 bwrap 环境:
    • execute('printf ok') 成功,stdout=ok
  • 真实 bwrap 环境:
    • execute('printf ok') 仍成功,stdout=ok

3. 真实 Ubuntu 24.04 + AppArmor VM 对照验证

在本地完整 Ubuntu 24.04 VM 中进行了原始版本与补丁版本对照验证:

  • kernel.apparmor_restrict_unprivileged_userns=1
    • 原始版本:仍返回 bwrap 包装命令并失败
    • 补丁版本:回退为原命令并成功执行
  • kernel.apparmor_restrict_unprivileged_userns=0
    • 原始版本:bwrap 正常执行
    • 补丁版本:同样继续走 bwrap,不破坏正常路径

对照结果说明:

  • 补丁确实只在 bwrap 不可用时回退
  • 不会破坏 bwrap 正常可用路径

风险边界

  • 该补丁属于 fail-open 缓解,不是 fail-closed 设计
  • 这与当前已有语义一致:原实现本来就在“系统没有 bwrap”时直接返回原命令
  • 如果未来项目希望 sandbox 不可用时直接拒绝执行,应单独讨论为新的策略变更,而不是混入这次 bugfix

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 51f0b54c-0621-4cf2-a3c6-4df765358cef

📥 Commits

Reviewing files that changed from the base of the PR and between fd27b52 and 299a2c9.

📒 Files selected for processing (1)
  • packages/extension-agent/src/computer/backends/local/sandbox.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/extension-agent/src/computer/backends/local/sandbox.ts

Walkthrough

在本次变更中,非 Windows 平台的 wrapCommandWithSandbox 强制要求 bwrap 可执行路径存在并新增启动探测:对 bwrap 运行一次最小化子进程探测并在失败时抛出错误;探测结果按 bwrap 路径缓存以避免重复检查。导入了 spawnSync,并新增了探测辅助逻辑和缓存。

Changes

Cohort / File(s) Summary
沙箱能力与探测逻辑
packages/extension-agent/src/computer/backends/local/sandbox.ts
修改 wrapCommandWithSandbox 行为:若 which.sync('bwrap') 无返回则抛错(不再静默返回原命令);新增 getBubblewrapError 启动探测(使用 spawnSync 运行最小 bwrap 调用),在探测失败时抛出错误;新增 BWRAP_PROBE_CACHE 以缓存探测结果并避免重复子进程调用。注意:控制流由“可选回退”变为“缺失或探测失败时抛错”,需要关注调用方对该异常的处理。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🐰 我是小兔去探路,轻敲 bwrap 的门,
若门未应或回声冷,便把问题轻声陈。
缓存探针记路径,别再重复去奔波,
报错明白好追踪,开发调试更从容。

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确描述了本 PR 的核心改动:添加 bwrap 不可用时的回退机制。
Description check ✅ Passed PR 描述详细说明了问题根因、修改内容、设计决策和验证方式,与代码改动完全相关。
Linked Issues check ✅ Passed 代码改动完全满足 #799 的需求:检测 bwrap 不可用时回退为原命令执行,避免权限错误导致命令失败。
Out of Scope Changes check ✅ Passed 所有改动仅涉及 sandbox.ts 中的 bwrap 可用性探测与回退逻辑,与 #799 的需求完全对应,无超出范围的改动。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a functional check for Bubblewrap availability before it is used for sandboxing, including a caching mechanism for the probe results. The review feedback identified a risk of process crashes due to missing error handling in the probe function and noted that temporary directories created during the check were not being cleaned up.

Comment thread packages/extension-agent/src/computer/backends/local/sandbox.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/extension-agent/src/computer/backends/local/sandbox.ts (1)

115-118: 建议在 bwrap 探测失败时添加日志记录。

canUseBubblewrap 返回 false 时,命令将以无沙箱模式运行(fail-open 设计)。这是一个安全相关的行为变化,用户应该知道沙箱被禁用了。缺少日志会导致用户无法感知系统正在以较低安全级别运行。

♻️ 建议添加警告日志

需要在文件顶部添加 logger 导入(根据项目现有模式),然后:

     if (!canUseBubblewrap(bwrap, tmp)) {
+        // Consider logging: logger.warn('bwrap detected but unusable, running command without sandbox')
         return command
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/extension-agent/src/computer/backends/local/sandbox.ts` around lines
115 - 118, When canUseBubblewrap(bwrap, tmp) returns false in sandbox.ts the
code currently silently falls back to unsandboxed execution; import the
project's logger used elsewhere in this module (add the same logger import
pattern at the top of the file) and add a warning log immediately before
returning the unsandboxed command (include context like bwrap path/flags and tmp
directory and mention that bubblewrap detection failed and execution will be
unsandboxed). Keep the return(command) behavior (fail-open) but ensure the
warning is logged using the module's logger so operators can see the reduced
security mode.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/extension-agent/src/computer/backends/local/sandbox.ts`:
- Around line 164-198: The canUseBubblewrap probe can throw from fs.mkdirSync
which would bubble up and break the fail-open design; update the
canUseBubblewrap function to catch exceptions around fs.mkdirSync (and any
filesystem prep) and on error log/debug if desired and return false so the probe
fails closed to sandbox usage without throwing, preserving existing caching via
BWRAP_PROBE_CACHE and keeping the rest of the spawnSync logic unchanged.

---

Nitpick comments:
In `@packages/extension-agent/src/computer/backends/local/sandbox.ts`:
- Around line 115-118: When canUseBubblewrap(bwrap, tmp) returns false in
sandbox.ts the code currently silently falls back to unsandboxed execution;
import the project's logger used elsewhere in this module (add the same logger
import pattern at the top of the file) and add a warning log immediately before
returning the unsandboxed command (include context like bwrap path/flags and tmp
directory and mention that bubblewrap detection failed and execution will be
unsandboxed). Keep the return(command) behavior (fail-open) but ensure the
warning is logged using the module's logger so operators can see the reduced
security mode.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e3a0320d-8b4b-46ed-9140-aa65b13ec4c1

📥 Commits

Reviewing files that changed from the base of the PR and between 0afb139 and fd27b52.

📒 Files selected for processing (1)
  • packages/extension-agent/src/computer/backends/local/sandbox.ts

Comment thread packages/extension-agent/src/computer/backends/local/sandbox.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd27b5272a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/extension-agent/src/computer/backends/local/sandbox.ts Outdated
@dingyi222666
Copy link
Copy Markdown
Member

hyw,直接关掉 bwrap 吗?那沙箱怎么办

@dingyi222666 dingyi222666 merged commit c079132 into ChatLunaLab:v1-dev Mar 28, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug]linux上chatluna-agent使用local后端在模型调用时产生bwrap权限报错

2 participants