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
|
||||
)
|
||||
|
||||
// ensureCloseOnExec ensures all currently open file descriptors have the syscall.FD_CLOEXEC flag 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.
|
||||
// ensureCloseOnExec ensures all currently open file descriptors have the
|
||||
// syscall.FD_CLOEXEC flag 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 {
|
||||
closeOnExecOnce.Do(func() {
|
||||
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)
|
||||
}
|
||||
})
|
||||
closeOnExecOnce.Do(func() { closeOnExecErr = doCloseOnExec() })
|
||||
|
||||
if closeOnExecErr == 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.
|
||||
|
||||
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