Skip to content

Commit 41c1687

Browse files
committed
refactor: multiplatform sandbox architecture (sys/linux + sys/windows)
Move 7 Linux-specific modules into src/sys/linux/, create sys.rs dispatch hub (crosvm pattern), add Windows stubs with matching security layers (Job Objects, AppContainer, Restricted Tokens, ETW). - Move executor, monitor, workspace, sysinfo, notify to sys/linux/ - Merge isolation/lockdown.rs + rlimits.rs into sys/linux/lockdown.rs - Extract virtual_fs.rs to crate root (platform-agnostic) - Add sys/linux/policy.rs (Plan → Linux primitives compilation) - Add complete sys/windows/ stubs with Win32 API documentation - Make evalbox-sys, libc, rustix, mio Linux-only deps - Guard build.rs C payload compilation with cfg(target_os = "linux") - Add #[non_exhaustive] to ExecutorError, Event, Status - CI: Windows x86_64 + ARM64, Linux x86_64 + ARM64, cross-compile - Update deny.toml with all 4 target triples - Bump workspace version to 0.2.0
1 parent c41b95d commit 41c1687

37 files changed

Lines changed: 3402 additions & 226 deletions

.github/workflows/ci.yml

Lines changed: 137 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ concurrency:
1111
cancel-in-progress: true
1212

1313
jobs:
14+
# ─── Linux x86_64: full Nix checks (clippy, fmt, test, doc) ───────
1415
nix-checks:
1516
name: Nix Checks
1617
runs-on: ubuntu-latest
@@ -24,42 +25,151 @@ jobs:
2425
- name: Run checks (clippy, fmt, test, doc)
2526
run: nix flake check -L
2627

27-
# E2E security tests require kernel 6.12+ (Landlock ABI v5).
28-
# GHA ubuntu-latest currently ships 6.11; image 20260209 has 6.14 but hasn't propagated yet.
29-
# Uncomment when runners get kernel 6.12+.
28+
# ─── Linux ARM64: native build + unit tests ────────────────────────
29+
arm64:
30+
name: Linux ARM64
31+
runs-on: ubuntu-24.04-arm
32+
steps:
33+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
34+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
35+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
36+
37+
- name: Clippy
38+
run: cargo clippy --workspace -- -D warnings
39+
40+
- name: Unit tests
41+
run: cargo test --workspace
42+
43+
# ─── Windows: compile + platform-agnostic tests ───────────────────
44+
#
45+
# Validates cross-platform compilation and runs tests that don't
46+
# require Linux syscalls (plan, validate, virtual_fs, policy).
47+
# Runs on both x86_64 and ARM64 runners.
48+
#
49+
windows:
50+
name: Windows ${{ matrix.arch }}
51+
runs-on: ${{ matrix.runner }}
52+
strategy:
53+
fail-fast: false
54+
matrix:
55+
include:
56+
- arch: x86_64
57+
runner: windows-latest
58+
- arch: ARM64
59+
runner: windows-11-arm
60+
steps:
61+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
62+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
63+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
64+
with:
65+
key: windows-${{ matrix.arch }}
66+
67+
- name: Check compilation
68+
run: cargo check -p evalbox-sandbox
69+
70+
- name: Clippy
71+
run: cargo clippy -p evalbox-sandbox -- -D warnings
72+
73+
- name: Unit tests
74+
run: cargo test -p evalbox-sandbox
75+
76+
# ─── Cross-compile check (compilation only, no tests) ──────────────
77+
#
78+
# Verifies that the codebase compiles for all supported targets:
79+
# - aarch64-unknown-linux-gnu (Linux ARM64, cross from x86_64)
80+
# - x86_64-unknown-linux-musl (Linux x86_64 static/musl)
81+
# - aarch64-pc-windows-msvc (Windows ARM64, cross-check)
82+
#
83+
cross-compile:
84+
name: Cross (${{ matrix.target }})
85+
runs-on: ${{ matrix.runner }}
86+
strategy:
87+
fail-fast: false
88+
matrix:
89+
include:
90+
- target: aarch64-unknown-linux-gnu
91+
runner: ubuntu-latest
92+
install: sudo apt-get update && sudo apt-get install -y gcc-aarch64-linux-gnu musl-tools
93+
- target: x86_64-unknown-linux-musl
94+
runner: ubuntu-latest
95+
install: sudo apt-get update && sudo apt-get install -y musl-tools
96+
- target: aarch64-pc-windows-msvc
97+
runner: windows-latest
98+
install: ""
99+
steps:
100+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
101+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
102+
with:
103+
targets: ${{ matrix.target }}
104+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
105+
with:
106+
key: ${{ matrix.target }}
107+
108+
- name: Install cross-compilation tools
109+
if: matrix.install != ''
110+
run: ${{ matrix.install }}
111+
112+
- name: Check compilation
113+
run: cargo check --workspace --target ${{ matrix.target }}
114+
env:
115+
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
116+
117+
# ─── E2E security tests (require kernel 6.12+ for Landlock ABI v5) ─
118+
#
119+
# Tests ACTUAL sandbox isolation: seccomp blocks, Landlock filesystem
120+
# rules, network blocking, resource limits, CVE payloads.
121+
#
122+
# Minimum kernel for evalbox is 6.7 (Landlock ABI 4), but security
123+
# tests exercise ABI 5 features (signal/IPC scoping) which need 6.12+.
30124
#
31-
# e2e:
32-
# name: E2E (${{ matrix.distro }})
33-
# runs-on: ubuntu-latest
34-
# needs: nix-checks
35-
# permissions:
36-
# id-token: write
37-
# contents: read
38-
# strategy:
39-
# fail-fast: false
40-
# matrix:
41-
# distro: [ubuntu:24.04, fedora:41, alpine:3.21]
42-
# steps:
43-
# - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
44-
# - uses: DeterminateSystems/determinate-nix-action@bafaa638b9d5ec0e7e3ac1a7fc80453ef1fd265f # v3
45-
# - uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # main
46-
# - name: Build security test binary
47-
# run: nix build -L .#security-test-bin
48-
# - name: Run security tests in ${{ matrix.distro }}
49-
# run: |
50-
# TEST_BIN=$(realpath result/bin/security_tests-*)
51-
# docker run --rm --privileged \
52-
# -v /nix/store:/nix/store:ro \
53-
# ${{ matrix.distro }} \
54-
# "$TEST_BIN" --ignored --test-threads=1
125+
# GHA ubuntu-latest ships kernel 6.11 — enable when runners get 6.12+.
126+
#
127+
e2e:
128+
name: E2E (${{ matrix.distro }})
129+
if: false # TODO: enable when GHA runners ship kernel 6.12+
130+
runs-on: ubuntu-latest
131+
needs: nix-checks
132+
permissions:
133+
id-token: write
134+
contents: read
135+
strategy:
136+
fail-fast: false
137+
matrix:
138+
distro: [ubuntu:24.04, fedora:41, alpine:3.21]
139+
steps:
140+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
141+
- uses: DeterminateSystems/determinate-nix-action@bafaa638b9d5ec0e7e3ac1a7fc80453ef1fd265f # v3
142+
- uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # main
143+
144+
- name: Check kernel version
145+
run: |
146+
KVER=$(uname -r | cut -d. -f1-2)
147+
echo "Kernel: $KVER"
148+
if [ "$(echo "$KVER < 6.12" | bc)" -eq 1 ]; then
149+
echo "::error::Kernel $KVER < 6.12, Landlock ABI v5 not available"
150+
exit 1
151+
fi
152+
153+
- name: Build security test binary
154+
run: nix build -L .#security-test-bin
155+
156+
- name: Run security tests in ${{ matrix.distro }}
157+
run: |
158+
TEST_BIN=$(realpath result/bin/security_tests-*)
159+
docker run --rm --privileged \
160+
-v /nix/store:/nix/store:ro \
161+
${{ matrix.distro }} \
162+
"$TEST_BIN" --ignored --test-threads=1
55163
164+
# ─── Dependency audit ──────────────────────────────────────────────
56165
cargo-deny:
57166
name: Cargo Deny
58167
runs-on: ubuntu-latest
59168
steps:
60169
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
61170
- uses: EmbarkStudios/cargo-deny-action@6c8f9facfa5047ec02d8485b6bf52b587b7777d1 # v2
62171

