Component: src/rawposix/src/fs_calls.rs (fcntl_syscall, F_DUPFD and F_DUPFD_CLOEXEC arms)
Severity: POSIX conformance
Found by: CONC-005a (#1304), conc_005_fd_exhaustion_isolation.c
Symptom
A cage at its virtual fd table limit cannot be distinguished from one that was handed
an invalid descriptor: both return EBADF. POSIX requires EMFILE for the former.
Well-behaved applications that retry after closing something instead treat the fd as
bad and give up.
Root cause
// src/rawposix/src/fs_calls.rs, F_DUPFD arm (~1451) and F_DUPFD_CLOEXEC arm (~1470)
Err(_) => return syscall_error(Errno::EBADF, "fcntl", "Bad File Descriptor"),
vfd_arg has already been validated by _fcntl_helper before this point, so the only
way the allocation can fail is a full table, which is EMFILE by definition.
Proposed fix
- Err(_) => return syscall_error(Errno::EBADF, "fcntl", "Bad File Descriptor"),
+ // `vfd_arg` was already validated by `_fcntl_helper` above, so the only
+ // way this allocation fails is a full virtual fd table: that is EMFILE,
+ // not EBADF. Reporting EBADF here made an exhausted cage look like it
+ // had been handed a bad descriptor.
+ Err(_) => return syscall_error(Errno::EMFILE, "fcntl", "Too many open files"),
Apply to both the F_DUPFD and F_DUPFD_CLOEXEC arms.
Guest-visible change: fcntl(fd, F_DUPFD) on a full table returns EMFILE, was
EBADF. This is a correction toward Linux.
Un-skip on merge
Remove conc_005_fd_exhaustion_isolation.c from skip_test_cases.txt.
Component:
src/rawposix/src/fs_calls.rs(fcntl_syscall,F_DUPFDandF_DUPFD_CLOEXECarms)Severity: POSIX conformance
Found by: CONC-005a (#1304),
conc_005_fd_exhaustion_isolation.cSymptom
A cage at its virtual fd table limit cannot be distinguished from one that was handed
an invalid descriptor: both return
EBADF. POSIX requiresEMFILEfor the former.Well-behaved applications that retry after closing something instead treat the fd as
bad and give up.
Root cause
vfd_arghas already been validated by_fcntl_helperbefore this point, so the onlyway the allocation can fail is a full table, which is
EMFILEby definition.Proposed fix
Apply to both the
F_DUPFDandF_DUPFD_CLOEXECarms.Guest-visible change:
fcntl(fd, F_DUPFD)on a full table returnsEMFILE, wasEBADF. This is a correction toward Linux.Un-skip on merge
Remove
conc_005_fd_exhaustion_isolation.cfromskip_test_cases.txt.