(
netns_fd: Option<RawFd>,
policy: &SandboxPolicy,
#[cfg(target_os = "linux")] supervisor_identity_mount: Option<
&crate::process::SupervisorIdentityMountNamespace,
| 1177 | } |
| 1178 | |
| 1179 | fn enter_netns_and_sandbox( |
| 1180 | netns_fd: Option<RawFd>, |
| 1181 | policy: &SandboxPolicy, |
| 1182 | #[cfg(target_os = "linux")] supervisor_identity_mount: Option< |
| 1183 | &crate::process::SupervisorIdentityMountNamespace, |
| 1184 | >, |
| 1185 | #[cfg(target_os = "linux")] prepared: Option<crate::sandbox::linux::PreparedSandbox>, |
| 1186 | ) -> std::io::Result<()> { |
| 1187 | // Enter network namespace before dropping privileges. |
| 1188 | // This ensures SSH shell processes are isolated to the same |
| 1189 | // network namespace as the entrypoint, forcing all traffic |
| 1190 | // through the veth pair and CONNECT proxy. |
| 1191 | #[cfg(target_os = "linux")] |
| 1192 | if let Some(fd) = netns_fd { |
| 1193 | #[allow(unsafe_code)] |
| 1194 | let result = unsafe { libc::setns(fd, libc::CLONE_NEWNET) }; |
| 1195 | if result != 0 { |
| 1196 | return Err(std::io::Error::last_os_error()); |
| 1197 | } |
| 1198 | } |
| 1199 | |
| 1200 | #[cfg(not(target_os = "linux"))] |
| 1201 | let _ = netns_fd; |
| 1202 | |
| 1203 | #[cfg(target_os = "linux")] |
| 1204 | if let Some(mount) = supervisor_identity_mount { |
| 1205 | mount.enter_for_child()?; |
| 1206 | } |
| 1207 | |
| 1208 | // Drop privileges. initgroups/setgid/setuid need /etc/group and |
| 1209 | // /etc/passwd which would be blocked if Landlock were already enforced. |
| 1210 | drop_privileges(policy).map_err(|err| std::io::Error::other(err.to_string()))?; |
| 1211 | crate::process::harden_child_process() |
| 1212 | .map_err(|err| std::io::Error::other(err.to_string()))?; |
| 1213 | |
| 1214 | // Phase 2: Enforce the prepared Landlock ruleset + seccomp. |
| 1215 | // restrict_self() does not require root. |
| 1216 | #[cfg(target_os = "linux")] |
| 1217 | if let Some(prepared) = prepared { |
| 1218 | crate::sandbox::linux::enforce(prepared) |
| 1219 | .map_err(|err| std::io::Error::other(err.to_string()))?; |
| 1220 | } |
| 1221 | |
| 1222 | #[cfg(not(target_os = "linux"))] |
| 1223 | sandbox::apply(policy, None).map_err(|err| std::io::Error::other(err.to_string()))?; |
| 1224 | |
| 1225 | Ok(()) |
| 1226 | } |
| 1227 | } |
| 1228 | |
| 1229 | fn to_u16(value: u32) -> u16 { |
no test coverage detected