From 07ae496cbb51259602abdeb6cf7fef70da3f48c9 Mon Sep 17 00:00:00 2001 From: Drew Newberry Date: Thu, 17 Sep 2026 23:43:27 -0700 Subject: [PATCH] chore(vm): refresh runtime defaults and hardening Signed-off-by: Drew Newberry --- crates/openshell-driver-vm/README.md | 1 + .../runtime/kernel/openshell.kconfig | 8 +++++++ crates/openshell-driver-vm/runtime/pins.env | 21 +++++-------------- crates/openshell-gateway/src/vm.rs | 13 ++++++++++-- docs/reference/gateway-config.mdx | 4 ++-- docs/reference/sandbox-compute-drivers.mdx | 2 +- e2e/rust/e2e-vm.sh | 2 +- tasks/scripts/gateway-vm.sh | 2 +- tasks/scripts/vm/build-libkrun.sh | 20 +++++++++++++----- 9 files changed, 45 insertions(+), 28 deletions(-) diff --git a/crates/openshell-driver-vm/README.md b/crates/openshell-driver-vm/README.md index 0dc41498c2..2cce3b1c04 100644 --- a/crates/openshell-driver-vm/README.md +++ b/crates/openshell-driver-vm/README.md @@ -47,6 +47,7 @@ First run takes a few minutes while `mise run vm:setup` stages libkrun/libkrunfw By default `mise run gateway:vm`: - Listens on plaintext HTTP at `127.0.0.1:18081`. +- Uses `nvcr.io/nvidia/base/ubuntu:24.04` as the sandbox and bootstrap image. - Configures the gateway installation name as `vm-dev` and registers the same name with the CLI by writing `~/.config/openshell/gateways/vm-dev/metadata.json`. It does not modify the diff --git a/crates/openshell-driver-vm/runtime/kernel/openshell.kconfig b/crates/openshell-driver-vm/runtime/kernel/openshell.kconfig index 4249e71121..d4493abd7b 100644 --- a/crates/openshell-driver-vm/runtime/kernel/openshell.kconfig +++ b/crates/openshell-driver-vm/runtime/kernel/openshell.kconfig @@ -35,3 +35,11 @@ CONFIG_SECURITY_LANDLOCK=y CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,ipe,bpf" CONFIG_SECCOMP=y CONFIG_SECCOMP_FILTER=y + +# Kernel memory hardening. Keep init-on-free disabled because its runtime cost +# is too high for sandbox workloads. +CONFIG_HARDENED_USERCOPY=y +CONFIG_INIT_STACK_ALL_ZERO=y +CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +CONFIG_SLAB_FREELIST_RANDOM=y diff --git a/crates/openshell-driver-vm/runtime/pins.env b/crates/openshell-driver-vm/runtime/pins.env index 5595394b54..35f52678a7 100644 --- a/crates/openshell-driver-vm/runtime/pins.env +++ b/crates/openshell-driver-vm/runtime/pins.env @@ -4,8 +4,7 @@ # Pinned dependency versions for the openshell-driver-vm runtime. # # This file is sourced by VM runtime packaging scripts. It centralises version -# pins and content-addressed digests so that builds are reproducible and -# auditable. +# pins so that builds are reproducible and auditable. # # Environment variables override these defaults — CI and local dev workflows # can still set the runtime dependency versions below. @@ -15,30 +14,20 @@ # 2. Run the relevant build script to verify. # 3. Commit pins.env alongside any script changes. -# ── Base Docker image (digest-pinned) ────────────────────────────────── -# Tag: nvcr.io/nvidia/base/ubuntu:noble-20251013 -VM_BASE_IMAGE="${VM_BASE_IMAGE:-nvcr.io/nvidia/base/ubuntu@sha256:43fa5063e80fbbc533892af3ccca190868ce48db5a8928b19d7815c40436af8e}" - -# ── Container images for rootfs pre-loading (digest-pinned) ──────────── -# Tag: registry.k8s.io/agent-sandbox/agent-sandbox-controller:v0.1.0 -AGENT_SANDBOX_IMAGE="${AGENT_SANDBOX_IMAGE:-registry.k8s.io/agent-sandbox/agent-sandbox-controller@sha256:ba71ea40ae0872791197badf2ab84f3f482df3902f1fce7ca9e076b1de9b57f6}" -# Tag: ghcr.io/nvidia/openshell-community/sandboxes/base:latest -COMMUNITY_SANDBOX_IMAGE="${COMMUNITY_SANDBOX_IMAGE:-ghcr.io/nvidia/openshell-community/sandboxes/base@sha256:d446c17105e7448e602238a8a5a4ddd0233c071082406522f81c31f8b1309525}" - # SERVER_IMAGE is intentionally NOT pinned here — it changes frequently # during local development. Override via IMAGE_REPO_BASE and IMAGE_TAG # environment variables (defaults: openshell/gateway:dev). -# ── umoci (guest OCI unpacker) ────────────────────────────────────────── +# ── umoci (guest OCI unpacker) ─────────────────────────────────────── # Repo: https://github.com/opencontainers/umoci UMOCI_VERSION="${UMOCI_VERSION:-v0.6.0}" -# ── libkrunfw upstream (commit-pinned) ───────────────────────────────── +# ── libkrunfw upstream (commit-pinned) ──────────────────────────────── # Repo: https://github.com/libkrun/libkrunfw -# Pinned: v5.6.1 (2026-09-16) +# Pinned: v5.6.1 (Linux 6.12.109, 2026-09-16) LIBKRUNFW_REF="${LIBKRUNFW_REF:-617938cf2ae9a3a0e5696d23a5d6252cd7a1ef4f}" -# ── libkrun upstream (commit-pinned) ────────────────────────────────── +# ── libkrun upstream (commit-pinned) ───────────────────────────────── # Repo: https://github.com/libkrun/libkrun # Pinned: v1.19.4 (2026-09-16) LIBKRUN_REF="${LIBKRUN_REF:-728df8125077d0db44265f6e997c72b81b65c015}" diff --git a/crates/openshell-gateway/src/vm.rs b/crates/openshell-gateway/src/vm.rs index 07735c7a9c..413d5a579b 100644 --- a/crates/openshell-gateway/src/vm.rs +++ b/crates/openshell-gateway/src/vm.rs @@ -58,6 +58,7 @@ use tower::service_fn; const DRIVER_BIN_NAME: &str = "openshell-driver-vm"; const COMPUTE_DRIVER_SOCKET_RUN_DIR: &str = "run"; const COMPUTE_DRIVER_SOCKET_NAME: &str = "compute-driver.sock"; +const DEFAULT_VM_SANDBOX_IMAGE: &str = "nvcr.io/nvidia/base/ubuntu:24.04"; /// Configuration for launching and talking to the VM compute driver. #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] @@ -233,7 +234,7 @@ impl Default for VmComputeConfig { Self { state_dir: Self::default_state_dir(), driver_dir: None, - default_image: openshell_core::image::default_sandbox_image(), + default_image: DEFAULT_VM_SANDBOX_IMAGE.to_string(), grpc_endpoint: String::new(), bootstrap_image: String::new(), krun_log_level: Self::default_krun_log_level(), @@ -759,7 +760,7 @@ async fn connect_compute_driver(socket_path: &Path) -> Result { #[cfg(all(test, unix))] mod tests { use super::{ - VmComputeConfig, append_otlp_args, append_vm_identity_args, + DEFAULT_VM_SANDBOX_IMAGE, VmComputeConfig, append_otlp_args, append_vm_identity_args, append_vm_proxy_and_spiffe_args, append_vm_rootfs_tar_args, compute_driver_guest_tls_paths, compute_driver_socket_path, current_euid, prepare_compute_driver_socket_path, prepare_vm_state_dir, resolve_compute_driver_bin, resolve_driver_search_dirs, @@ -772,6 +773,14 @@ mod tests { use std::path::PathBuf; use tempfile::tempdir; + #[test] + fn vm_uses_nvidia_ubuntu_default_image() { + assert_eq!( + VmComputeConfig::default().default_image, + DEFAULT_VM_SANDBOX_IMAGE + ); + } + #[test] fn vm_driver_command_includes_gateway_otlp_configuration() { let mut command = tokio::process::Command::new("openshell-driver-vm"); diff --git a/docs/reference/gateway-config.mdx b/docs/reference/gateway-config.mdx index 75599ae19f..74fdb6812b 100644 --- a/docs/reference/gateway-config.mdx +++ b/docs/reference/gateway-config.mdx @@ -911,12 +911,12 @@ guest_tls_key = "/var/lib/openshell/guest-tls/client-key.pem" state_dir = "/var/lib/openshell/vm" # Where the gateway looks for the openshell-driver-vm subprocess binary. driver_dir = "/usr/local/libexec/openshell" -default_image = "ghcr.io/nvidia/openshell-community/sandboxes/base:latest" +default_image = "nvcr.io/nvidia/base/ubuntu:24.04" # Optional override. When omitted, the gateway derives # https://host.openshell.internal: for the VM driver. grpc_endpoint = "https://host.openshell.internal:17670" # Empty falls back to default_image. -bootstrap_image = "ghcr.io/nvidia/openshell-community/sandboxes/base:latest" +bootstrap_image = "nvcr.io/nvidia/base/ubuntu:24.04" krun_log_level = 1 vcpus = 2 mem_mib = 2048 diff --git a/docs/reference/sandbox-compute-drivers.mdx b/docs/reference/sandbox-compute-drivers.mdx index d24ff67ef4..e9e616d013 100644 --- a/docs/reference/sandbox-compute-drivers.mdx +++ b/docs/reference/sandbox-compute-drivers.mdx @@ -363,7 +363,7 @@ compute_driver = "vm" For a launch-time override, set `OPENSHELL_COMPUTE_DRIVER=vm` in the gateway environment and restart the service. -Configure VM driver values such as `grpc_endpoint`, `driver_dir`, `state_dir`, `default_image`, `bootstrap_image`, `vcpus`, `mem_mib`, `overlay_disk_mib`, `krun_log_level`, and `guest_tls_*` in `[openshell.drivers.vm]`. The VM `state_dir` stores overlay disks, console logs, runtime state, image-rootfs cache, and the private `run/compute-driver.sock` socket. The VM socket path is managed by the gateway and is not configurable through remote endpoint settings. +Configure VM driver values such as `grpc_endpoint`, `driver_dir`, `state_dir`, `default_image`, `bootstrap_image`, `vcpus`, `mem_mib`, `overlay_disk_mib`, `krun_log_level`, and `guest_tls_*` in `[openshell.drivers.vm]`. The default sandbox image is `nvcr.io/nvidia/base/ubuntu:24.04`. The VM `state_dir` stores overlay disks, console logs, runtime state, image-rootfs cache, and the private `run/compute-driver.sock` socket. The VM socket path is managed by the gateway and is not configurable through remote endpoint settings. The gateway starts `openshell-driver-vm` over a private Unix socket and passes its process ID so the driver can reject unexpected local clients. The driver's standalone TCP listener is disabled unless `--allow-unauthenticated-tcp` is set for local development. diff --git a/e2e/rust/e2e-vm.sh b/e2e/rust/e2e-vm.sh index 8f687e5fed..6fd355170b 100755 --- a/e2e/rust/e2e-vm.sh +++ b/e2e/rust/e2e-vm.sh @@ -51,7 +51,7 @@ DRIVER_BIN="${OPENSHELL_VM_DRIVER_BIN:-${ROOT}/target/debug/openshell-driver-vm} CLI_BIN="${OPENSHELL_BIN:-${ROOT}/target/debug/openshell}" E2E_TEST_OVERRIDE="${OPENSHELL_E2E_VM_TEST:-}" E2E_FEATURES="${OPENSHELL_E2E_VM_FEATURES-e2e-vm}" -SANDBOX_IMAGE="${OPENSHELL_SANDBOX_IMAGE:-${COMMUNITY_SANDBOX_IMAGE:-ghcr.io/nvidia/openshell-community/sandboxes/base:latest}}" +SANDBOX_IMAGE="${OPENSHELL_SANDBOX_IMAGE:-nvcr.io/nvidia/base/ubuntu:24.04}" # The VM driver places `compute-driver.sock` under `[openshell.drivers.vm].state_dir`. # AF_UNIX SUN_LEN is 104 bytes on macOS (108 on Linux), so paths anchored diff --git a/tasks/scripts/gateway-vm.sh b/tasks/scripts/gateway-vm.sh index ff3f1e7dff..c8fda42216 100755 --- a/tasks/scripts/gateway-vm.sh +++ b/tasks/scripts/gateway-vm.sh @@ -39,7 +39,7 @@ PORT="${OPENSHELL_SERVER_PORT:-18081}" GATEWAY_NAME="${OPENSHELL_VM_GATEWAY_NAME:-vm-dev}" STATE_DIR="${OPENSHELL_VM_GATEWAY_STATE_DIR:-${ROOT}/.cache/gateway-vm}" SANDBOX_NAMESPACE="${OPENSHELL_SANDBOX_NAMESPACE:-vm-dev}" -SANDBOX_IMAGE="${OPENSHELL_SANDBOX_IMAGE:-${COMMUNITY_SANDBOX_IMAGE:-ghcr.io/nvidia/openshell-community/sandboxes/base:latest}}" +SANDBOX_IMAGE="${OPENSHELL_SANDBOX_IMAGE:-nvcr.io/nvidia/base/ubuntu:24.04}" VM_BOOTSTRAP_IMAGE="${OPENSHELL_VM_BOOTSTRAP_IMAGE:-}" SANDBOX_IMAGE_PULL_POLICY="${OPENSHELL_SANDBOX_IMAGE_PULL_POLICY:-if_not_present}" # VM currently has no image-pull-policy setting in its driver configuration; unlike diff --git a/tasks/scripts/vm/build-libkrun.sh b/tasks/scripts/vm/build-libkrun.sh index bd40f2f1d5..8058f3605d 100755 --- a/tasks/scripts/vm/build-libkrun.sh +++ b/tasks/scripts/vm/build-libkrun.sh @@ -216,15 +216,25 @@ if [ -f openshell.kconfig ]; then CONFIG_SECURITY \ CONFIG_SECURITY_LANDLOCK \ CONFIG_SECCOMP \ - CONFIG_SECCOMP_FILTER; do - val="$(grep "^${opt}=" "${KERNEL_SOURCES}/.config" 2>/dev/null || true)" - if [ -n "$val" ]; then - echo " ${opt}: ${val#*=}" + CONFIG_SECCOMP_FILTER \ + CONFIG_HARDENED_USERCOPY \ + CONFIG_INIT_STACK_ALL_ZERO \ + CONFIG_INIT_ON_ALLOC_DEFAULT_ON \ + CONFIG_SLAB_FREELIST_RANDOM; do + val="$(grep -E "^(# )?${opt}(=| )" "${KERNEL_SOURCES}/.config" 2>/dev/null || true)" + if [ "$val" = "${opt}=y" ]; then + echo " ${opt}: y" else - echo " WARNING: ${opt} not set after merge!" >&2 + echo " WARNING: ${opt} is not enabled after merge: ${val:-unset}" >&2 all_ok=false fi done + if grep -qx '# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set' "${KERNEL_SOURCES}/.config"; then + echo " CONFIG_INIT_ON_FREE_DEFAULT_ON: disabled" + else + echo " WARNING: CONFIG_INIT_ON_FREE_DEFAULT_ON is not explicitly disabled after merge!" >&2 + all_ok=false + fi lsm_order="$(grep '^CONFIG_LSM=' "${KERNEL_SOURCES}/.config" 2>/dev/null || true)" if [[ "$lsm_order" == *landlock* ]]; then echo " CONFIG_LSM: ${lsm_order#*=}"