mirror of
https://github.com/zap-proto/zip.git
synced 2026-10-19 15:38:57 +00:00
A descriptor is not data: its number is an index into a table the peer does not share, so a byte stream cannot hand over a pipe, a console, or an already-open file. SCM_RIGHTS is the kernel doing that translation, and it rides the same unix connection peerOf already reads SO_PEERCRED from. Needed to carry a sandbox control plane. gVisor's urpc passes Files on 20 of its 22 call sites — exec's stdio, checkpoint restore, the memory file — so a transport without this cannot replace it at all. Refuses rather than half-delivering: an empty body would let the kernel discard a control-only message and lose the descriptors while the call reports success, and a non-unix connection would deliver the bytes without the files. Co-authored-by: Hanzo Dev <[email protected]>
22 lines
666 B
Go
22 lines
666 B
Go
//go:build linux
|
|
|
|
package zip
|
|
|
|
import (
|
|
"os"
|
|
"runtime"
|
|
"syscall"
|
|
)
|
|
|
|
// recvFlags asks the kernel to set close-on-exec as it installs each received
|
|
// descriptor. Doing it here rather than afterwards closes a real window: a
|
|
// concurrent fork between recvmsg and fcntl leaks every descriptor in flight
|
|
// into the child, and nothing about the leak is visible at either end.
|
|
const recvFlags = syscall.MSG_CMSG_CLOEXEC
|
|
|
|
// setCloexec is a no-op on Linux — recvFlags already did it atomically.
|
|
func setCloexec(int) {}
|
|
|
|
// runtimeKeepFiles holds the files alive until the syscall has copied them.
|
|
func runtimeKeepFiles(files []*os.File) { runtime.KeepAlive(files) }
|