mirror of
https://github.com/openai/codex.git
synced 2026-09-14 11:57:03 +00:00
Merge 9c3cbc35b4 into sapling-pr-archive-bolinfest
This commit is contained in:
@@ -1,3 +1,51 @@
|
||||
//! Unix shell-escalation protocol implementation.
|
||||
//!
|
||||
//! A patched shell invokes an exec wrapper on every `exec()` attempt. The wrapper sends an
|
||||
//! `EscalateRequest` over the inherited `CODEX_ESCALATE_SOCKET`, and the server decides whether to
|
||||
//! run the command directly (`Run`) or execute it on the server side (`Escalate`).
|
||||
//!
|
||||
//! ### Escalation flow
|
||||
//!
|
||||
//! Command Server Shell Execve Wrapper
|
||||
//! |
|
||||
//! o----->o
|
||||
//! | |
|
||||
//! | o--(exec)-->o
|
||||
//! | | |
|
||||
//! |o<-(EscalateReq)--o
|
||||
//! || | |
|
||||
//! |o--(Escalate)---->o
|
||||
//! || | |
|
||||
//! |o<---------(fds)--o
|
||||
//! || | |
|
||||
//! o<------o | |
|
||||
//! | || | |
|
||||
//! x------>o | |
|
||||
//! || | |
|
||||
//! |x--(exit code)--->o
|
||||
//! | | |
|
||||
//! | o<--(exit)--x
|
||||
//! | |
|
||||
//! o<-----x
|
||||
//!
|
||||
//! ### Non-escalation flow
|
||||
//!
|
||||
//! Server Shell Execve Wrapper Command
|
||||
//! |
|
||||
//! o----->o
|
||||
//! | |
|
||||
//! | o--(exec)-->o
|
||||
//! | | |
|
||||
//! |o<-(EscalateReq)--o
|
||||
//! || | |
|
||||
//! |o-(Run)---------->o
|
||||
//! | | |
|
||||
//! | | x--(exec)-->o
|
||||
//! | | |
|
||||
//! | o<--------------(exit)--x
|
||||
//! | |
|
||||
//! o<-----x
|
||||
//!
|
||||
pub mod escalate_client;
|
||||
pub mod escalate_protocol;
|
||||
pub mod escalate_server;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Launches the codex-exec-mcp-server binary bundled in this package.
|
||||
// Reports the path to the appropriate Bash binary bundled in this package.
|
||||
|
||||
import { spawn } from "node:child_process";
|
||||
import { accessSync, constants } from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { resolveBashPath } from "./bashSelection";
|
||||
@@ -12,8 +10,6 @@ async function main(): Promise<void> {
|
||||
const targetTriple = resolveTargetTriple(process.platform, process.arch);
|
||||
const vendorRoot = path.resolve(__dirname, "..", "vendor");
|
||||
const targetRoot = path.join(vendorRoot, targetTriple);
|
||||
const execveWrapperPath = path.join(targetRoot, "codex-execve-wrapper");
|
||||
const serverPath = path.join(targetRoot, "codex-exec-mcp-server");
|
||||
|
||||
const osInfo = process.platform === "linux" ? readOsRelease() : null;
|
||||
const { path: bashPath } = resolveBashPath(
|
||||
@@ -23,70 +19,7 @@ async function main(): Promise<void> {
|
||||
osInfo,
|
||||
);
|
||||
|
||||
[execveWrapperPath, serverPath, bashPath].forEach((checkPath) => {
|
||||
try {
|
||||
accessSync(checkPath, constants.F_OK);
|
||||
} catch {
|
||||
throw new Error(`Required binary missing: ${checkPath}`);
|
||||
}
|
||||
});
|
||||
|
||||
const args = [
|
||||
"--execve",
|
||||
execveWrapperPath,
|
||||
"--bash",
|
||||
bashPath,
|
||||
...process.argv.slice(2),
|
||||
];
|
||||
const child = spawn(serverPath, args, {
|
||||
stdio: "inherit",
|
||||
});
|
||||
|
||||
const forwardSignal = (signal: NodeJS.Signals) => {
|
||||
if (child.killed) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
child.kill(signal);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
};
|
||||
|
||||
(["SIGINT", "SIGTERM", "SIGHUP"] as const).forEach((sig) => {
|
||||
process.on(sig, () => forwardSignal(sig));
|
||||
});
|
||||
|
||||
child.on("error", (err) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
const childResult = await new Promise<
|
||||
| { type: "signal"; signal: NodeJS.Signals }
|
||||
| { type: "code"; exitCode: number }
|
||||
>((resolve) => {
|
||||
child.on("exit", (code, signal) => {
|
||||
if (signal) {
|
||||
resolve({ type: "signal", signal });
|
||||
} else {
|
||||
resolve({ type: "code", exitCode: code ?? 1 });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (childResult.type === "signal") {
|
||||
// This environment running under `node --test` may not allow rethrowing a signal.
|
||||
// Wrap in a try to avoid masking the original termination reason.
|
||||
try {
|
||||
process.kill(process.pid, childResult.signal);
|
||||
} catch {
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
process.exit(childResult.exitCode);
|
||||
}
|
||||
console.log(`Platform Bash is: ${bashPath}`);
|
||||
}
|
||||
|
||||
void main().catch((err) => {
|
||||
|
||||
Reference in New Issue
Block a user