Skip to content

Linux worker process sandboxing - #4755

Draft
iang-msft wants to merge 84 commits into
microsoft:mainfrom
iang-msft:main
Draft

iang-msft wants to merge 84 commits into
microsoft:mainfrom
iang-msft:main

Conversation

@iang-msft

Copy link
Copy Markdown

This PR includes several features to enable sandboxing of OpenVMM worker processes on linux hosts.

  1. Sandboxing crate that abstracts platform specifics
  2. Integration of the sandbox crate into worker spawn
  3. Profiling feature to collect syscall and file usage
  4. Base profiles for VM Worker & TPM Worker processes

The profiling features uses ptrace to capture and log syscalls.

The sandboxing crate uses process namespaces created upon process fork, along with landlock and seccomp profiles applied shortly after process spawn.

This change also modifies ttrpc invocations to spawn worker processes instead of using inproc mesh.

iang-msft and others added 30 commits September 4, 2026 13:36
Launch VM and TPM Mesh hosts in Linux user and mount namespaces, adding a network namespace for restricted profiles. Retain PAL's vfork path by self-mapping the effective UID/GID before exec, then apply role-owned policy before tracing and Mesh startup.

Known gaps: VM and TPM profiles remain broad and identical; inherited-handle grants are not wired or enforced; VNC/GDB and non-Linux sandbox backends are not covered; and full VM/TPM boot validation remains outstanding.
Removed references do uncommitted docs.
Removed description, should apply to all workers
Add in-process Linux worker syscall tracing and a sandbox_profile_builder tool that converts worker JSONL traces into candidate sandbox profiles.
Trace only sandbox-profile-relevant syscalls so KVM hot paths run without ptrace stops while preserving syscall results and decoded arguments.
- load platform syscall denials from JSON configuration
- derive filesystem, network, and syscall policies from worker traces
- document the sandbox profiling workflow
- move worker syscall tracing into a separate pal_tracer crate
- derive filesystem, network, and syscall sandbox policies from worker traces
- replace separate syscall-denial rationale documentation with reasons stored alongside each denial in structured JSON
- wire PAL tracing into OpenVMM worker process launch
Generate sandbox profiles automatically from worker traces
Replace the JSON denylist and runtime parsing with static mandatory and optional syscall inventories. Update tracing, profiling, and the sandbox test launcher to consume the shared sandbox policy.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iang-msft and others added 2 commits October 28, 2026 00:37
Mount ancestors before descendants and union compatible permissions across duplicate and nested grants so builder order cannot hide earlier access. Reject overlapping write and execute permissions before filesystem setup. Extend existing runtime tests to exercise both declaration orders, nested permissions, and device grant composition.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 252beba7-825f-475b-9a31-8da82494a58b
Compose filesystem grants before mounting
Copilot AI balanced review requested due to automatic review settings October 28, 2026 00:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

iang-msft and others added 2 commits October 28, 2026 01:09
Scan args_os and match the ASCII role option without requiring unrelated paths to be UTF-8. Keep unknown and duplicate roles as errors, including malformed non-UTF-8 role values, and cover these cases with parser regressions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 252beba7-825f-475b-9a31-8da82494a58b
Handle non-UTF-8 paths during sandbox role scanning
Copilot AI balanced review requested due to automatic review settings October 28, 2026 01:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

iang-msft and others added 2 commits October 28, 2026 01:41
Grant file-specific access for proc maps, worker naming, and the overcommit setting without exposing unrelated proc files. Add an isolated regression that verifies real reads and writes with Landlock enforced.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 252beba7-825f-475b-9a31-8da82494a58b
Allow required implicit proc accesses under Landlock
Copilot AI balanced review requested due to automatic review settings October 28, 2026 01:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

iang-msft and others added 2 commits October 28, 2026 02:13
Reserve Identity UID/GID values for future host identity provisioning and reject explicit requests during preparation. Remove sandbox credential-setting launch fields and reject PAL identity overrides with user namespace self-mapping, while preserving ordinary process identity changes.

