anthropics / anthropics/sandbox-runtime

Linux bwrap: allowWrite paths become read-only when allowRead parent overlaps under a denyRead region

Abierto
#263 0 comentarios 3 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
TypeScript
Estrellas
5.2k
Forks
439
Merge medio
2 d 9 min
PR fusionados (30 d)
13

Descripción

## Summary

When the filesystem config specifies `denyRead` and `allowRead` on overlapping regions, `allowWrite` paths nested under an `allowRead` ancestor silently become read-only. The sandbox command fails with `EROFS` or `Read-only file system` on write operations that should be permitted.

## Reproduction

### Config

```typescript
import { wrapCommandWithSandboxLinux } from './src/sandbox/linux-sandbox-utils.js'

const wrapped = await wrapCommandWithSandboxLinux({
command: 'touch /tmp/srt-test/workspace/project/hello.txt',
needsNetworkRestriction: false,
readConfig: {
denyOnly: ['/tmp/srt-test'],
allowWithinDeny: ['/tmp/srt-test/workspace'],
},
writeConfig: {
allowOnly: ['/tmp/srt-test/workspace/project'],
denyWithinAllow: [],
},
})
```

### Setup

```bash
mkdir -p /tmp/srt-test/workspace/project
```

### Command

```bash
eval "$wrapped"
# → touch: cannot touch '/tmp/srt-test/workspace/project/hello.txt': Read-only file system
```

## Expected vs Actual Behavior

**Expected:** `/tmp/srt-test/workspace/project/hello.txt` is created successfully. `allowWrite` paths should remain writable regardless of `allowRead` configuration.

**Actual:** The write fails with `Read-only file system`. The `allowWrite` path is silently downgraded to read-only.

## Root Cause

In `generateFilesystemArgs()` (`src/sandbox/linux-sandbox-utils.ts`), when processing a `denyRead` directory, the function:

1. Mounts `--tmpfs` over the denied path (wiping everything under it)
2. Re-binds `allowWrite` paths with `--bind` (writable)
3. Re-allows `allowRead` paths with `--ro-bind` (read-only)

Since bwrap processes mounts in argument order, a later mount on a parent path **hides** earlier mounts on child paths. When `allowRead` is a parent of `allowWrite`, step 3's `--ro-bind` overwrites step 2's `--bind`:

```
--tmpfs /tmp/srt-test
--bind /tmp/srt-test/workspace/project /tmp/srt-test/workspace/project
--ro-bind /tmp/srt-test/workspace /tmp/srt-test/workspace ← HIDES the --bind above
```

## Fix

Swap the loop order: emit `allowRead` ro-binds **before** `allowWrite` re-binds. Write mounts then layer on top and remain writable.

## Environment

- **OS:** Linux (any distro with bubblewrap)
- **bwrap version:** any (mount ordering is fundamental to bwrap's design)
- **sandbox-runtime:** current `main`

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.