Repository navigation
contain: fail closed on incomplete file descriptor cleanup - #328
canbolayir wants to merge 3 commits into
Conversation
|
One data point on the "close_range is available since 5.9" argument from #294/#297: I reproduced it on 4ff54a6 with In |
|
Thanks for working on this FD-sanitization issue. I independently reproduced the high-numbered file-descriptor inheritance problem against NsJail commit I also have regression evidence covering NsJail's TCP listening mode and normal execution when descriptor cleanup succeeds. Would an automated regression test covering high-numbered FD inheritance and cleanup-failure behavior be useful for this PR? I would be happy to contribute focused test coverage without duplicating the existing fix. Thanks! |
|
Added automated regression coverage for high-numbered FD inheritance. The tests pass on Ubuntu 24.04, covering the The CLA and zizmor checks are also green. The remaining upstream workflows require maintainer approval. Could a maintainer review the fix and regression coverage when convenient? Thanks! |
|
Hi @canbolayir, Thanks for adding automated high-FD regression coverage to #328. I've prepared a small, test-only extension to your existing tests that adds The patch changes only Local validation results:
No production code changes are involved. Would you be interested in incorporating this additional regression coverage? I can share the patch or submit a focused contribution using whichever workflow you prefer. Thanks! |
Summary
Ensure that file descriptor cleanup cannot silently leave high-numbered inherited descriptors open across
execve().The existing fallback in
containMakeFdsCOENaive()only scans descriptors 0 through 1023. Ifclose_range(CLOSE_RANGE_CLOEXEC)fails and/proc/self/fdis unavailable after mount/chroot setup, an inheritable descriptor numbered 1024 or higher can therefore survive into the jailed process.This change:
/proc/self/fdbefore mount/chroot setup changes the filesystem view;close_range()fails;Security impact
A high-numbered inherited host descriptor can expose resources that were not explicitly passed with
--pass_fd, including files, sockets, pipes, or directory descriptors.Lowering
RLIMIT_NOFILEdoes not address this because descriptors opened before the limit is lowered remain valid.Reproduction
The issue was reproduced by:
close_range()to returnENOSYS;--disable_procwith a minimal chroot; andBefore this change, the jailed program can read the host-only descriptor.
With this change, the same descriptor does not survive
execve().Relation to #297
This is separate from #297.
The issue here is not primarily support for older kernels. The current containment path already attempts fallback cleanup when
close_range()fails. The problem is that the final fallback can report success while only checking descriptors below 1024.close_range()can also be unavailable to the process because of an outer syscall policy or similar execution environment, even on a kernel that implements it.Validation
f100fd917c6d3ed0fd15d868528b735cb5fb1a1a;git apply --checkpassed;git diff --checkpassed;make clean && make -j2passed.