From 8354d68947c7753bbf5414330e3654f595b05878 Mon Sep 17 00:00:00 2001 From: Ladislav Smola Date: Tue, 16 Jun 2026 17:37:41 +0200 Subject: [PATCH] feat(sandbox): Landlock TCP port restriction in Platform mode When Platform mode is active, apply Landlock ABI v4 network rules to restrict TCP connect to only the proxy port (default 3128). This makes the loopback CONNECT proxy mandatory at the kernel level. Graceful degradation: if kernel ABI < v4, the network rules are skipped with a warn-level log. Also fixes rules_applied underflow via saturating_sub. Ref: NVIDIA/OpenShell#899 Signed-off-by: Ladislav Smola --- .../src/sandbox/linux/landlock.rs | 42 +++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/crates/openshell-sandbox/src/sandbox/linux/landlock.rs b/crates/openshell-sandbox/src/sandbox/linux/landlock.rs index e7f37ce4f..825cfb2c7 100644 --- a/crates/openshell-sandbox/src/sandbox/linux/landlock.rs +++ b/crates/openshell-sandbox/src/sandbox/linux/landlock.rs @@ -3,10 +3,10 @@ //! Landlock filesystem sandboxing. -use crate::policy::{LandlockCompatibility, SandboxPolicy}; +use crate::policy::{LandlockCompatibility, NetworkMode, SandboxPolicy}; use landlock::{ - ABI, Access, AccessFs, CompatLevel, Compatible, PathBeneath, PathFd, PathFdError, Ruleset, - RulesetAttr, RulesetCreatedAttr, + ABI, Access, AccessFs, AccessNet, CompatLevel, Compatible, NetPort, PathBeneath, PathFd, + PathFdError, Ruleset, RulesetAttr, RulesetCreatedAttr, }; use miette::{IntoDiagnostic, Result}; use std::path::{Path, PathBuf}; @@ -184,6 +184,12 @@ pub fn prepare(policy: &SandboxPolicy, workdir: Option<&str>) -> Result) -> Result { + ruleset = r; + debug!( + port = proxy_port, + "Landlock allow TCP connect (proxy port only)" + ); + rules_applied += 1; + } + Err(e) => { + tracing::warn!( + error = %e, + "Landlock TCP port restriction unavailable (ABI v4 required). \ + Network enforcement degraded: agent can bypass proxy via direct \ + connect(). Upgrade to RHEL 9.6+ for kernel-enforced TCP port restriction." + ); + } + } + } + if rules_applied == 0 { return Err(miette::miette!( "Landlock ruleset has zero valid paths — all {} path(s) failed to open. \ @@ -215,7 +249,7 @@ pub fn prepare(policy: &SandboxPolicy, workdir: Option<&str>) -> Result