Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ jobs:
# ping_test.go. Go test helpers are only in scope within the same directory,
# so both files must reside in builtins/ping/.
corpus_path: builtins/ping
- pkg: ./builtins/pwd/
name: pwd
# pwd fuzz tests live in builtins/pwd/ alongside the pwd_test.go
# helpers (pwdRun) — same rationale as ping above.
corpus_path: builtins/pwd
- pkg: ./interp/tests/
name: interp
corpus_path: interp/tests
Expand Down
1 change: 1 addition & 0 deletions SHELL_FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Blocked features are rejected before execution with exit code 2.
- ✅ `ping [-c N] [-W DURATION] [-i DURATION] [-q] [-4|-6] [-h] HOST` — send ICMP echo requests to a network host and report round-trip statistics; `-f` (flood), `-b` (broadcast), `-s` (packet size), `-I` (interface), `-p` (pattern), and `-R` (record route) are blocked; count/wait/interval are clamped to safe ranges with a warning; multicast, unspecified (`0.0.0.0`/`::`), and broadcast addresses (IPv4 last-octet `.255`) are rejected — note: directed broadcasts on non-standard subnets (e.g. `.127` on a `/25`) are not blocked without subnet-mask knowledge
- ✅ `ps [-e|-A] [-f] [-p PIDLIST]` — report process status; default shows current-session processes; `-e`/`-A` shows all; `-f` adds UID/PPID/STIME columns; `-p` selects by PID list
- ✅ `printf FORMAT [ARGUMENT]...` — format and print data to stdout; supports `%s`, `%b`, `%c`, `%d`, `%i`, `%o`, `%u`, `%x`, `%X`, `%e`, `%E`, `%f`, `%F`, `%g`, `%G`, `%%`; format reuse for excess arguments; `%n` rejected (security risk); `-v` rejected
- ✅ `pwd [-LP]` — print the absolute pathname of the current working directory; `-L` (default) prints the shell's tracked logical path, `-P` resolves all symlinks; `-P` is best-effort within the sandbox (path components above `AllowedPaths` pass through unresolved); `--version` rejected
- ✅ `sed [-n] [-e SCRIPT] [-E|-r] [SCRIPT] [FILE]...` — stream editor for filtering and transforming text; uses RE2 regex engine; `-i`/`-f` rejected; `e`/`w`/`W`/`r`/`R` commands blocked
- ✅ `strings [-a] [-n MIN] [-t o|d|x] [-o] [-f] [-s SEP] [FILE]...` — print printable character sequences in files (default min length 4); offsets via `-t`/`-o`; filename prefix via `-f`; custom separator via `-s`
- ✅ `tail [-n N|-c N] [-q|-v] [-z] [FILE]...` — output the last part of files (default: last 10 lines); supports `+N` offset mode; `-f`/`--follow` is rejected
Expand Down
21 changes: 21 additions & 0 deletions analysis/symbols_builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,22 @@ var builtinPerCommandSymbols = map[string][]string{
"strings.ReplaceAll", // 🟢 replaces all occurrences of a substring; pure function, no I/O.
"strings.ToLower", // 🟢 converts string to lowercase; pure function, no I/O.
},
"pwd": {
"context.Context", // 🟢 deadline/cancellation plumbing; pure interface, no side effects.
"errors.Is", // 🟢 error comparison; pure function, no I/O.
"errors.New", // 🟢 creates a simple error value; pure function, no I/O.
"fmt.Errorf", // 🟢 error formatting; pure function, no I/O.
"io/fs.ModeSymlink", // 🟢 file mode bit constant for symlinks; pure constant.
"path/filepath.Clean", // 🟢 normalizes a path lexically (collapses ".", "..", duplicate separators); pure function, no I/O.
"path/filepath.Dir", // 🟢 returns the directory component of a path; pure function, no I/O.
"path/filepath.IsAbs", // 🟢 reports whether a path is absolute; pure function, no I/O.
"path/filepath.Join", // 🟢 lexically joins path components with the OS separator; pure function, no I/O.
"path/filepath.Separator", // 🟢 OS path separator constant ('/' or '\\'); pure constant, no I/O.
"path/filepath.VolumeName", // 🟢 returns the volume prefix of a path (e.g. "C:" on Windows, "" on Unix); pure function, no I/O.
"strings.HasPrefix", // 🟢 pure function for prefix matching; no I/O.
"strings.IndexByte", // 🟢 finds byte in string; pure function, no I/O.
"strings.TrimPrefix", // 🟢 removes a leading prefix from a string; pure function, no I/O.
},
"sort": {
"bufio.NewScanner", // 🟢 line-by-line input reading (e.g. head, cat); no write or exec capability.
"context.Context", // 🟢 deadline/cancellation plumbing; pure interface, no side effects.
Expand Down Expand Up @@ -472,9 +488,13 @@ var builtinAllowedSymbols = []string{
"os.IsNotExist", // 🟢 checks if error is "not exist"; pure function, no I/O.
"os.O_RDONLY", // 🟢 read-only file flag constant; cannot open files by itself.
"os.PathError", // 🟢 error type for filesystem path errors; pure type, no I/O.
"path/filepath.Clean", // 🟢 normalizes a path lexically (collapses ".", "..", duplicate separators); pure function, no I/O.
"path/filepath.Dir", // 🟢 returns the directory component of a path; pure function, no I/O.
"path/filepath.IsAbs", // 🟢 reports whether a path is absolute; pure function, no I/O.
"path/filepath.Join", // 🟢 lexically joins path components with the OS separator; pure function, no I/O.
"path/filepath.Separator", // 🟢 OS path separator constant ('/' or '\\'); pure constant, no I/O.
"path/filepath.ToSlash", // 🟢 converts OS path separators to forward slashes; pure function, no I/O.
"path/filepath.VolumeName", // 🟢 returns the volume prefix of a path (e.g. "C:" on Windows, "" on Unix); pure function, no I/O.
"regexp.Compile", // 🟢 compiles a regular expression; pure function, no I/O. Uses RE2 engine (linear-time, no backtracking).
"regexp.QuoteMeta", // 🟢 escapes all special regex characters in a string; pure function, no I/O.
"regexp.Regexp", // 🟢 compiled regular expression type; no I/O side effects. All matching methods are linear-time (RE2).
Expand Down Expand Up @@ -503,6 +523,7 @@ var builtinAllowedSymbols = []string{
"strings.ReplaceAll", // 🟢 replaces all occurrences of a substring; pure function, no I/O.
"strings.Split", // 🟢 splits a string by separator into a slice; pure function, no I/O.
"strings.ToLower", // 🟢 converts string to lowercase; pure function, no I/O.
"strings.TrimPrefix", // 🟢 removes a leading prefix from a string; pure function, no I/O.
"strings.TrimSpace", // 🟢 removes leading/trailing whitespace; pure function.
"syscall.ByHandleFileInformation", // 🟢 Windows file info struct for extracting nlink; read-only type, no I/O.
"syscall.EACCES", // 🟢 POSIX errno constant for permission denied; pure constant, no I/O.
Expand Down
9 changes: 9 additions & 0 deletions builtins/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,15 @@ type CallContext struct {
// Used by builtins that need to compute absolute paths for sub-operations.
WorkDir func() string

// HostPrefix returns the configured host-mount prefix used by
// container-style sandboxes to translate host-absolute paths
// (e.g. /var/log/pods/...) into the prefixed paths the sandbox can
// open (e.g. /mnt/host/var/log/pods/...). Returns "" when no prefix
// is configured. Builtins that resolve absolute symlink targets
// (e.g. pwd -P) use this to keep their output consistent with what
// the sandbox itself accepts.
HostPrefix func() string

// RunCommand executes a builtin command within the shell's sandbox.
// dir overrides the working directory for path resolution.
// Returns the command's exit code.
Expand Down
Loading
Loading