Document controller identity inheritance and remove stale claims of per-worker host identity isolation and worker-side UID/GID switching. Cover rejected zero and nonzero requests, default namespace mappings, and ordinary PAL launches.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 252beba7-825f-475b-9a31-8da82494a58b
…tities

Defer unsupported sandbox host identities explicitly
Copilot AI balanced review requested due to automatic review settings October 28, 2026 02:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Comment thread support/sandbox/src/profiles/vm_worker.rs Outdated
Comment on lines +331 to +335
DeniedSyscall {
name: "waitid",
enforcement: MANDATORY,
reason: None,
},
Comment thread support/pal/src/unix/process/linux.rs
Comment thread support/sandbox/src/profiles/vm_worker.rs Outdated
iang-msft and others added 6 commits October 28, 2026 04:31
Replace recursive /etc grants with optional loader, resolver/NSS, and OpenSSL configuration files. Narrow the TPM SSL directory grant as well to prevent aliases from re-exposing private keys, and bind resolver configuration directly without granting its runtime target.

Exercise file access, missing configuration, resolver symlinks, NSS lookup, and denial of private fixtures in isolated namespace tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 252beba7-825f-475b-9a31-8da82494a58b
Request CLONE_NEWIPC for every confined Linux launch, including unrestricted-network profiles. Keep namespace creation required with no weaker fallback.

Exercise SysV shared memory, semaphore, and message queue isolation through real PAL launches for both worker roles and both clone modes. Update namespace documentation and kernel creation-order guidance.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 252beba7-825f-475b-9a31-8da82494a58b
Allocate owner-only staging mountpoints with mkdtemp instead of reusing a fixed host pathname. Remove the backing directory through the old root after pivot_root, and detach all staging mount layers before nonrecursive cleanup on setup errors.

Cover pre-existing files and symlinks, unique private allocations, successful cleanup, mount and grant failures, and stacked root-grant mounts without deleting writable bind contents.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 252beba7-825f-475b-9a31-8da82494a58b
Compile tracing bytecode in the parent so the pre-exec callback only borrows and installs it, without compiling or dropping heap-owned filter state. Return compilation errors from spawn before creating a child instead of silently skipping the tracing filter.

Document the parent-side compilation contract and add an oversized-filter regression. Existing live tracing tests continue to verify successful filter installation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 252beba7-825f-475b-9a31-8da82494a58b
Continue consuming synthetic ptrace and syscall stops, but forward genuine SIGTRAP signals so application handlers and default termination behave normally. Preserve existing SIGSTOP handling.

Add traced child regressions for a SIGTRAP handler and an unhandled SIGTRAP, with core dumps disabled for the latter.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 252beba7-825f-475b-9a31-8da82494a58b
Copilot AI balanced review requested due to automatic review settings October 28, 2026 05:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

fn do_main(pidfile_guard: &mut Option<pidfile::Pidfile>) -> anyhow::Result<i32> {
meshworker::apply_vmm_mesh_host_sandbox()?;

#[cfg(target_os = "linux")]
fn linux_clone_flags(profile: &Profile) -> u64 {
let mut flags = libc::CLONE_NEWUSER | libc::CLONE_NEWNS | libc::CLONE_NEWIPC;
Comment on lines +1307 to +1308
#[cfg(target_os = "linux")]
None,
Comment on lines +53 to +56
let profile = Profile::deny_all()
.name("vm_worker")
.read("/sys/devices")
.read_exec("/usr/lib")
Comment on lines +67 to +71
#[test]
fn network_operations_work_in_namespace() {
let exe = std::env::current_exe().expect("failed to get test executable path");
let output = Command::new("unshare")
.args(["--user", "--map-root-user", "--net"])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Guide unsafe Related to unsafe code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants