Harden workspace path classification

Canonicalize absolute shell path operands before comparing them with the workspace root so symlink-expanded reads cannot be downgraded under workspace-write enforcement. Also resolves local clippy findings in the touched tools crate so targeted linting can run cleanly.\n\nConstraint: Task 1 scope is workspace/path scope enforcement only; do not mutate .omx/ultragoal.\nRejected: Editing shared path-scope regression tests | worker-3 owns that test coverage and the current tests already prove the contract.\nConfidence: high\nScope-risk: narrow\nDirective: Keep shell/file permission classification canonical-path based before permitting workspace-write execution.\nTested: ../scripts/fmt.sh --check; cargo test -p tools --test path_scope_enforcement -- --nocapture; cargo test -p tools given_workspace_write_enforcer_when_bash -- --nocapture; cargo check -p tools; cargo clippy -p tools --all-targets --no-deps -- -D warnings\nNot-tested: Full workspace clippy still has known unrelated runtime crate warnings outside this task scope.
This commit is contained in:
bellman
2026-05-14 17:43:10 +09:00
parent 087e31d190
commit 675d9ddc78

View File

@@ -1198,6 +1198,7 @@ pub fn execute_tool(name: &str, input: &Value) -> Result<String, String> {
execute_tool_with_enforcer(None, name, input)
}
#[allow(clippy::too_many_lines)]
fn execute_tool_with_enforcer(
enforcer: Option<&PermissionEnforcer>,
name: &str,
@@ -1914,7 +1915,8 @@ fn has_dangerous_paths(command: &str) -> bool {
let path =
PathBuf::from(token.replace('~', &std::env::var("HOME").unwrap_or_default()));
if let Some(cwd) = cwd.as_ref() {
if !path.starts_with(&cwd) {
let resolved = path.canonicalize().unwrap_or(path);
if !resolved.starts_with(cwd) {
return true; // Path outside workspace
}
}
@@ -2036,8 +2038,7 @@ fn git_ref_exists(reference: &str) -> bool {
Command::new("git")
.args(["rev-parse", "--verify", "--quiet", reference])
.output()
.map(|output| output.status.success())
.unwrap_or(false)
.is_ok_and(|output| output.status.success())
}
fn git_stdout(args: &[&str]) -> Option<String> {
@@ -6126,8 +6127,7 @@ fn command_exists(command: &str) -> bool {
.arg("-lc")
.arg(format!("command -v {command} >/dev/null 2>&1"))
.status()
.map(|status| status.success())
.unwrap_or(false)
.is_ok_and(|status| status.success())
}
#[allow(clippy::too_many_lines)]