From: TAKANO Mitsuhiro <takano32@gmail.com>
To: qemu-devel@nongnu.org
Cc: "Laurent Vivier" <laurent@vivier.eu>,
"Helge Deller" <deller@gmx.de>,
"Pierrick Bouvier" <pierrick.bouvier@oss.qualcomm.com>,
"Alex Bennée" <alex.bennee@linaro.org>
Subject: [PATCH 1/2] linux-user: validate the fd for a zero-length readv/writev
Date: Sun, 25 Oct 2026 07:12:02 +0000 [thread overview]
Message-ID: <20261025071203.1214199-1-takano32@gmail.com> (raw)
lock_iovec() returns NULL with errno left at zero when the vector count
is zero, and the readv/writev family turns that into a successful return
without ever entering the kernel. The kernel checks the file descriptor
before it looks at the vector, so a read from a write-only descriptor
fails with EBADF even when iovcnt is zero, while qemu-user reports
success:
fd = open("/dev/null", O_WRONLY);
readv(fd, NULL, 0); /* kernel: -1 EBADF, qemu-user: 0 */
Return an empty vector for the zero count so that the syscall is issued
and the host reports the real error. This covers readv, writev,
preadv, pwritev, preadv2, pwritev2 and vmsplice, which all share
lock_iovec(); sendmsg/recvmsg already handle a zero iov itself.
Reproducer and measurements: https://github.com/takano32/qemu-user-zero-iovec
Signed-off-by: TAKANO Mitsuhiro <takano32@gmail.com>
---
linux-user/syscall.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0380691a8b..3197ccaec6 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3093,8 +3093,13 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
bool bad_address = false;
if (count == 0) {
- errno = 0;
- return NULL;
+ /*
+ * The kernel validates the file descriptor before it looks at the
+ * vector, so readv(fd, NULL, 0) on a read-only fd fails with EBADF
+ * rather than returning 0. Hand back an empty vector so that the
+ * caller issues the syscall and the host reports the real error.
+ */
+ return g_new0(struct iovec, 1);
}
if (count > IOV_MAX) {
errno = EINVAL;
--
2.53.0
next reply other threads:[~2026-10-25 7:12 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-25 7:12 TAKANO Mitsuhiro [this message]
2026-10-25 7:12 ` [PATCH 2/2] tests/tcg: check that a zero-length readv/writev validates the fd TAKANO Mitsuhiro
2026-10-25 17:13 ` [PATCH 1/2] linux-user: validate the fd for a zero-length readv/writev Alex Bennée
2026-10-25 20:51 ` [PATCH v2 0/2] " TAKANO Mitsuhiro
2026-10-25 20:51 ` [PATCH v2 1/2] " TAKANO Mitsuhiro
2026-10-25 20:51 ` [PATCH v2 2/2] tests/tcg: check that a zero-length readv/writev validates the fd TAKANO Mitsuhiro
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261025071203.1214199-1-takano32@gmail.com \
--to=takano32@gmail.com \
--cc=alex.bennee@linaro.org \
--cc=deller@gmx.de \
--cc=laurent@vivier.eu \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.