Skip to content
Merged
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
13 changes: 0 additions & 13 deletions .cargo/config.toml

This file was deleted.

76 changes: 41 additions & 35 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,59 @@ on:
pull_request:
branches: [main]

env:
CARGO_TERM_COLOR: always
RUSTFLAGS: -Dwarnings
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
fmt:
name: Format
nix-checks:
name: Nix Checks
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- run: rustup component add rustfmt
- run: cargo fmt --all --check
- uses: DeterminateSystems/determinate-nix-action@v3
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Run checks (clippy, fmt, test, doc)
run: nix flake check -L

clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: rustup component add clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-targets --all-features

doc:
name: Documentation
runs-on: ubuntu-latest
env:
RUSTDOCFLAGS: -Dwarnings
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- run: cargo doc --no-deps --all-features

unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- run: cargo test --lib --all-features
# E2E security tests require kernel 6.12+ (Landlock ABI v5).
# GHA ubuntu-latest currently ships 6.11; image 20260209 has 6.14 but hasn't propagated yet.
# Uncomment when runners get kernel 6.12+.
#
# e2e:
# name: E2E (${{ matrix.distro }})
# runs-on: ubuntu-latest
# needs: nix-checks
# permissions:
# id-token: write
# contents: read
# strategy:
# fail-fast: false
# matrix:
# distro: [ubuntu:24.04, fedora:41, alpine:3.21]
# steps:
# - uses: actions/checkout@v4
# - uses: DeterminateSystems/determinate-nix-action@v3
# - uses: DeterminateSystems/magic-nix-cache-action@main
# - name: Build security test binary
# run: nix build -L .#security-test-bin
# - name: Run security tests in ${{ matrix.distro }}
# run: |
# TEST_BIN=$(realpath result/bin/security_tests-*)
# docker run --rm --privileged \
# -v /nix/store:/nix/store:ro \
# ${{ matrix.distro }} \
# "$TEST_BIN" --ignored --test-threads=1

semver-check:
name: SemVer Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- name: Check semver
uses: obi1kenobi/cargo-semver-checks-action@v2
- uses: obi1kenobi/cargo-semver-checks-action@v2
with:
package: evalbox
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.direnv
target/
bindings/
bindings/

# Local cargo config
.cargo/
43 changes: 37 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.1] - 2026-02-22

### Changed

- **Architecture: remove namespace isolation, use Landlock v5 as primary**
- Removed user, PID, network, mount, UTS, and IPC namespaces
- Removed `pivot_root` and bind mount rootfs setup
- Landlock v5 replaces namespaces for filesystem, network, signal, and IPC control
- Plain `fork()` instead of `clone()` with `CLONE_NEW*` flags
- Minimum kernel raised from 5.13 to 6.12 (Landlock ABI 5)

- **Resource limits moved to dedicated module** (`isolation/rlimits.rs`)
- `RLIMIT_DATA` (256 MiB) instead of `RLIMIT_AS` (breaks Go/Java/V8 runtimes)
- Added `RLIMIT_CPU`, `RLIMIT_CORE`, `RLIMIT_STACK`

- **Nix flake migrated to flake-parts + import-tree**
- Auto-discovery of modules via `import-tree ./nix`
- Removed manual `forAllSystems` boilerplate
- Restricted to `x86_64-linux` (arm not yet supported)

### Added

- Seccomp user notify support (`SECCOMP_RET_USER_NOTIF`) for optional syscall interception
- `nix run .#test-all` to run the full security test suite
- `SECURITY.md` — GitHub standard vulnerability reporting policy
- `CONTRIBUTING.md` — development setup, testing guide
- Security hardening roadmap (UDP filtering, /proc restriction, optional PID namespace)

### Removed

- `crates/evalbox-sandbox/src/isolation/namespace.rs` — namespace setup
- `crates/evalbox-sandbox/src/isolation/rootfs.rs` — pivot_root + bind mounts
- `nix/lib.nix`, `nix/checks.nix`, `nix/tests/` — replaced by flake-parts modules

## [0.1.0] - 2025-02-17

### Added
Expand All @@ -19,14 +53,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Go runtime with compilation caching
- Shell runtime for script execution

- **Security isolation** (7 layers of defense)
- User namespaces (unprivileged containers)
- PID namespace (process isolation)
- Network namespace (network isolation)
- Mount namespace + pivot_root (filesystem isolation)
- Landlock LSM (kernel-enforced filesystem rules)
- **Security isolation**
- Landlock v5 (filesystem, network, signal, IPC access control)
- Seccomp BPF (syscall whitelist with ~100 allowed syscalls)
- Resource limits (memory, PIDs, file descriptors, timeout)
- Privilege hardening (NO_NEW_PRIVS, securebits, capability drop)

