-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Description
We have a test that started failing against runc 1.3.4. It tries to run a process via runc that will exhaust file descriptors, to validate the RLIMIT_NOFILE we provided the container. In 1.3.3 (and 1.3.2), we see this error returned:
runc exec: exit status 255: exec failed: unable to start container process: error loading seccomp filter into kernel: error patching filter: error disassembling original filter: error creating scratch pipe: pipe2: too many open files
However starting in 1.3.4, we get a stack trace:
runtime: eventfd failed with 18446744073709551592
fatal error: runtime: eventfd failed
goroutine 1 gp=0xc000002380 m=0 mp=0x7f1ea67d8ac0 [running, locked to thread]:
runtime.throw({0x7f1ea61f2c33?, 0x200000003?})
runtime/panic.go:1094 +0x4a fp=0xc000147520 sp=0xc0001474f0 pc=0x7f1ea5cb7faa
runtime.netpollinit()
runtime/netpoll_epoll.go:31 +0x14e fp=0xc000147590 sp=0xc000147520 pc=0x7f1ea5c7c42e
runtime.netpollGenericInit()
runtime/netpoll.go:224 +0x35 fp=0xc0001475a8 sp=0xc000147590 pc=0x7f1ea5c7b975
internal/poll.runtime_pollServerInit()
runtime/netpoll.go:215 +0xf fp=0xc0001475b8 sp=0xc0001475a8 pc=0x7f1ea5cb6aef
sync.(*Once).doSlow(0x7f1e00000000?, 0xc000147640?)
sync/once.go:78 +0xac fp=0xc000147610 sp=0xc0001475b8 pc=0x7f1ea5cd5a4c
sync.(*Once).Do(...)
sync/once.go:69
internal/poll.(*pollDesc).init(0xc000026260, 0xc000026240)
internal/poll/fd_poll_runtime.go:39 +0x3c fp=0xc000147630 sp=0xc000147610 pc=0x7f1ea5d32cdc
internal/poll.(*FD).Init(0xc000026240, {0x7f1ea61e7400?, 0x7f1ea5d10254?}, 0x0?)
internal/poll/fd_unix.go:66 +0x45 fp=0xc000147650 sp=0xc000147630 pc=0x7f1ea5d33bc5
os.newFile(0x7, {0x7f1ea61e7066, 0x2}, 0x2, 0x0)
os/file_unix.go:218 +0x15d fp=0xc000147690 sp=0xc000147650 pc=0x7f1ea5d425dd
os.Pipe()
os/pipe2_unix.go:21 +0xb8 fp=0xc0001476f0 sp=0xc000147690 pc=0x7f1ea5d44f38
github.com/opencontainers/runc/libcontainer/seccomp/patchbpf.disassembleFilter(0xc0000a1920)
github.com/opencontainers/runc@v1.4.0/libcontainer/seccomp/patchbpf/enosys_linux.go:144 +0x53 fp=0xc0001477c8 sp=0xc0001476f0 pc=0x7f1ea5fcd0d3
github.com/opencontainers/runc/libcontainer/seccomp/patchbpf.enosysPatchFilter(0xc0000e2880, 0xc000147800?)
github.com/opencontainers/runc@v1.4.0/libcontainer/seccomp/patchbpf/enosys_linux.go:623 +0x2a fp=0xc000147898 sp=0xc0001477c8 pc=0x7f1ea5fcf60a
github.com/opencontainers/runc/libcontainer/seccomp/patchbpf.PatchAndLoad(0xc0000e2880, 0xc0000a1920)
github.com/opencontainers/runc@v1.4.0/libcontainer/seccomp/patchbpf/enosys_linux.go:719 +0x25 fp=0xc000147910 sp=0xc000147898 pc=0x7f1ea5fcfd65
github.com/opencontainers/runc/libcontainer/seccomp.InitSeccomp(0xc0000e2880)
github.com/opencontainers/runc@v1.4.0/libcontainer/seccomp/seccomp_linux.go:126 +0x518 fp=0xc0001479a8 sp=0xc000147910 pc=0x7f1ea5fd12d8
github.com/opencontainers/runc/libcontainer.(*linuxSetnsInit).Init(0xc000147b30)
github.com/opencontainers/runc@v1.4.0/libcontainer/setns_init_linux.go:111 +0x4db fp=0xc000147ac8 sp=0xc0001479a8 pc=0x7f1ea5fff5db
github.com/opencontainers/runc/libcontainer.containerInit({0xc00002a017, 0x5}, 0xc0000f85a0, 0xc00002c040, 0x0, 0x0, 0x0, 0xc00004a018)
github.com/opencontainers/runc@v1.4.0/libcontainer/init_linux.go:252 +0xf7 fp=0xc000147b78 sp=0xc000147ac8 pc=0x7f1ea5fe6bd7
github.com/opencontainers/runc/libcontainer.startInitialization()
github.com/opencontainers/runc@v1.4.0/libcontainer/init_linux.go:235 +0x81a fp=0xc000147dd0 sp=0xc000147b78 pc=0x7f1ea5fe663a
github.com/opencontainers/runc/libcontainer.Init()
github.com/opencontainers/runc@v1.4.0/libcontainer/init_linux.go:109 +0x25 fp=0xc000147e18 sp=0xc000147dd0 pc=0x7f1ea5fe5dc5
main.init.0()
github.com/opencontainers/runc@v1.4.0/init.go:14 +0x33 fp=0xc000147e28 sp=0xc000147e18 pc=0x7f1ea60a7e73
runtime.doInit1(0x7f1ea67ad840)
runtime/proc.go:7670 +0xd7 fp=0xc000147f50 sp=0xc000147e28 pc=0x7f1ea5c928b7
runtime.doInit(...)
runtime/proc.go:7637
runtime.main()
runtime/proc.go:256 +0x350 fp=0xc000147fe0 sp=0xc000147f50 pc=0x7f1ea5c83630
runtime.goexit({})
runtime/asm_amd64.s:1693 +0x1 fp=0xc000147fe8 sp=0xc000147fe0 pc=0x7f1ea5cbff41
Our tests use NOFILE limit of 10. Increasing this to 20 allows the container to create, and run through the test code, failing on the 11th FD. We can decrease NOFILE down to 14, at which point the container creation failures resume. It would appear that in our case (or maybe all?) we need 14 FDs for runc to create the container, but after creating, 10 remain in use inside the container processes, as at the NOFILE value of 15, we get a container, and the test process is able to open 5 FDs before failing.
Steps to reproduce the issue
- Create a container on runc 1.3.4 and 1.3.3 with a NOFILE limit of 10, 14, 15, 20, and 12.
- Have the container run the following:
User: "root",
Path: "sh",
Args: "-c", `
set -e
# must start after fd 2
exec 10<>file1
exec 11<>file2
exec 12<>file3
exec 13<>file4
exec 14<>file5
exec 15<>file6
exec 16<>file7
exec 17<>file8
exec 18<>file9
exec 19<>file10
exec 20<>file11
echo should have died by now
`,
Describe the results you received and expected
At a minimum, runc should return the error it previously returned, rather than panicking.
I don't know if the NOFILE limit should apply to runc while it creates the container or not, but ideally it would at least set a minimum value for that limit which returns an error if it's too small for it to create a container, if that is something that runc can determine.
What version of runc are you using?
1.3.4.
Host OS information
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
Host kernel information
Linux d56a88a5-8e16-4cb0-a838-91d3fdf523ed 5.15.0-161-generic #171-Ubuntu SMP Sat Oct 11 08:17:01 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux