mirror of
https://github.com/instructkr/claude-code.git
synced 2026-04-06 03:08:48 +03:00
fix(sandbox): probe unshare capability instead of binary existence
On GitHub Actions runners, `unshare` binary exists at /usr/bin/unshare
but user namespaces (CLONE_NEWUSER) are restricted, causing `unshare
--user --map-root-user` to silently fail. This produced empty stdout
in the bash_stdout_roundtrip parity test (mock_parity_harness.rs:533).
Replace the simple `command_exists("unshare")` check with
`unshare_user_namespace_works()` that actually probes whether
`unshare --user --map-root-user true` succeeds. Result is cached
via OnceLock so the probe runs at most once per process.
Fixes: CI red on main@85c5b0e (Rust CI run 23933274144)
This commit is contained in:
@@ -161,7 +161,7 @@ pub fn resolve_sandbox_status(config: &SandboxConfig, cwd: &Path) -> SandboxStat
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn resolve_sandbox_status_for_request(request: &SandboxRequest, cwd: &Path) -> SandboxStatus {
|
pub fn resolve_sandbox_status_for_request(request: &SandboxRequest, cwd: &Path) -> SandboxStatus {
|
||||||
let container = detect_container_environment();
|
let container = detect_container_environment();
|
||||||
let namespace_supported = cfg!(target_os = "linux") && command_exists("unshare");
|
let namespace_supported = cfg!(target_os = "linux") && unshare_user_namespace_works();
|
||||||
let network_supported = namespace_supported;
|
let network_supported = namespace_supported;
|
||||||
let filesystem_active =
|
let filesystem_active =
|
||||||
request.enabled && request.filesystem_mode != FilesystemIsolationMode::Off;
|
request.enabled && request.filesystem_mode != FilesystemIsolationMode::Off;
|
||||||
@@ -282,6 +282,27 @@ fn command_exists(command: &str) -> bool {
|
|||||||
.is_some_and(|paths| env::split_paths(&paths).any(|path| path.join(command).exists()))
|
.is_some_and(|paths| env::split_paths(&paths).any(|path| path.join(command).exists()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check whether `unshare --user` actually works on this system.
|
||||||
|
/// On some CI environments (e.g. GitHub Actions), the binary exists but
|
||||||
|
/// user namespaces are restricted, causing silent failures.
|
||||||
|
fn unshare_user_namespace_works() -> bool {
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
static RESULT: OnceLock<bool> = OnceLock::new();
|
||||||
|
*RESULT.get_or_init(|| {
|
||||||
|
if !command_exists("unshare") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::process::Command::new("unshare")
|
||||||
|
.args(["--user", "--map-root-user", "true"])
|
||||||
|
.stdin(std::process::Stdio::null())
|
||||||
|
.stdout(std::process::Stdio::null())
|
||||||
|
.stderr(std::process::Stdio::null())
|
||||||
|
.status()
|
||||||
|
.map(|s| s.success())
|
||||||
|
.unwrap_or(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{
|
use super::{
|
||||||
|
|||||||
Reference in New Issue
Block a user