From f04ab527c9dc0d702534e64c995f1397951a2ac7 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sat, 9 Jan 2021 21:37:22 -0700 Subject: [PATCH] writev and friends should return EINVAL when iovcnt = 0 POSIX requires readv/writev to return EINVAL when iovcnt = 0. PR: 252551 --- contrib/netbsd-tests/lib/libc/sys/t_write.c | 22 +++++++++++++++++++++ sys/kern/subr_uio.c | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/contrib/netbsd-tests/lib/libc/sys/t_write.c b/contrib/netbsd-tests/lib/libc/sys/t_write.c index 18bcaba4f7aa..412cb4206218 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_write.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_write.c @@ -213,6 +213,27 @@ ATF_TC_BODY(writev_iovmax, tc) ATF_REQUIRE_EQ_MSG(errno, EINVAL, "got: %s", strerror(errno)); } +ATF_TC(writev_zero); +ATF_TC_HEAD(writev_zero, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "writev must return EINVAL when iovcnt == 0"); +} + +ATF_TC_BODY(writev_zero, tc) +{ + ssize_t retval; + + (void)printf("Calling writev(2, NULL, 0)...\n"); + + errno = 0; + retval = writev(2, NULL, 0); + + ATF_REQUIRE_EQ_MSG(retval, -1, "got: %zd", retval); + ATF_REQUIRE_EQ_MSG(errno, EINVAL, "got: %s", strerror(errno)); +} + ATF_TP_ADD_TCS(tp) { @@ -221,6 +242,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, write_pos); ATF_TP_ADD_TC(tp, write_ret); ATF_TP_ADD_TC(tp, writev_iovmax); + ATF_TP_ADD_TC(tp, writev_zero); return atf_no_error(); } diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c index a7b7988cf661..da6d31456b44 100644 --- a/sys/kern/subr_uio.c +++ b/sys/kern/subr_uio.c @@ -370,7 +370,7 @@ copyinuio(const struct iovec *iovp, u_int iovcnt, struct uio **uiop) int error, i; *uiop = NULL; - if (iovcnt > UIO_MAXIOV) + if (iovcnt <= 0 || iovcnt > UIO_MAXIOV) return (EINVAL); iovlen = iovcnt * sizeof (struct iovec); uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); -- 2.30.0