fs/inode: bug fix about fdlist_extend, fdlist_install and eventfd/timerfd_blocking_io #17731
+28
−13
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR contains four bug fixes and improvements to the NuttX file system layer, specifically focusing on file descriptor management and event handling:
1. Fix fd allocation exceeding OPEN_MAX (fs/inode/fs_files.c)
The OPEN_MAX boundary check in
fdlist_extend()was incorrectly usingorig_rowsinstead of(orig_rows + 1)when validating whether the new allocation would exceed limits. This allowed file descriptor allocation to succeed even when it would exceed OPEN_MAX, potentially causing memory corruption or exceeding system resource limits.Example: With OPEN_MAX=256 and CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=32, when orig_rows=8 (already at 256 fds), the old code would check
32 * 8 > 256(false, allows extension to 288), while the fixed code correctly checks32 * 9 > 256(true, blocks extension).2. Fix fd tag loss during parent-to-child inheritance (fs/inode/fs_files.c)
When child processes inherited file descriptors from parent via
fdlist_copy(), the fd tags (fd_tag_fdsanandfd_tag_fdcheck) were not being preserved. This caused assertion failures when child processes closed inherited fds, as the fdcheck/fdsan subsystems expected matching tags.The fix adds a
copyparameter tofdlist_install()to distinguish between new fd allocation (initialize fresh tags) and fd inheritance (preserve parent tags). This is critical for any application using fork/clone with inherited file descriptors when CONFIG_FDSAN or CONFIG_FDCHECK are enabled.3. Fix busy loop in eventfd/timerfd (fs/vfs/fs_eventfd.c, fs/vfs/fs_timerfd.c)
Updated semaphore handling to properly advance to the next waiting task, preventing busy loops in event and timer file descriptor operations. Without this fix, certain polling scenarios could cause the system to spin unnecessarily.
Impact
Users:
Build Process:
Hardware:
Documentation:
Security:
Compatibility:
Testing
Test 1: OPEN_MAX Boundary Check
Test Procedure:
Before Fix:
Could allocate up to 288 fds (exceeded OPEN_MAX=256 by 32)
Potential memory corruption
After Fix:
Correctly stops at or before OPEN_MAX (253-256 depending on stdio fds)
Returns -EMFILE when limit reached
No memory corruption
Test 2: Fork with Inherited FDs
Test Procedure:
After Fix:
Child successfully closes inherited fds
fd_tag_fdsan and fd_tag_fdcheck properly preserved
No crashes, all tests pass
Test Log:
Ran complete test suite with uv_run_tests_main including:
run_helper_tcp4_echo_server
Multiple fork/close cycles
File descriptor inheritance scenarios
All tests PASSED without assertions
OSTest Verification:
Ran full OSTest suite with all patches applied:
All tests PASSED