diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b714e9..f49ed44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,9 +18,9 @@ jobs: id-token: write contents: read steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/determinate-nix-action@v3 - - uses: DeterminateSystems/magic-nix-cache-action@main + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: DeterminateSystems/determinate-nix-action@bafaa638b9d5ec0e7e3ac1a7fc80453ef1fd265f # v3 + - uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # main - name: Run checks (clippy, fmt, test, doc) run: nix flake check -L @@ -40,9 +40,9 @@ jobs: # 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 + # - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + # - uses: DeterminateSystems/determinate-nix-action@bafaa638b9d5ec0e7e3ac1a7fc80453ef1fd265f # v3 + # - uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # main # - name: Build security test binary # run: nix build -L .#security-test-bin # - name: Run security tests in ${{ matrix.distro }} @@ -57,15 +57,15 @@ jobs: name: Cargo Deny runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: EmbarkStudios/cargo-deny-action@v2 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: EmbarkStudios/cargo-deny-action@6c8f9facfa5047ec02d8485b6bf52b587b7777d1 # v2 semver-check: name: SemVer Check runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: Swatinem/rust-cache@v2 - - uses: obi1kenobi/cargo-semver-checks-action@v2 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 + - uses: obi1kenobi/cargo-semver-checks-action@6b69fcf40e9b5fb17adeb57e4b6ecd020649a239 # v2 with: package: evalbox diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 270f853..f10ad05 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,13 +13,13 @@ jobs: name: Release-plz runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 + - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable + - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 - name: Run release-plz - uses: MarcoIeni/release-plz-action@v0.5 + uses: MarcoIeni/release-plz-action@064f4d1e36c843611ddf013be726beaa4ad804db # v0.5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/.gitignore b/.gitignore index 7df85ac..8dc9d5f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,7 @@ fuzz/corpus/ fuzz/artifacts/ # Local cargo config -.cargo/ \ No newline at end of file +.cargo/ + +# SBOM (generated by cargo-cyclonedx) +*.cdx.json \ No newline at end of file diff --git a/crates/evalbox-sys/src/lib.rs b/crates/evalbox-sys/src/lib.rs index 83a8b9f..8a27c08 100644 --- a/crates/evalbox-sys/src/lib.rs +++ b/crates/evalbox-sys/src/lib.rs @@ -22,7 +22,7 @@ //! ## Seccomp-BPF //! //! Seccomp-BPF allows filtering syscalls via BPF programs. This crate provides -//! an architecture-aware whitelist-based filter (x86_64 and aarch64) that allows +//! an architecture-aware whitelist-based filter (`x86_64` and `aarch64`) that allows //! safe syscalls and kills the process on any other syscall. //! //! ## Seccomp User Notify diff --git a/crates/evalbox-sys/src/seccomp.rs b/crates/evalbox-sys/src/seccomp.rs index 8325760..ef16ffd 100644 --- a/crates/evalbox-sys/src/seccomp.rs +++ b/crates/evalbox-sys/src/seccomp.rs @@ -8,7 +8,7 @@ //! //! The BPF filter runs on every syscall: //! -//! 1. Verify architecture is supported (x86_64 or aarch64, kill otherwise) +//! 1. Verify architecture is supported (`x86_64` or `aarch64`, kill otherwise) //! 2. Load syscall number from `seccomp_data` //! 3. Block `clone3` entirely (cannot inspect flags in struct) //! 4. For `clone`, inspect flags and block namespace creation @@ -166,7 +166,7 @@ pub struct SockFprog { pub filter: *const SockFilter, } -/// Base syscalls allowed on all architectures (x86_64 and aarch64). +/// Base syscalls allowed on all architectures (`x86_64` and `aarch64`). /// /// **Ordering**: Hot syscalls first for faster BPF linear scan. /// The kernel checks each JEQ instruction sequentially, so placing @@ -352,11 +352,11 @@ const BASE_WHITELIST: &[i64] = &[ libc::SYS_recvmmsg, ]; -/// Legacy x86_64 syscalls not available on aarch64. +/// Legacy `x86_64` syscalls not available on `aarch64`. /// -/// On aarch64, glibc always uses the modern `*at()` equivalents +/// On `aarch64`, glibc always uses the modern `*at()` equivalents /// (e.g., `openat` instead of `open`, `newfstatat` instead of `stat`). -/// These legacy syscalls only exist in the x86_64 syscall table. +/// These legacy syscalls only exist in the `x86_64` syscall table. #[cfg(target_arch = "x86_64")] const LEGACY_WHITELIST: &[i64] = &[ libc::SYS_fstat, @@ -393,7 +393,7 @@ const LEGACY_WHITELIST: &[i64] = &[ libc::SYS_signalfd, ]; -/// On aarch64, all equivalent functionality is provided by the modern +/// On `aarch64`, all equivalent functionality is provided by the modern /// syscalls already in `BASE_WHITELIST`. #[cfg(target_arch = "aarch64")] const LEGACY_WHITELIST: &[i64] = &[]; @@ -401,7 +401,7 @@ const LEGACY_WHITELIST: &[i64] = &[]; /// Returns the default syscall whitelist for the current architecture. /// /// Combines `BASE_WHITELIST` (common to all architectures) with -/// `LEGACY_WHITELIST` (x86_64-only legacy syscalls). +/// `LEGACY_WHITELIST` (`x86_64`-only legacy syscalls). pub fn default_whitelist() -> Vec { [BASE_WHITELIST, LEGACY_WHITELIST].concat() } @@ -411,7 +411,7 @@ pub fn default_whitelist() -> Vec { /// ## Filter Layout /// /// ```text -/// [0-2] Architecture check (x86_64) +/// [0-2] Architecture check (`x86_64`) /// [3] Load syscall number /// [4] clone3 -> KILL /// [5] clone -> clone_handler @@ -681,7 +681,7 @@ const BASE_NOTIFY_FS_SYSCALLS: &[i64] = &[ libc::SYS_readlinkat, ]; -/// Legacy FS syscalls intercepted on x86_64 only. +/// Legacy FS syscalls intercepted on `x86_64` only. #[cfg(target_arch = "x86_64")] const LEGACY_NOTIFY_FS_SYSCALLS: &[i64] = &[ libc::SYS_open, diff --git a/fuzz/oss-fuzz-build.sh b/fuzz/oss-fuzz-build.sh new file mode 100755 index 0000000..c590628 --- /dev/null +++ b/fuzz/oss-fuzz-build.sh @@ -0,0 +1,31 @@ +#!/bin/bash -eu +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +cd $SRC/evalbox + +if [ "$SANITIZER" = "coverage" ]; then + export RUSTFLAGS="$RUSTFLAGS -C debug-assertions=no" + export CFLAGS="" +fi + +cargo fuzz build -O --debug-assertions + +FUZZ_TARGET_OUTPUT_DIR=fuzz/target/x86_64-unknown-linux-gnu/release +for f in fuzz/fuzz_targets/*.rs; do + FUZZ_TARGET_NAME=$(basename ${f%.*}) + cp $FUZZ_TARGET_OUTPUT_DIR/$FUZZ_TARGET_NAME $OUT/ +done diff --git a/nix/devshell.nix b/nix/devshell.nix index 4ad8f5d..70c57ba 100644 --- a/nix/devshell.nix +++ b/nix/devshell.nix @@ -25,5 +25,6 @@ ]; RUST_BACKTRACE = "1"; }; + }; }