From 15e099319e144c0618852c1d5861b73cb1bb09aa Mon Sep 17 00:00:00 2001 From: Ladislav Smola Date: Wed, 17 Jun 2026 17:13:11 +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). Graceful degradation: handle_access(ConnectTcp) and add_rule(NetPort) failures are caught independently -- filesystem sandboxing continues even if TCP port restriction is unavailable (ABI < v4). Also fixes rules_applied underflow via saturating_sub. Ref: NVIDIA/OpenShell#899 Signed-off-by: Ladislav Smola --- .../src/sandbox/linux/landlock.rs | 56 +++++++++++++++++-- 1 file changed, 52 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..428675ebb 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,26 @@ pub fn prepare(policy: &SandboxPolicy, workdir: Option<&str>) -> Result { + ruleset = r; + tcp_handled = true; + } + Err(e) => { + tracing::warn!( + error = %e, + "Landlock handle_access(ConnectTcp) failed (ABI v4 required). \ + TCP port restriction will not be applied." + ); + } + } + } + let mut ruleset = ruleset.create().into_diagnostic()?; let mut rules_applied: usize = 0; @@ -207,6 +227,34 @@ pub fn prepare(policy: &SandboxPolicy, workdir: Option<&str>) -> 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. \ + 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 +263,7 @@ pub fn prepare(policy: &SandboxPolicy, workdir: Option<&str>) -> Result