返回资讯中心
外部精选
软件工程
#开发者实时流

Sandboxable port of busybox for agents in Go

Busybox utilities in Go, compilable to WebAssembly via TinyGo for sandboxed execution in AI agents. Produces a unified multi-call busybox binary and standalone applet binaries under cmd/.

Hacker News 最新jcbhmr2026/10/22 · 23 天前17 分钟阅读

以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。

Busybox utilities in Go, compilable to WebAssembly via TinyGo for sandboxed execution in AI agents. Produces a unified multi-call busybox binary and standalone applet binaries under cmd/.

Reference target: BusyBox v1.35.0 (Debian 1:1.35.0-4+b7) Test suite: 387/387 (100%)

Quick start

Applets

Test results

Shell

Text processing

Testing

Structure

Sandboxing

Development

Quick start

make setup-toolchain # Go + TinyGo via Homebrew make install-dev # linters, security tools make build # native binary → _build/busybox make build-wasm # WASM binary → _build/busybox.wasm (4.7MB) make build-wasm-optimized # size-optimised → _build/busybox.wasm (2.0MB) make test

./_build/busybox sed 's/foo/bar/g' input.txt ln -s _build/busybox _build/grep && ./_build/grep -i pattern file.txt wasmtime --dir=. _build/busybox.wasm cat file.txt

Applets

57 applets, all with full Godoc (including flag lists).

start-stop-daemon, top, and 14 other OS-dependent applets return stubs under WASM (see Sandboxing).

BusyBox reference suite — 387/387

Runs via /bin/bash with ECHO="echo".

Old-style (directory-based) — 79/79: cat, cp, cut, echo, find, gzip, ls, mkdir, mv, pwd, rm, rmdir, tail, tr, wc, wget.

Category Pass Category Pass

ash-alias 5/5 ash-quoting 24/24

ash-arith 6/6 ash-read 10/10

ash-comm 3/3 ash-redir 27/27

ash-getopts 8/8 ash-signals 22/22

ash-glob 10/10 ash-standalone 6/6

ash-heredoc 25/25 ash-vars 69/69

ash-invert 3/3 ash-z_slow 3/3

ash-misc 99/99

ash-parsing 35/35 Total 349/349

Shell (ash)

