Skip to content

refactor: prepare shell-escalation for reusable executors#12614

Closed
bolinfest wants to merge 1 commit intomainfrom
pr12614
Closed

refactor: prepare shell-escalation for reusable executors#12614
bolinfest wants to merge 1 commit intomainfrom
pr12614

Conversation

@bolinfest
Copy link
Copy Markdown
Collaborator

@bolinfest bolinfest commented Feb 23, 2026

Why

PR #12584 became difficult to review as a single feature diff. This PR isolates the shell-escalation prep work so later exec-server and core changes can be reviewed against a stable API.

The main goal is to make shell-escalation reusable from multiple callers without hard-coding a dependency on codex-core internals.

What Changed

  • Introduce a reusable executor interface in shell-escalation (ShellCommandExecutor) and thread it through unix::escalate_server::run_escalate_server.
  • Move sandbox execution inputs needed by shell-escalation into a crate-local SandboxState type.
  • Open up the unix module API surface needed by downstream callers (pub mod unix, public ShellEscalationPolicy).
  • Tighten socket handling in unix/socket.rs (explicit try_io error handling and Socket::pair_raw for Unix socketpairs).
  • Add a temporary compatibility shim in shell-escalation/src/lib.rs so existing callers continue to build while the stacked follow-up PRs land.

Verification

  • No standalone verification run after splitting this prep refactor out of the larger zsh-fork change.
  • The follow-up stacked PRs adopt this API (#12615 and the remaining core/test changes), which exercises the integration path.

Stack created with Sapling. Best reviewed with ReviewStack.

Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 97687a49a5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


pub fn pair() -> std::io::Result<(Self, Self)> {
let (server, client) = Socket::pair(Domain::UNIX, Type::DGRAM, None)?;
let (server, client) = Socket::pair_raw(Domain::UNIX, Type::DGRAM, None)?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restore CLOEXEC on the datagram server endpoint

Switching AsyncDatagramSocket::pair() to Socket::pair_raw makes both ends inheritable across exec, but EscalateServer::exec only intends to pass the client FD via ESCALATE_SOCKET_ENV_VAR. With this change, the spawned shell also inherits the server endpoint, so a child process can consume handshake datagrams (and their passed stream FDs) before escalate_task reads them, causing flaky escalation handshakes and policy-server bypass/DoS behavior in real command trees.

Useful? React with 👍 / 👎.


pub fn pair() -> std::io::Result<(AsyncSocket, AsyncSocket)> {
let (server, client) = Socket::pair(Domain::UNIX, Type::STREAM, None)?;
let (server, client) = Socket::pair_raw(Domain::UNIX, Type::STREAM, None)?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep stream control sockets close-on-exec

Changing AsyncSocket::pair() to Socket::pair_raw removes close-on-exec for the control channel used by escalate_client::run. In the EscalateAction::Run path, that process immediately calls execv, so the target command now inherits internal escalation stream FDs that were previously dropped on exec; long-lived/daemonized commands can retain these descriptors and unexpectedly keep internal channels alive.

Useful? React with 👍 / 👎.

@bolinfest bolinfest force-pushed the pr12614 branch 4 times, most recently from a4a59f9 to 420df62 Compare February 24, 2026 01:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant