This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit b71c713c8acd81d78db7566f7cbb57d0bd865dd0 Author: Marco Casaroli <[email protected]> AuthorDate: Mon Oct 19 23:33:40 2026 +0200 fs/vfs: Read the FIONBIO argument before the file reference is taken. ioctl(fd, FIONBIO, &value) passes a pointer to an int. The driver reads the int, and file_vioctl() reads it again after the driver ioctl, while nx_vioctl() holds a reference to the file. In a kernel build or a protected build the pointer comes from user space, so another thread can change the int between the two reads, and then the driver and f_oflags do not agree. Read the int once in nx_vioctl() before file_get2(), and give the driver and file_vioctl() a pointer to the kernel copy. No user memory is read with the reference held. Kernel callers of file_ioctl() do not change. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- fs/vfs/fs_ioctl.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/fs/vfs/fs_ioctl.c b/fs/vfs/fs_ioctl.c index 0de0de35ba9..5e9b6cb3328 100644 --- a/fs/vfs/fs_ioctl.c +++ b/fs/vfs/fs_ioctl.c @@ -165,8 +165,25 @@ static int nx_vioctl(int fd, int req, va_list ap) { FAR struct file *filep; FAR struct fd *fdp; + FAR int *nonblockp = NULL; + int nonblock; int ret; + /* FIONBIO passes a pointer to an int. Read the int before file_get2(), + * so that a bad pointer faults with no file reference held, and give the + * driver a pointer to the copy. + */ + + if (req == FIONBIO) + { + nonblockp = va_arg(ap, FAR int *); + if (nonblockp != NULL) + { + nonblock = *nonblockp; + nonblockp = &nonblock; + } + } + ret = file_get2(fd, &filep, &fdp); if (ret < 0) { @@ -207,6 +224,10 @@ static int nx_vioctl(int fd, int req, va_list ap) break; #endif + case FIONBIO: + ret = file_ioctl(filep, req, (unsigned long)(uintptr_t)nonblockp); + break; + default: ret = file_vioctl(filep, req, ap); break;
