Route sendmsg/recvmsg via shared host_iov helper
sys_sendmsg and sys_recvmsg resolved each guest iov entry with guest_ptr_bound() and clamped the entry's length to the contiguous prefix when the guest VA crossed a host-side discontinuity (primary slab to guest_mapping / guest_overflow region, or between two distinct mappings). The loop then continued populating host_iov[i+1..] at full requested length, so the host sendmsg(2) placed bytes from iov[i+1] on the wire where the truncated tail of iov[i] belonged, and recvmsg(2) scattered received bytes into the wrong guest buffer past a truncated entry. The case only fires when a guest iov entry straddles two distinct host mappings; the typical single-region iov masked it in tests.
Hoist the already-correct build_host_iov helper from src/syscall/io.c into src/syscall/internal.h as host_iov_prepare and the wrapper host_iov_prepare_msg, together with host_iov_buf_t and the SYSCALL_IOV_MAX / SYSCALL_IOV_STACK_MAX constants. host_iov_prepare keeps the strict readv/writev contract (rejects iovcnt <= 0); host_iov_prepare_msg short-circuits iovcnt == 0 for ancillary-only sendmsg/recvmsg payloads. Replace the duplicated inline iov build loops in src/syscall/net-msg.c with the shared call. Side effects: lifts the per-call iovcnt cap from 64 to SYSCALL_IOV_MAX (1024) and drops roughly 80 lines of duplicated logic.
The shared helper truncates at the first non-contiguous iov entry and zeros every subsequent entry, so the host call returns a POSIX-compliant short I/O instead of mis-aligning the wire data.
Summary by cubic
Fixes misaligned I/O in sendmsg/recvmsg when a guest iovec crosses non‑contiguous host mappings by routing both calls through a shared host_iov helper. Lifts the iov cap to 1024 and removes duplicated logic.
-
Bug Fixes
- Truncate at the first non‑contiguous iov entry and zero the rest so the host returns a POSIX short I/O instead of misplacing data.
- Cap
msg_iovlenatSYSCALL_IOV_MAXbefore int narrowing; allowiovcnt == 0for ancillary‑only messages.
-
Refactors
- Hoisted
build_host_iovintohost_iov_prepare/host_iov_prepare_msginsrc/syscall/internal.hwithhost_iov_buf_t,host_iov_free, and sharedSYSCALL_IOV_MAX/SYSCALL_IOV_STACK_MAX. - Replaced inline iov loops in
src/syscall/net-msg.c; raised per‑call cap from 64 to 1024; removed ~80 lines. - Added a test to keep strict
readv/writev/pwritev2behavior: zeroiovcntstays-EINVALand does not move the file offset.
- Hoisted