fix sudo-unshare sandbox: drop privileges after PROC_CLEANUP (#383)
the sudo-unshare sandbox path runs the entire command as root, causing files modified by shell commands (e.g. git merge) to become root-owned. this breaks file_write/file_edit which run in the Node.js parent process as the normal user (EACCES errors). after PROC_CLEANUP (which needs root for umount/mount), drop back to the original user via `su -p` so file operations match the uid of the parent process. security-neutral: PID namespace isolation is the barrier, not privilege level inside it. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
pullfrog[bot]
parent
52ec35790a
commit
f8a871f723
@@ -143922,6 +143922,7 @@ function SelectModeTool(ctx) {
|
||||
import { spawn as spawn2, spawnSync as spawnSync3 } from "node:child_process";
|
||||
import { randomUUID as randomUUID3 } from "node:crypto";
|
||||
import { closeSync, openSync, writeFileSync as writeFileSync7 } from "node:fs";
|
||||
import { userInfo } from "node:os";
|
||||
import { join as join9 } from "node:path";
|
||||
var ShellParams = type({
|
||||
command: "string",
|
||||
@@ -143986,6 +143987,8 @@ function spawnShell(params) {
|
||||
envArgs.push(`${k}=${v}`);
|
||||
}
|
||||
}
|
||||
const username = userInfo().username;
|
||||
const escaped = params.command.replace(/'/g, "'\\''");
|
||||
return spawn2(
|
||||
"sudo",
|
||||
[
|
||||
@@ -143997,7 +144000,7 @@ function spawnShell(params) {
|
||||
"--mount-proc",
|
||||
"bash",
|
||||
"-c",
|
||||
`${PROC_CLEANUP} ${params.command}`
|
||||
`${PROC_CLEANUP} exec su -p -s /bin/bash ${username} -c '${escaped}'`
|
||||
],
|
||||
{ ...spawnOpts, env: {} }
|
||||
);
|
||||
|
||||
+7
-1
@@ -2,6 +2,7 @@
|
||||
import { type ChildProcess, type StdioOptions, spawn, spawnSync } from "node:child_process";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { closeSync, openSync, writeFileSync } from "node:fs";
|
||||
import { userInfo } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { type } from "arktype";
|
||||
import { log } from "../utils/log.ts";
|
||||
@@ -110,6 +111,11 @@ function spawnShell(params: SpawnParams): ChildProcess {
|
||||
envArgs.push(`${k}=${v}`);
|
||||
}
|
||||
}
|
||||
// drop back to original user after PROC_CLEANUP so files aren't owned by root.
|
||||
// sudo is only needed for unshare; the actual command should run as the normal user
|
||||
// to avoid ownership mismatches with file_write/file_edit (which run in the Node.js parent).
|
||||
const username = userInfo().username;
|
||||
const escaped = params.command.replace(/'/g, "'\\''");
|
||||
return spawn(
|
||||
"sudo",
|
||||
[
|
||||
@@ -121,7 +127,7 @@ function spawnShell(params: SpawnParams): ChildProcess {
|
||||
"--mount-proc",
|
||||
"bash",
|
||||
"-c",
|
||||
`${PROC_CLEANUP} ${params.command}`,
|
||||
`${PROC_CLEANUP} exec su -p -s /bin/bash ${username} -c '${escaped}'`,
|
||||
],
|
||||
{ ...spawnOpts, env: {} }
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user