diff --git a/crates/openshell-sandbox/src/sandbox/linux/landlock.rs b/crates/openshell-sandbox/src/sandbox/linux/landlock.rs index 214fc700a..6b121e0ca 100644 --- a/crates/openshell-sandbox/src/sandbox/linux/landlock.rs +++ b/crates/openshell-sandbox/src/sandbox/linux/landlock.rs @@ -119,6 +119,45 @@ pub fn prepare(policy: &SandboxPolicy, workdir: Option<&str>) -> Result { + openshell_ocsf::ocsf_emit!( + openshell_ocsf::DetectionFindingBuilder::new(crate::ocsf_ctx()) + .activity(openshell_ocsf::ActivityId::Open) + .severity(openshell_ocsf::SeverityId::High) + .confidence(openshell_ocsf::ConfidenceId::High) + .is_alert(true) + .finding_info( + openshell_ocsf::FindingInfo::new( + "landlock-unavailable", + "Landlock Filesystem Sandbox Unavailable", + ) + .with_desc(&format!( + "Running WITHOUT filesystem restrictions: Landlock is {availability}. \ + Set landlock.compatibility to 'hard_requirement' to make this fatal." + )), + ) + .message(format!( + "Landlock filesystem sandbox unavailable: {availability}" + )) + .build() + ); + return Ok(None); + } + LandlockCompatibility::HardRequirement => { + return Err(miette::miette!( + "Landlock unavailable in hard_requirement mode: {availability}" + )); + } + } + } + let total_paths = read_only.len() + read_write.len(); let abi = ABI::V2; openshell_ocsf::ocsf_emit!( @@ -135,8 +174,6 @@ pub fn prepare(policy: &SandboxPolicy, workdir: Option<&str>) -> Result = (|| { let access_all = AccessFs::from_all(abi); let access_read = AccessFs::from_read(abi);