Files
zip/childsig_linux.go
zeekayandHanzo Dev 5f283eb742 fix: a plugin must not outlive the host that started it
Graceful Shutdown already stops every child. A host that is SIGKILLed,
OOM-killed, or crashes never runs its hooks — and a plugin is a separate
process, so it kept running, kept holding its unix socket, and kept serving
requests for a host that no longer existed. Orphaned plugins on stale sockets
are the one way a subprocess plugin is genuinely more dangerous than a
linked-in one, so it is worth the platform-specific code.

Children are now started with Pdeathsig on Linux: the kernel signals them when
their parent dies, whether or not the parent got to say so. Non-Linux builds
get a documented no-op — Shutdown still covers every ordinary exit path there.

Found by noticing empty /tmp/zip-* directories left behind by hosts that had
been killed rather than shut down.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 13:23:24 -07:00

26 lines
814 B
Go

//go:build linux
package zip
import (
"os/exec"
"syscall"
)
// tieToHost makes the kernel signal this child when its host dies.
//
// Graceful Shutdown already stops every child, but a host that is SIGKILLed,
// OOM-killed, or crashes never runs its hooks — and a plugin is a separate
// process, so it would keep running, keep holding its socket, and keep serving
// requests for a host that no longer exists. Pdeathsig closes that: the child
// dies with the parent whether or not the parent got to say so.
//
// This is the one place a subprocess plugin is genuinely more dangerous than a
// linked-in one, so it is worth the platform-specific code.
func tieToHost(cmd *exec.Cmd) {
if cmd.SysProcAttr == nil {
cmd.SysProcAttr = &syscall.SysProcAttr{}
}
cmd.SysProcAttr.Pdeathsig = syscall.SIGTERM
}