Near-complete POSIX shell. Pipelines, redirections (< > >> 2> >& <& >&-), control flow (if/elif/else/fi, while, until, for, case/esac), command substitution ($(...), backticks), arithmetic ($(())), functions, parameter expansion (${VAR:-default}, ${#VAR}, ${VAR##pattern}), 25+ builtins, background jobs (&, jobs/fg/wait), here-documents, subshells, traps/signals.

sed — 92/92

BRE/ERE (-E/-r), backreferences (\1–\9), all standard commands (s d p q a i c y = l r w h H g G x N P D b t T), addresses (line, $, regex, ranges, first~step, 0,/regex/), in-place editing (-i), escape sequences (\n \t \r), labels/branches, multiple expressions (-e, -f), --version.

Per-line trailing-newline tracking via noNLLines map[int]bool — suppresses final \n when the last output line originated from an input line lacking a trailing newline. The w command truncates output files similarly via wfileLastLine.

-u -U N -b -w -B -a -q -r -N. The -B implementation post-filters blank-only hunks rather than stripping blanks pre-diff.

-E -F -i -v -c -l -L -n -h -H -o -q -r -w -x -s -e -f. Invokable as egrep/fgrep.

Full parser/evaluator: BEGIN/END, patterns, arrays, control flow, 30+ builtins, printf/sprintf, getline, regex, I/O redirection.

Every applet has at least one fuzz test. The 22 most complex have multi-function coverage:

Safety filters prevent non-termination during fuzzing:

make test # unit tests make test-race # with race detector make coverage # with coverage

fuzz seeds only (quick)

go test ./pkg/applets/sed -run='Fuzz' -count=1

actual fuzzing (10s)

go test ./pkg/applets/sed -run='^$' -fuzz='^FuzzSedExpr$' -fuzztime=10s

all fuzz seeds

for d in pkg/applets/*/; do go test ./$d -run='Fuzz' -count=1 -timeout 30s; done

Structure

go-busybox/ ├── cmd/ # standalone entry points (51 + busybox) │ └── busybox/ # multi-call dispatcher ├── pkg/ │ ├── applets/ # 57 applet packages │ │ ├── ash/ # shell (5,700+ lines) │ │ ├── sed/ # stream editor (1,200+ lines) │ │ ├── procutil/ # shared process helpers │ │ └── ... │ ├── core/ # shared: fs/, archiveutil/, headtail, textutil │ ├── integration/ # BusyBox comparison tests │ ├── sandbox/ # capability-based sandboxing │ └── testutil/ # FuzzCompare, CaptureStdio, etc. ├── busybox-reference/ # reference binary (v1.35.0) + test suite ├── docs/SPEC.md ├── plan.md # ash fix log (21 fixes, all applied) └── Makefile

Metric Count

Applet packages 57 (+procutil)

Source files (non-test) 138

Source lines ~29,000

Unit test files 62

Fuzz test files 58

Fuzz functions 100

Fuzz seeds 353

Sandboxing

Under WASM, utilities run within WASI's capability model: only pre-opened directories are accessible; network is off by default; memory is isolated via WASM linear memory; syscalls are limited to WASI preview1.

sandbox.Init(&sandbox.Config{ AllowedPaths: []sandbox.PathRule{ {Path: "/data", Permission: sandbox.PermRead | sandbox.PermWrite}, {Path: "/config", Permission: sandbox.PermRead}, }, AllowCwd: true, CwdPermission: sandbox.PermRead, })

Applets requiring OS APIs unavailable under WASI have *_wasm.go stubs that print an error and exit. 16 applets are stubbed:

ash, ionice, nice, nohup, renice, setsid, ss, start-stop-daemon, taskset, time, timeout, top, users, w, watch, who.

The remaining 41 applets compile and run natively under WASM. Process-management applets (kill, killall, pgrep, pkill, pidof, ps) compile but depend on /proc at runtime — they'll fail gracefully if the filesystem isn't mounted. The procutil signal table is reduced under WASI (no SIGHUP, SIGUSR1, SIGUSR2, SIGALRM).

Requires Go 1.22+, TinyGo 0.34+ (WASM), Make.

pkg/applets/<name>/<name>.go — Run(stdio *core.Stdio, args []string) int

Package Godoc + Run Godoc with flag list

Register in cmd/busybox/main.go

cmd/<name>/main.go entry point

*_test.go unit tests

*_fuzz_test.go fuzz tests

*_wasm.go stub if needed

Godoc convention

// Run executes the grep command with the given arguments. // // Supported flags: // // -E extended regular expressions // -i ignore case // -v invert match // -c count matching lines func Run(stdio *core.Stdio, args []string) int {

Applet status

Applet Tests Key features

ash 349/349 POSIX shell, 25+ builtins, signals, jobs, heredocs

awk 53/53 full parser, 30+ builtins, arrays, getline, printf

sed 92/92 BRE/ERE, in-place, hold space, branches, NL tracking

grep 44/44 ERE/fixed, recursive, word/line, multi-pattern

diff 12/12 unified, whitespace modes, blank-line ignore, recursive

cp 13/13 recursive, symlinks, --parents, hard links

printf 24/24 full format specs, %b, octal/hex

cut 22/22 fields, characters, bytes, custom delimiters

uniq 14/14 count, duplicate, unique, case-insensitive

sort 5/5 numeric, reverse, unique, key-based

tar 3/3 create, extract, gzip, stdin, symlinks, hardlinks

gunzip 5/5 keep, stdout, force, stdin

wget 4/4 -q, -O, -P, combined flags, auto-mkdir

pidof 3/3 cmdline matching, self-exclusion

taskset 3/3 CPU affinity get/set

xargs 7/7 -n, -I, no-cmd defaults to echo

tr 2/2 translate, delete, squeeze, complement, POSIX classes

start-stop-daemon — --start/--exec, --pidfile (native only, partial)

top — static listing stub

All others: complete, no dedicated reference-suite tests.

Fork, branch, hack.

make check before committing.

make security after lint.

go test ./pkg/applets/... -run='Fuzz' -count=1 — all seeds must pass.

Pull request.

See SPEC.md for the full specification.

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →