mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-04-06 11:13:38 +00:00
fix(sandbox): mount media directory read-only inside bwrap sandbox
This commit is contained in:
parent
cef0f3f988
commit
9f96be6e9b
@ -8,14 +8,19 @@ and register it in _BACKENDS below.
|
||||
import shlex
|
||||
from pathlib import Path
|
||||
|
||||
from nanobot.config.paths import get_media_dir
|
||||
|
||||
|
||||
def _bwrap(command: str, workspace: str, cwd: str) -> str:
|
||||
"""Wrap command in a bubblewrap sandbox (requires bwrap in container).
|
||||
|
||||
Only the workspace is bind-mounted read-write; its parent dir (which holds
|
||||
config.json) is hidden behind a fresh tmpfs.
|
||||
config.json) is hidden behind a fresh tmpfs. The media directory is
|
||||
bind-mounted read-only so exec commands can read uploaded attachments.
|
||||
"""
|
||||
ws = Path(workspace).resolve()
|
||||
media = get_media_dir().resolve()
|
||||
|
||||
try:
|
||||
sandbox_cwd = str(ws / Path(cwd).resolve().relative_to(ws))
|
||||
except ValueError:
|
||||
@ -33,6 +38,7 @@ def _bwrap(command: str, workspace: str, cwd: str) -> str:
|
||||
"--tmpfs", str(ws.parent), # mask config dir
|
||||
"--dir", str(ws), # recreate workspace mount point
|
||||
"--bind", str(ws), str(ws),
|
||||
"--ro-bind-try", str(media), str(media), # read-only access to media
|
||||
"--chdir", sandbox_cwd,
|
||||
"--", "sh", "-c", command,
|
||||
]
|
||||
|
||||
@ -92,6 +92,22 @@ class TestBwrapBackend:
|
||||
assert "/bin" in try_targets
|
||||
assert "/etc/ssl/certs" in try_targets
|
||||
|
||||
def test_media_dir_ro_bind(self, tmp_path, monkeypatch):
|
||||
"""Media directory should be read-only mounted inside the sandbox."""
|
||||
fake_media = tmp_path / "media"
|
||||
fake_media.mkdir()
|
||||
monkeypatch.setattr(
|
||||
"nanobot.agent.tools.sandbox.get_media_dir",
|
||||
lambda: fake_media,
|
||||
)
|
||||
ws = str(tmp_path / "project")
|
||||
result = wrap_command("bwrap", "ls", ws, ws)
|
||||
tokens = _parse(result)
|
||||
|
||||
try_indices = [i for i, t in enumerate(tokens) if t == "--ro-bind-try"]
|
||||
try_pairs = {(tokens[i + 1], tokens[i + 2]) for i in try_indices}
|
||||
assert (str(fake_media), str(fake_media)) in try_pairs
|
||||
|
||||
|
||||
class TestUnknownBackend:
|
||||
def test_raises_value_error(self, tmp_path):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user