zyfeier opened a new pull request, #18372: URL: https://github.com/apache/nuttx/pull/18372
In file_dup2, the file descriptor is initialized with the O_NONBLOCK flag. If the inode's ioctl(FIONBIO) call fails with a result other than OK or ENOTTY, the file may be mistakenly released. *Note: Please adhere to [Contributing Guidelines](https://github.com/apache/nuttx/blob/master/CONTRIBUTING.md).* ## Summary In `file_dup2`, the file descriptor is initialized with the `O_NONBLOCK` flag. If the inode's `ioctl(FIONBIO)` call fails with a result other than `OK` or `-ENOTTY`, the file may be mistakenly released. This patch fixes three issues in `noteram_driver.c`: 1. Change the default ioctl return value from `-ENOSYS` to `-ENOTTY` to comply with the expected behavior in `file_dup2` 2. Set `filep->f_priv = NULL` before freeing the context in `noteram_close` to avoid dangling pointer 3. Fix indentation in the default case of the ioctl switch statement ## Impact - Prevents file descriptors from being mistakenly released when duplicated via `file_dup2` - No breaking changes - Improves code robustness and correctness ## Testing Build Host: Ubuntu Linux x86_64 Configuration: sim:note NuttX Version: 12.12.0 Build $ tools/configure.sh sim:note $ make -j$(nproc) Build completed successfully with no errors or warnings. Test: ioctl(FIONBIO) on /dev/note/ram fs_ioctl.c only accepts OK or -ENOTTY for FIONBIO. Any other error code (e.g., -ENOSYS) causes mistakenly close and release the file. Test program: ``` int main(int argc, char *argv[]) { int fd, ret; int zero = 0; char buf[64]; printf("=== noteram file_dup2 simulation test ===\n\n"); /* Step 1: open with O_NONBLOCK (same as file_dup2 line 120) */ fd = open("/dev/note/ram", O_RDONLY | O_NONBLOCK); printf("Step 1: open(\"/dev/note/ram\", O_RDONLY | O_NONBLOCK) = %d\n", fd); /* Step 2: ioctl(FIONBIO, 0) to clear nonblock (same as file_dup2 line 131) */ ret = ioctl(fd, FIONBIO, &zero); printf("Step 2: ioctl(fd, FIONBIO, 0) = %d", ret); if (ret < 0) { printf(" (errno=%d: %s)\n", errno, strerror(errno)); printf("Step 3: file_dup2 would CLOSE the file (bug triggered!)\n"); close(fd); printf("\nFAIL: ioctl(FIONBIO) returned error, file_dup2 releases fd\n"); } else { printf("\n"); ret = read(fd, buf, sizeof(buf)); printf("Step 3: read(fd) = %d bytes (fd still usable)\n", ret); close(fd); printf("\nPASS: ioctl(FIONBIO) returned OK, file_dup2 works correctly\n"); } printf("=== test complete ===\n"); return 0; } ``` Before fix (returns -ENOSYS): ``` === noteram file_dup2 simulation test === Step 1: open("/dev/note/ram", O_RDONLY | O_NONBLOCK) = 3 Step 2: ioctl(fd, FIONBIO, 0) = -1 (errno=38: Unknown error 38) Step 3: file_dup2 would CLOSE the file (bug triggered!) FAIL: ioctl(FIONBIO) returned error, file_dup2 releases fd === test complete === ``` After fix (returns -ENOTTY): ``` === noteram file_dup2 simulation test === Step 1: open("/dev/note/ram", O_RDONLY | O_NONBLOCK) = 3 Step 2: ioctl(fd, FIONBIO, 0) = 0 Step 3: read(fd) = 50 bytes (fd still usable) PASS: ioctl(FIONBIO) returned OK, file_dup2 works correctly === test complete === ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