172+
# ─── SemVer compatibility ──────────────────────────────────────────
63173
semver-check:
64174
name: SemVer Check
65175
runs-on: ubuntu-latest

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ members = [
1010
name = "evalbox"
1111

1212
[workspace.package]
13-
version = "0.1.1"
13+
version = "0.2.0"
1414
edition = "2024"
1515
rust-version = "1.85"
1616
license = "MIT OR Apache-2.0"
@@ -22,9 +22,9 @@ keywords = ["sandbox", "isolation", "security", "landlock", "seccomp"]
2222
categories = ["os::linux-apis", "development-tools"]
2323

2424
[workspace.dependencies]
25-
evalbox = { version = "0.1.1", path = "crates/evalbox" }
26-
evalbox-sys = { version = "0.1.1", path = "crates/evalbox-sys" }
27-
evalbox-sandbox = { version = "0.1.1", path = "crates/evalbox-sandbox" }
25+
evalbox = { version = "0.2.0", path = "crates/evalbox" }
26+
evalbox-sys = { version = "0.2.0", path = "crates/evalbox-sys" }
27+
evalbox-sandbox = { version = "0.2.0", path = "crates/evalbox-sandbox" }
2828

2929
libc = "0.2"
3030
serde = { version = "1", features = ["derive"] }

crates/evalbox-sandbox/Cargo.toml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,27 @@ repository.workspace = true
88
description = "Sandbox orchestration for evalbox"
99

1010
[dependencies]
11+
thiserror.workspace = true
12+
which.workspace = true
13+
tempfile.workspace = true
14+
15+
# Linux-only dependencies (seccomp, landlock, pidfd, mio epoll)
16+
[target.'cfg(target_os = "linux")'.dependencies]
1117
evalbox-sys.workspace = true
1218
libc.workspace = true
1319
rustix.workspace = true
14-
tempfile.workspace = true
1520
mio.workspace = true
16-
thiserror.workspace = true
17-
which.workspace = true
1821

19-
[build-dependencies]
22+
# Windows-only dependencies (future: windows-sys for Job Objects, AppContainer)
23+
# [target.'cfg(target_os = "windows")'.dependencies]
24+
# windows-sys = { version = "0.59", features = [...] }
25+
26+
[target.'cfg(target_os = "linux")'.build-dependencies]
2027
cc = "1.2"
2128

29+
[package.metadata.docs.rs]
30+
all-features = true
31+
rustdoc-args = ["--cfg", "docsrs"]
32+
2233
[lints]
2334
workspace = true

0 commit comments

Comments
 (0)