Swatantra-66 opened a new issue, #21543:
URL: https://github.com/apache/nuttx/issues/21543
### Description / Steps to reproduce the issue
### Summary
POSIX.1-2017 (IEEE Std 1003.1-2017) and POSIX.1-2024 explicitly mandate for
both `readv()` and `writev()`:
> *"The `readv()` / `writev()` function shall fail if:*
> *`[EINVAL]` The sum of the `iov_len` values in the `iov` array overflowed
an `ssize_t`.*
> *or*
> *`[EINVAL]` The `iovcnt` argument was less than or equal to 0, or greater
than `{IOV_MAX}`."*
Currently, NuttX's VFS layer (`fs/vfs/fs_read.c` and `fs/vfs/fs_write.c`)
does not enforce these boundaries, leading to non-compliant return values and
partial I/O on overflow.
In fact, this omission is already noted in `include/sys/uio.h` (lines
107-108, 132-133, 149-150):
```c
/* In include/sys/uio.h: */
* EINVAL.
* The sum of the iov_len values in the iov array overflowed an ssize_t
* or The 'iovcnt' argument was less than or equal to 0, or greater than
* IOV_MAX (Not implemented).
*
* TODO: If the sum of the iov_len values is greater than SSIZE_MAX, the
* operation will fail and no data will be transferred.
```
---
### Steps to Reproduce
1. Call `readv(fd, iov, 0)` or `writev(fd, iov, 0)`:
- **Expected (POSIX):** Returns `-1`, `errno = EINVAL`.
- **Actual (NuttX):** Returns `0` (indicates zero-byte success / EOF).
2. Call `readv(fd, iov, -1)` or `writev(fd, iov, -1)`:
- **Expected (POSIX):** Returns `-1`, `errno = EINVAL`.
- **Actual (NuttX):** Bypasses validation and returns `0`.
3. Call `readv()` or `writev()` with `iovcnt > IOV_MAX`:
- **Expected (POSIX):** Returns `-1`, `errno = EINVAL`.
- **Actual (NuttX):** Allowed and processed unchecked.
4. Call `readv()` or `writev()` where `iov[0].iov_len = 10` and
`iov[1].iov_len = SSIZE_MAX`:
- **Expected (POSIX):** Returns `-1`, `errno = EINVAL` upfront, with no
data read or written.
- **Actual (NuttX):** In `file_readv_compat()` and
`file_writev_compat()`, transfers 10 bytes on `iov[0]`, detects overflow on
`iov[1]`, executes `break`, and returns `10` (partial transfer) rather than
rejecting the invalid request upfront.
---
### Behavior Comparison
| Scenario / Parameter | POSIX IEEE Std 1003.1 | Current NuttX VFS |
Proposed Fix |
| :--- | :--- | :--- | :--- |
| `iovcnt == 0` | Fail with `[EINVAL]` | Returns `0` (Success) | Fail with
`-EINVAL` |
| `iovcnt < 0` | Fail with `[EINVAL]` | Returns `0` (Success) | Fail with
`-EINVAL` |
| `iovcnt > IOV_MAX` | Fail with `[EINVAL]` | Unchecked / Allowed | Fail
with `-EINVAL` |
| Sum of `iov_len` > `SSIZE_MAX` (`i == 0`) | Fail with `[EINVAL]` | Fails
with `-EINVAL` | Fail upfront with `-EINVAL` |
| Sum of `iov_len` > `SSIZE_MAX` (`i > 0`) | Fail with `[EINVAL]`, no data
transferred | Returns partial bytes (`ntotal`) | Fail upfront with `-EINVAL`,
no data transferred |
---
### Proposed Solution
1. In `file_readv()` and `file_writev()`, validate `iovcnt` upfront:
```c
if (iovcnt <= 0 || iovcnt > IOV_MAX)
{
return -EINVAL;
}
```
2. Validate in an upfront pass that the accumulated sum of `iov_len` does
not exceed `SSIZE_MAX` before initiating any file operations or acquiring
locks, returning `-EINVAL` on overflow.
3. Update the comments and `TODO` items in `include/sys/uio.h` to reflect
the completed POSIX conformance.
I have a patch ready with 100% `nxstyle` and `checkpatch` compliance and
would be glad to submit a PR if this is the desired approach.
### On which OS does this issue occur?
[OS: Linux]
### What is the version of your OS?
Ubuntu 22.04 LTS (all)
### NuttX Version
master
### Issue Architecture
[Arch: all]
### Issue Area
[Area: Posix]
### Host information
Host: Linux x86_64 / Ubuntu 22.04 (Architecture-independent VFS logic bug)
Target: All architectures (sim:nsh, arm, etc.)
### Verification
- [x] I have verified before submitting the report.
--
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]