diff --git a/patch/0048-runc-utils-use-close_range-2-to-close-leftover-file-descr.patch b/patch/0048-runc-utils-use-close_range-2-to-close-leftover-file-descr.patch new file mode 100644 index 0000000000000000000000000000000000000000..c6076c2f8aa0f348c3c715002e4f6bcaff49cf45 --- /dev/null +++ b/patch/0048-runc-utils-use-close_range-2-to-close-leftover-file-descr.patch @@ -0,0 +1,70 @@ +From 70f4e46e68d6795863b13743ed6d3895fd721318 Mon Sep 17 00:00:00 2001 +From: Aleksa Sarai +Date: Fri, 7 Jul 2023 15:11:41 +1000 +Subject: [PATCH] utils: use close_range(2) to close leftover file descriptors + +close_range(2) is far more efficient than a readdir of /proc/self/fd and +then doing a syscall for each file descriptor. + +Signed-off-by: Aleksa Sarai +--- + libcontainer/utils/utils_unix.go | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/libcontainer/utils/utils_unix.go b/libcontainer/utils/utils_unix.go +index 220d0b43..6b9a7be0 100644 +--- a/libcontainer/utils/utils_unix.go ++++ b/libcontainer/utils/utils_unix.go +@@ -5,8 +5,10 @@ package utils + + import ( + "fmt" ++ "math" + "os" + "strconv" ++ "sync" + + "golang.org/x/sys/unix" + ) +@@ -23,9 +25,38 @@ func EnsureProcHandle(fh *os.File) error { + return nil + } + ++var ( ++ haveCloseRangeCloexecBool bool ++ haveCloseRangeCloexecOnce sync.Once ++) ++ ++func haveCloseRangeCloexec() bool { ++ haveCloseRangeCloexecOnce.Do(func() { ++ // Make sure we're not closing a random file descriptor. ++ tmpFd, err := unix.FcntlInt(0, unix.F_DUPFD_CLOEXEC, 0) ++ if err != nil { ++ return ++ } ++ defer unix.Close(tmpFd) ++ ++ err = unix.CloseRange(uint(tmpFd), uint(tmpFd), unix.CLOSE_RANGE_CLOEXEC) ++ // Any error means we cannot use close_range(CLOSE_RANGE_CLOEXEC). ++ // -ENOSYS and -EINVAL ultimately mean we don't have support, but any ++ // other potential error would imply that even the most basic close ++ // operation wouldn't work. ++ haveCloseRangeCloexecBool = err == nil ++ }) ++ return haveCloseRangeCloexecBool ++} ++ + // CloseExecFrom applies O_CLOEXEC to all file descriptors currently open for + // the process (except for those below the given fd value). + func CloseExecFrom(minFd int) error { ++ if haveCloseRangeCloexec() { ++ err := unix.CloseRange(uint(minFd), math.MaxUint, unix.CLOSE_RANGE_CLOEXEC) ++ return os.NewSyscallError("close_range", err) ++ } ++ + fdDir, err := os.Open("/proc/self/fd") + if err != nil { + return err +-- +2.43.0 +