Patchwork posix: Add invalid flags test for p{write,read}v2

login
register
mail settings
Submitter Adhemerval Zanella Netto
Date June 16, 2017, 3:09 p.m.
Message ID <1497625780-8732-1-git-send-email-adhemerval.zanella@linaro.org>
Download mbox | patch
Permalink /patch/21050/
State New
Headers show

Comments

Adhemerval Zanella Netto - June 16, 2017, 3:09 p.m.
This patch add an extra test for passing invalid flags and check its
expected failure.  It shows an invalid LO_HI_LONG macro definition for
x86_64 with leads to passing invalid flags on some configurations.

The new tests fails on i686-linux-gnu and potentially on other 32 bits
architecture that uses the compat syscall definition due a kernel bug.
It is intended to be fixed upstream.  I have added a comment for it and
I think disabling this is not the correct approach since if the syscall
is ignoring the flag it defeats the whole purpose of the syscall.  The
failure indicates the kernel requires an update.

Checked on x86_64-linux-gnu

	* misc/tst-preadvwritev2-common.c: New file.
	* misc/tst-preadvwritev2.c (do_test): Add test for invalid flag.
	* misc/tst-preadvwritev64v2.c (do_test): Likewise.
---
 ChangeLog                       |  6 ++++++
 misc/tst-preadvwritev2-common.c | 48 +++++++++++++++++++++++++++++++++++++++++
 misc/tst-preadvwritev2.c        |  3 +++
 misc/tst-preadvwritev64v2.c     |  3 +++
 4 files changed, 60 insertions(+)
 create mode 100644 misc/tst-preadvwritev2-common.c
Christoph Hellwig - June 16, 2017, 3:42 p.m.
On Fri, Jun 16, 2017 at 12:09:40PM -0300, Adhemerval Zanella wrote:
> This patch add an extra test for passing invalid flags and check its
> expected failure.  It shows an invalid LO_HI_LONG macro definition for
> x86_64 with leads to passing invalid flags on some configurations.
> 
> The new tests fails on i686-linux-gnu and potentially on other 32 bits
> architecture that uses the compat syscall definition due a kernel bug.
> It is intended to be fixed upstream.  I have added a comment for it and
> I think disabling this is not the correct approach since if the syscall
> is ignoring the flag it defeats the whole purpose of the syscall.  The
> failure indicates the kernel requires an update.

Linus just merged the fix for that issue, so Linux 4.12 should be.
It will also go into the stable trees.

Patch

diff --git a/misc/tst-preadvwritev2-common.c b/misc/tst-preadvwritev2-common.c
new file mode 100644
index 0000000..4c53d56
--- /dev/null
+++ b/misc/tst-preadvwritev2-common.c
@@ -0,0 +1,48 @@ 
+/* Common function for preadv2 and pwritev2 tests.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <support/check.h>
+
+static void
+do_test_with_invalid_flags (void)
+{
+  int invalid_flag = 0x1;
+#ifdef RWF_HIPRI
+  invalid_flag <<= 1;
+#endif
+#ifdef RWF_DSYNC
+  invalid_flag <<= 1;
+#endif
+#ifdef RWF_SYNC
+  invalid_flag <<= 1;
+#endif
+
+  char buf[32];
+  const struct iovec vec = { .iov_base = buf, .iov_len = sizeof (buf) };
+  if (preadv2 (temp_fd, &vec, 1, 0, invalid_flag) != -1)
+    FAIL_EXIT1 ("preadv2 did not fail with an invalid flag");
+  if (errno != ENOTSUP)
+    FAIL_EXIT1 ("preadv2 failure did not set errno to ENOTSUP (%d)", errno);
+
+  /* This might fail for compat syscall (32 bits running on 64 bits kernel)
+     due a kernel issue.  */
+  if (pwritev2 (temp_fd, &vec, 1, 0, invalid_flag) != -1)
+    FAIL_EXIT1 ("pwritev2 did not fail with an invalid flag");
+  if (errno != ENOTSUP)
+    FAIL_EXIT1 ("pwritev2 failure did not set errno to ENOTSUP (%d)", errno);
+}
diff --git a/misc/tst-preadvwritev2.c b/misc/tst-preadvwritev2.c
index cf36272..682c757 100644
--- a/misc/tst-preadvwritev2.c
+++ b/misc/tst-preadvwritev2.c
@@ -23,9 +23,12 @@ 
   pwritev2 (__fd, __iov, __iovcnt, __offset, 0)
 
 #include "tst-preadvwritev-common.c"
+#include "tst-preadvwritev2-common.c"
 
 static int
 do_test (void)
 {
+  do_test_with_invalid_flags ();
+
   return do_test_with_offset (0);
 }
diff --git a/misc/tst-preadvwritev64v2.c b/misc/tst-preadvwritev64v2.c
index 8d0c48e..9ddc762 100644
--- a/misc/tst-preadvwritev64v2.c
+++ b/misc/tst-preadvwritev64v2.c
@@ -25,9 +25,12 @@ 
   pwritev2 (__fd, __iov, __iovcnt, __offset, 0)
 
 #include "tst-preadvwritev-common.c"
+#include "tst-preadvwritev2-common.c"
 
 static int
 do_test (void)
 {
+  do_test_with_invalid_flags ();
+
   return do_test_with_offset (0);
 }