forked from rosa/hakurei
container: set CLOEXEC via close_range
This is guarded behind the close_range build tag for now. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -186,31 +186,24 @@ var (
|
|||||||
closeOnExecErr error
|
closeOnExecErr error
|
||||||
)
|
)
|
||||||
|
|
||||||
// ensureCloseOnExec ensures all currently open file descriptors have the syscall.FD_CLOEXEC flag set.
|
// ensureCloseOnExec ensures all currently open file descriptors have the
|
||||||
// This is only ran once as it is intended to handle files left open by the parent, and any file opened
|
// syscall.FD_CLOEXEC flag set.
|
||||||
// on this side should already have syscall.FD_CLOEXEC set.
|
//
|
||||||
|
// This is only ran once as it is intended to handle files left open by the
|
||||||
|
// parent, and any file opened on this side should already have
|
||||||
|
// syscall.FD_CLOEXEC set.
|
||||||
func ensureCloseOnExec() error {
|
func ensureCloseOnExec() error {
|
||||||
closeOnExecOnce.Do(func() {
|
closeOnExecOnce.Do(func() { closeOnExecErr = doCloseOnExec() })
|
||||||
const fdPrefixPath = "/proc/self/fd/"
|
|
||||||
|
|
||||||
var entries []os.DirEntry
|
|
||||||
if entries, closeOnExecErr = os.ReadDir(fdPrefixPath); closeOnExecErr != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var fd int
|
|
||||||
for _, ent := range entries {
|
|
||||||
if fd, closeOnExecErr = strconv.Atoi(ent.Name()); closeOnExecErr != nil {
|
|
||||||
break // not reached
|
|
||||||
}
|
|
||||||
CloseOnExec(fd)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if closeOnExecErr == nil {
|
if closeOnExecErr == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &StartError{Fatal: true, Step: "set FD_CLOEXEC on all open files", Err: closeOnExecErr, Passthrough: true}
|
return &StartError{
|
||||||
|
Fatal: true,
|
||||||
|
Step: "set FD_CLOEXEC on all open files",
|
||||||
|
Err: closeOnExecErr,
|
||||||
|
Passthrough: true,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start starts the container init. The init process blocks until Serve is called.
|
// Start starts the container init. The init process blocks until Serve is called.
|
||||||
|
|||||||
11
container/syscall_close_range.go
Normal file
11
container/syscall_close_range.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
//go:build close_range
|
||||||
|
|
||||||
|
package container
|
||||||
|
|
||||||
|
import "hakurei.app/ext"
|
||||||
|
|
||||||
|
// doCloseOnExec implements ensureCloseOnExec by calling CloseRange with
|
||||||
|
// CLOSE_RANGE_CLOEXEC.
|
||||||
|
func doCloseOnExec() error {
|
||||||
|
return ext.CloseRange(0, ext.MaxUint, ext.CLOSE_RANGE_CLOEXEC)
|
||||||
|
}
|
||||||
28
container/syscall_range_proc.go
Normal file
28
container/syscall_range_proc.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
//go:build !close_range
|
||||||
|
|
||||||
|
package container
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"hakurei.app/container/fhs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// doCloseOnExec implements ensureCloseOnExec by ranging over proc_pid_fd(5).
|
||||||
|
func doCloseOnExec() error {
|
||||||
|
entries, err := os.ReadDir(fhs.ProcSelf + "fd/")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var fd int
|
||||||
|
for _, ent := range entries {
|
||||||
|
if fd, err = strconv.Atoi(ent.Name()); err != nil {
|
||||||
|
return err // not reached
|
||||||
|
}
|
||||||
|
syscall.CloseOnExec(fd)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user