Skip to content

Commit 8eca122

Browse files
nixprimegvisor-bot
authored andcommitted
embeddedbinary: fix ForkExec flake
PiperOrigin-RevId: 822752112
1 parent c952130 commit 8eca122

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

tools/embeddedbinary/embeddedbinary_template.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,21 @@ func run(options *Options, fork bool) (int, error) {
141141
if _, err := unix.Seek(tmpFD, 0, unix.SEEK_SET); err != nil {
142142
return 0, fmt.Errorf("cannot seek temp file back to 0: %w", err)
143143
}
144-
fdPath := fmt.Sprintf("/proc/self/fd/%d", tmpFD)
145144
if fork {
145+
// Go's syscall/exec_linux.go:forkAndExecInChild1() can clobber FDs
146+
// outside of syscall.ProcAttr.Files, including tmpFD, so the FD that
147+
// the child execs must be in syscall.ProcAttr.Files to ensure that
148+
// it's valid at time of execve().
149+
childTmpFD := len(options.Files)
150+
files := append(options.Files, uintptr(tmpFD))
151+
fdPath := fmt.Sprintf("/proc/self/fd/%d", childTmpFD)
146152
return syscall.ForkExec(fdPath, options.Argv, &syscall.ProcAttr{
147153
Env: options.Envv,
148-
Files: options.Files,
154+
Files: files,
149155
Sys: options.SysProcAttr,
150156
})
151157
}
158+
fdPath := fmt.Sprintf("/proc/self/fd/%d", tmpFD)
152159
if err := unix.Exec(fdPath, options.Argv, options.Envv); err != nil {
153160
return 0, fmt.Errorf("cannot exec embedded binary: %w", err)
154161
}

0 commit comments

Comments
 (0)