- **Seccomp filtering**
- Whitelist-based syscall filter
Expand Down
80 changes: 80 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Contributing

## Development Setup

evalbox uses Nix for a reproducible dev environment:

```bash
nix develop
```

This provides the Rust toolchain, GCC (for test payloads), Python, and Go.

## Building

```bash
cargo build
```

## Testing

### Fast checks (CI)

```bash
# Runs via nix: clippy, fmt, unit tests, docs
nix flake check
```

Or manually:

```bash
cargo clippy --all-targets -- -D warnings
cargo fmt --check
cargo test --lib
cargo doc --no-deps
```

### Full test suite (requires user namespaces)

```bash
nix run .#test-all
```

Or manually:

```bash
cargo build -p evalbox-sandbox
cargo test -p evalbox-sandbox --test security_tests --ignored -- --test-threads=1
```

The security tests require Linux with user namespaces enabled. They compile C payloads that attempt real exploit techniques (CVEs, syscall abuse, escape vectors) and verify the sandbox blocks them.

### Running specific test categories

```bash
cargo test -p evalbox-sandbox --test security_tests seccomp -- --ignored
cargo test -p evalbox-sandbox --test security_tests filesystem -- --ignored
cargo test -p evalbox-sandbox --test security_tests network -- --ignored
cargo test -p evalbox-sandbox --test security_tests cve -- --ignored
cargo test -p evalbox-sandbox --test security_tests resources -- --ignored
```

## Project Structure

```
evalbox/ # Public API, language runtimes
evalbox-sandbox/ # Sandbox orchestration, isolation
evalbox-sys/ # Low-level Linux syscall wrappers
```

See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for details.

## Pull Requests

- Run `nix flake check` before submitting
- Security-related changes should include tests in `crates/evalbox-sandbox/tests/security/`
- Keep the seccomp whitelist minimal: don't add syscalls without justification

## Security

Found a vulnerability? See [SECURITY.md](SECURITY.md) for reporting instructions.
22 changes: 2 additions & 20 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ members = [
"crates/evalbox-sandbox",
]

[workspace.metadata.crane]
name = "evalbox"

[workspace.package]
version = "0.1.0"
edition = "2024"
Expand All @@ -30,7 +33,7 @@ rustix = { version = "1", features = ["event", "process", "system", "mount", "fs
thiserror = "2"
tempfile = "3"
mio = { version = "1.0", features = ["os-poll", "os-ext"] }
which = "7"
which = "8"

[workspace.lints.rust]
unsafe_op_in_unsafe_fn = "warn"
Expand All @@ -39,7 +42,6 @@ unused_must_use = "warn"

[workspace.lints.clippy]
all = { level = "warn", priority = -1 }
# Useful pedantic lints (not all)
cast_possible_truncation = "warn"
cast_sign_loss = "warn"
cloned_instead_of_copied = "warn"
Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Execute code like `eval()`, but safe. No containers, no VMs, no root.
- **Simple** - One function call, security handled for you
- **Multi-language** - Python, Go, and shell/terminal commands
- **Fast** - Millisecond startup, no containers or VMs
- **Secure** - 7 layers of isolation (namespaces, Landlock, seccomp, rlimits)
- **Secure** - Landlock v5 + seccomp-BPF + rlimits, no namespaces needed

## Quick Start

Expand All @@ -38,8 +38,8 @@ let output = shell::run("curl https://example.com")

## Requirements

- Linux kernel 5.13+ (Landlock ABI 1+)
- User namespaces enabled
- Linux kernel 6.12+ (Landlock ABI 5)
- Seccomp enabled

## Installation

Expand All @@ -50,15 +50,16 @@ evalbox = { version = "0.1", features = ["python", "go", "shell"] }

## Security

7 layers of isolation: user namespaces, PID namespace, network namespace, mount namespace + pivot_root, Landlock LSM, seccomp BPF, rlimits.
Isolation via Landlock v5 (filesystem + network + signal + IPC scoping), seccomp-BPF (syscall whitelist), rlimits, privilege hardening (NO_NEW_PRIVS, securebits, capability drop).

See [SECURITY.md](docs/SECURITY.md) for threat model and CVE protections.
See [Security Model](docs/SECURITY_MODEL.md) for threat model and CVE protections.

## Documentation

- [Architecture](docs/ARCHITECTURE.md)
- [Security Model](docs/SECURITY.md)
- [Security Model](docs/SECURITY_MODEL.md)
- [Roadmap](docs/ROADMAP.md)
- [Contributing](CONTRIBUTING.md)

## License

Expand Down
Loading
Loading