This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] Fix misreported errno on preadv2/pwritev2 (BZ#23579)
- From: Szabolcs Nagy <Szabolcs dot Nagy at arm dot com>
- To: Adhemerval Zanella <adhemerval dot zanella at linaro dot org>, "libc-alpha at sourceware dot org" <libc-alpha at sourceware dot org>
- Cc: nd <nd at arm dot com>
- Date: Tue, 23 Oct 2018 13:09:47 +0000
- Subject: Re: [PATCH] Fix misreported errno on preadv2/pwritev2 (BZ#23579)
- References: <20180829212032.32507-1-adhemerval.zanella@linaro.org>
On 29/08/18 22:20, Adhemerval Zanella wrote:
> The fallback code of Linux wrapper for preadv2/pwritev2 executes
> regardless of the errno code for preadv2, instead of the case where
> the syscall is not supported.
>
> This fixes it by calling the fallback code iff errno is ENOSYS. The
> patch also adds tests for both invalid file descriptor and invalid
> iov_len and vector count.
>
> The only discrepancy between preadv2 and fallback code regarding
> error reporting is when an invalid flags are used. The fallback code
> bails out earlier with ENOTSUP instead of EINVAL/EBADF when the syscall
> is used.
>
> Checked on x86_64-linux-gnu on a 4.4.0 and 4.15.0 kernel.
>
> [BZ #23579]
> * misc/tst-preadvwritev2-common.c (do_test_with_invalid_fd): New
> test.
> * misc/tst-preadvwritev2.c, misc/tst-preadvwritev64v2.c (do_test):
> Call do_test_with_invalid_fd.
> * sysdeps/unix/sysv/linux/preadv2.c (preadv2): Use fallback code iff
> errno is ENOSYS.
> * sysdeps/unix/sysv/linux/preadv64v2.c (preadv64v2): Likewise.
> * sysdeps/unix/sysv/linux/pwritev2.c (pwritev2): Likewise.
> * sysdeps/unix/sysv/linux/pwritev64v2.c (pwritev64v2): Likewise.
with build-many-glibcs.py in
logs/glibcs/i686-gnu/010-glibcs-i686-gnu-check-log.txt i see
In file included from tst-preadvwritev2.c:26:
tst-preadvwritev2-common.c: In function ‘do_test_with_invalid_iov’:
tst-preadvwritev2-common.c:89:22: error: ‘IOV_MAX’ undeclared (first use in this function); did you mean ‘INT_MAX’?
struct iovec iov[IOV_MAX+1] = { 0 };
^~~~~~~
INT_MAX
tst-preadvwritev2-common.c:89:22: note: each undeclared identifier is reported only once for each function it appears in
tst-preadvwritev2-common.c:89:18: error: unused variable ‘iov’ [-Werror=unused-variable]
struct iovec iov[IOV_MAX+1] = { 0 };
^~~
cc1: all warnings being treated as errors
make[3]: *** [../o-iterator.mk:9: /data/glibc-build-j2/build/glibcs/i686-gnu/glibc/misc/tst-preadvwritev2.o] Error 1
...
> +static void
> +do_test_with_invalid_iov (void)
> +{
> + {
> + char buf[256];
> + struct iovec iov;
> +
> + iov.iov_base = buf;
> + iov.iov_len = (size_t)SSIZE_MAX + 1;
> +
> + TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, 0) == -1);
> + TEST_COMPARE (errno, EINVAL);
> + TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, 0) == -1);
> + TEST_COMPARE (errno, EINVAL);
> +
> + /* Same as for invalid file descriptor tests, emulation fallback
> + first checks for flag value and return ENOTSUP. */
> + TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
> + TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
> + TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
> + TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
> + }
> +
> + {
> + /* An invalid iovec buffer should trigger an invalid memory access
> + or an error (Linux for instance returns EFAULT). */
> + struct iovec iov[IOV_MAX+1] = { 0 };
> +
> + TEST_VERIFY (preadv2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
> + TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
> + TEST_VERIFY (pwritev2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
> + TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
> + }
> +}