Skip to content

exec: add optional --exec-wait-fifo#5375

Open
cpuguy83 wants to merge 1 commit into
opencontainers:mainfrom
cpuguy83:exec-wait-fifo
Open

exec: add optional --exec-wait-fifo#5375
cpuguy83 wants to merge 1 commit into
opencontainers:mainfrom
cpuguy83:exec-wait-fifo

Conversation

@cpuguy83

@cpuguy83 cpuguy83 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes #5373
Alternative to implementing full create/start split as suggested in #3453

When you run runc exec --detach you can already get the new process's pidfd (--pidfd-socket) and pid (--pid-file) before it runs, but nothing actually holds the process there. The program can execve, and possibly exit, before whatever is supervising it has finished adopting it. I didn't want to build out a whole create/start style lifecycle for exec just to get that, when all it really needs is a single wait point right before execve.

So this adds an opt-in --exec-wait-fifo <path>. The caller creates and owns the fifo. runc passes it into the setns process, which does all of its normal setup and then, just before execve, opens the fifo for writing. That open blocks until something opens the read end, so a supervisor can finish its handoff and then open the fifo to let the program run. We write a byte and exec.

It's the same handshake create/start already use with the internal exec.fifo, so this reuses that path (awaitExecFifo) instead of adding another one.

Typical flow for a supervisor:

  • exec with --detach, --pid-file, --pidfd-socket, --exec-wait-fifo
  • grab the pidfd, wait for runc to return
  • adopt the (still paused) process
  • open the fifo's read end
  • the program runs, same pid

Added an integration test covering the wait behavior plus the not-a-fifo and missing-path errors.

@cpuguy83 cpuguy83 changed the title exec: add optional --exec-wait-fifo synchronization point exec: add optional --exec-wait-fifo Jul 17, 2026
When you run exec with --detach you can already get the new process's
pidfd and pid before it runs, but nothing actually holds the process
there. The program can execve, and possibly exit, before whatever is
supervising it has finished adopting it. I didn't want to build out a
whole create/start style lifecycle for exec just to get that, when all
it really needs is a single wait point right before execve.

So this adds an opt-in --exec-wait-fifo <path>. The caller creates and
owns the fifo. runc passes it into the setns process, which does all of
its normal setup and then, just before execve, opens the fifo for
writing. That open blocks until something opens the read end, so a
supervisor can finish its handoff and then open the fifo to let the
program run. We write a byte and exec.

It's the same handshake create/start already use with the internal
exec.fifo, so this reuses that path (awaitExecFifo) instead of adding
another one. The O_PATH fd is closed before execve so the CVE-2016-9962
workaround still holds on old kernels. Nothing changes when the flag
isn't set.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
@kolyshkin

Copy link
Copy Markdown
Contributor

I'd rather address #5251 first -- we keep adding code into this area and it's getting more and more complicated and harder to follow.

@cyphar PTAL

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.

Add an optional pre-exec wait FIFO to runc exec

2 participants