Blame SOURCES/valgrind-3.15.0-copy_file_range.patch

5a43b8
commit 5f00db054a6f59502e9deeeb59ace2261207ee31
5a43b8
Author: Alexandra Hajkova <ahajkova@redhat.com>
5a43b8
Date:   Thu May 2 08:24:02 2019 -0400
5a43b8
5a43b8
    Add support for the copy_file_range syscall
5a43b8
    
5a43b8
    Support amd64, x86, arm64, ppc64, ppc32 and s390x architectures.
5a43b8
    Also add sys-copy_file_range test case.
5a43b8
5a43b8
diff --git a/configure.ac b/configure.ac
5a43b8
index d043ce3..3528925 100755
5a43b8
--- a/configure.ac
5a43b8
+++ b/configure.ac
5a43b8
@@ -4172,6 +4172,7 @@ AC_CHECK_FUNCS([     \
5a43b8
         utimensat    \
5a43b8
         process_vm_readv  \
5a43b8
         process_vm_writev \
5a43b8
+        copy_file_range \
5a43b8
         ])
5a43b8
 
5a43b8
 # AC_CHECK_LIB adds any library found to the variable LIBS, and links these
5a43b8
@@ -4187,6 +4188,8 @@ AM_CONDITIONAL([HAVE_PTHREAD_SPINLOCK],
5a43b8
                [test x$ac_cv_func_pthread_spin_lock = xyes])
5a43b8
 AM_CONDITIONAL([HAVE_PTHREAD_SETNAME_NP],
5a43b8
                [test x$ac_cv_func_pthread_setname_np = xyes])
5a43b8
+AM_CONDITIONAL([HAVE_COPY_FILE_RANGE],
5a43b8
+               [test x$ac_cv_func_copy_file_range = xyes])
5a43b8
 
5a43b8
 if test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX \
5a43b8
      -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX ; then
5a43b8
diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h
5a43b8
index f76191a..1edf9eb 100644
5a43b8
--- a/coregrind/m_syswrap/priv_syswrap-linux.h
5a43b8
+++ b/coregrind/m_syswrap/priv_syswrap-linux.h
5a43b8
@@ -379,6 +379,7 @@ DECL_TEMPLATE(linux, sys_getsockname);
5a43b8
 DECL_TEMPLATE(linux, sys_getpeername);
5a43b8
 DECL_TEMPLATE(linux, sys_socketpair);
5a43b8
 DECL_TEMPLATE(linux, sys_kcmp);
5a43b8
+DECL_TEMPLATE(linux, sys_copy_file_range);
5a43b8
 
5a43b8
 // Some arch specific functions called from syswrap-linux.c
5a43b8
 extern Int do_syscall_clone_x86_linux ( Word (*fn)(void *), 
5a43b8
diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c
5a43b8
index 30e7d0e..0c1d8d1 100644
5a43b8
--- a/coregrind/m_syswrap/syswrap-amd64-linux.c
5a43b8
+++ b/coregrind/m_syswrap/syswrap-amd64-linux.c
5a43b8
@@ -863,6 +863,8 @@ static SyscallTableEntry syscall_table[] = {
5a43b8
    LINXY(__NR_statx,             sys_statx),             // 332
5a43b8
 
5a43b8
    LINX_(__NR_membarrier,        sys_membarrier),        // 324
5a43b8
+
5a43b8
+   LINX_(__NR_copy_file_range,   sys_copy_file_range),   // 326
5a43b8
 };
5a43b8
 
5a43b8
 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
5a43b8
diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c
5a43b8
index 290320a..f66be2d 100644
5a43b8
--- a/coregrind/m_syswrap/syswrap-arm64-linux.c
5a43b8
+++ b/coregrind/m_syswrap/syswrap-arm64-linux.c
5a43b8
@@ -819,7 +819,7 @@ static SyscallTableEntry syscall_main_table[] = {
5a43b8
    //   (__NR_userfaultfd,       sys_ni_syscall),        // 282
5a43b8
    LINX_(__NR_membarrier,        sys_membarrier),        // 283
5a43b8
    //   (__NR_mlock2,            sys_ni_syscall),        // 284
5a43b8
-   //   (__NR_copy_file_range,   sys_ni_syscall),        // 285
5a43b8
+   LINX_(__NR_copy_file_range,   sys_copy_file_range),   // 285
5a43b8
    //   (__NR_preadv2,           sys_ni_syscall),        // 286
5a43b8
    //   (__NR_pwritev2,          sys_ni_syscall),        // 287
5a43b8
    //   (__NR_pkey_mprotect,     sys_ni_syscall),        // 288
5a43b8
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
5a43b8
index 73ef98d..cd0ee74 100644
5a43b8
--- a/coregrind/m_syswrap/syswrap-linux.c
5a43b8
+++ b/coregrind/m_syswrap/syswrap-linux.c
5a43b8
@@ -12093,6 +12093,36 @@ POST(sys_bpf)
5a43b8
    }
5a43b8
 }
5a43b8
 
5a43b8
+PRE(sys_copy_file_range)
5a43b8
+{
5a43b8
+  PRINT("sys_copy_file_range (%lu, %lu, %lu, %lu, %lu, %lu)", ARG1, ARG2, ARG3,
5a43b8
+        ARG4, ARG5, ARG6);
5a43b8
+
5a43b8
+  PRE_REG_READ6(vki_size_t, "copy_file_range",
5a43b8
+                int, "fd_in",
5a43b8
+                vki_loff_t *, "off_in",
5a43b8
+                int, "fd_out",
5a43b8
+                vki_loff_t *, "off_out",
5a43b8
+                vki_size_t, "len",
5a43b8
+                unsigned int, "flags");
5a43b8
+
5a43b8
+  /* File descriptors are "specially" tracked by valgrind.
5a43b8
+     valgrind itself uses some, so make sure someone didn't
5a43b8
+     put in one of our own...  */
5a43b8
+  if (!ML_(fd_allowed)(ARG1, "copy_file_range(fd_in)", tid, False) ||
5a43b8
+      !ML_(fd_allowed)(ARG3, "copy_file_range(fd_in)", tid, False)) {
5a43b8
+     SET_STATUS_Failure( VKI_EBADF );
5a43b8
+  } else {
5a43b8
+     /* Now see if the offsets are defined. PRE_MEM_READ will
5a43b8
+        double check it can dereference them. */
5a43b8
+     if (ARG2 != 0)
5a43b8
+        PRE_MEM_READ( "copy_file_range(off_in)", ARG2, sizeof(vki_loff_t));
5a43b8
+     if (ARG4 != 0)
5a43b8
+        PRE_MEM_READ( "copy_file_range(off_out)", ARG4, sizeof(vki_loff_t));
5a43b8
+  }
5a43b8
+}
5a43b8
+
5a43b8
+
5a43b8
 #undef PRE
5a43b8
 #undef POST
5a43b8
 
5a43b8
diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c
5a43b8
index f812f1f..71f208d 100644
5a43b8
--- a/coregrind/m_syswrap/syswrap-ppc32-linux.c
5a43b8
+++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c
5a43b8
@@ -1021,6 +1021,8 @@ static SyscallTableEntry syscall_table[] = {
5a43b8
    LINXY(__NR_getrandom,         sys_getrandom),        // 359
5a43b8
    LINXY(__NR_memfd_create,      sys_memfd_create),     // 360
5a43b8
 
5a43b8
+   LINX_(__NR_copy_file_range,   sys_copy_file_range),  // 379
5a43b8
+
5a43b8
    LINXY(__NR_statx,             sys_statx),            // 383
5a43b8
 };
5a43b8
 
5a43b8
diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c
5a43b8
index eada099..1a42c1f 100644
5a43b8
--- a/coregrind/m_syswrap/syswrap-ppc64-linux.c
5a43b8
+++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c
5a43b8
@@ -1007,6 +1007,8 @@ static SyscallTableEntry syscall_table[] = {
5a43b8
 
5a43b8
    LINX_(__NR_membarrier,        sys_membarrier),       // 365
5a43b8
 
5a43b8
+   LINX_(__NR_copy_file_range,   sys_copy_file_range),  // 379
5a43b8
+
5a43b8
    LINXY(__NR_statx,             sys_statx),            // 383
5a43b8
 };
5a43b8
 
5a43b8
diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c
5a43b8
index ad78384..41ada8d 100644
5a43b8
--- a/coregrind/m_syswrap/syswrap-s390x-linux.c
5a43b8
+++ b/coregrind/m_syswrap/syswrap-s390x-linux.c
5a43b8
@@ -854,6 +854,8 @@ static SyscallTableEntry syscall_table[] = {
5a43b8
    LINXY(__NR_recvmsg, sys_recvmsg),                                  // 372
5a43b8
    LINX_(__NR_shutdown, sys_shutdown),                                // 373
5a43b8
 
5a43b8
+   LINX_(__NR_copy_file_range, sys_copy_file_range),                  // 375
5a43b8
+
5a43b8
    LINXY(__NR_statx, sys_statx),                                      // 379
5a43b8
 };
5a43b8
 
5a43b8
diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c
5a43b8
index f05619e..f8d97ea 100644
5a43b8
--- a/coregrind/m_syswrap/syswrap-x86-linux.c
5a43b8
+++ b/coregrind/m_syswrap/syswrap-x86-linux.c
5a43b8
@@ -1608,6 +1608,8 @@ static SyscallTableEntry syscall_table[] = {
5a43b8
 
5a43b8
    LINX_(__NR_membarrier,        sys_membarrier),       // 375
5a43b8
 
5a43b8
+   LINX_(__NR_copy_file_range,   sys_copy_file_range),   // 377
5a43b8
+
5a43b8
    LINXY(__NR_statx,             sys_statx),            // 383
5a43b8
 
5a43b8
    /* Explicitly not supported on i386 yet. */
5a43b8
diff --git a/memcheck/tests/linux/Makefile.am b/memcheck/tests/linux/Makefile.am
5a43b8
index d7515d9..00e99a5 100644
5a43b8
--- a/memcheck/tests/linux/Makefile.am
5a43b8
+++ b/memcheck/tests/linux/Makefile.am
5a43b8
@@ -20,6 +20,7 @@ EXTRA_DIST = \
5a43b8
 	stack_switch.stderr.exp stack_switch.vgtest \
5a43b8
 	syscalls-2007.vgtest syscalls-2007.stderr.exp \
5a43b8
 	syslog-syscall.vgtest syslog-syscall.stderr.exp \
5a43b8
+	sys-copy_file_range.vgtest sys-copy_file_range.stderr.exp \
5a43b8
 	sys-openat.vgtest sys-openat.stderr.exp sys-openat.stdout.exp \
5a43b8
 	sys-statx.vgtest sys-statx.stderr.exp \
5a43b8
 	timerfd-syscall.vgtest timerfd-syscall.stderr.exp \
5a43b8
@@ -49,6 +50,10 @@ if HAVE_AT_FDCWD
5a43b8
 check_PROGRAMS += sys-openat
5a43b8
 endif
5a43b8
 
5a43b8
+if HAVE_COPY_FILE_RANGE
5a43b8
+        check_PROGRAMS += sys-copy_file_range
5a43b8
+endif
5a43b8
+
5a43b8
 AM_CFLAGS   += $(AM_FLAG_M3264_PRI)
5a43b8
 AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
5a43b8
 
5a43b8
diff --git a/memcheck/tests/linux/sys-copy_file_range.c b/memcheck/tests/linux/sys-copy_file_range.c
5a43b8
new file mode 100644
5a43b8
index 0000000..83981c6
5a43b8
--- /dev/null
5a43b8
+++ b/memcheck/tests/linux/sys-copy_file_range.c
5a43b8
@@ -0,0 +1,67 @@
5a43b8
+#define _GNU_SOURCE
5a43b8
+#include <fcntl.h>
5a43b8
+#include <stdio.h>
5a43b8
+#include <stdlib.h>
5a43b8
+#include <sys/stat.h>
5a43b8
+#include <sys/syscall.h>
5a43b8
+#include <unistd.h>
5a43b8
+
5a43b8
+int main(int argc, char **argv)
5a43b8
+{
5a43b8
+    int fd_in, fd_out;
5a43b8
+    struct stat stat;
5a43b8
+    loff_t len, ret;
5a43b8
+
5a43b8
+    fd_in = open("copy_file_range_source", O_CREAT | O_RDWR);
5a43b8
+    if (fd_in == -1) {
5a43b8
+        perror("open copy_file_range_source");
5a43b8
+        exit(EXIT_FAILURE);
5a43b8
+    }
5a43b8
+
5a43b8
+    if (write(fd_in, "foo bar\n", 8) != 8) {
5a43b8
+        perror("writing to the copy_file_range_source");
5a43b8
+        exit(EXIT_FAILURE);
5a43b8
+    }
5a43b8
+    lseek(fd_in, 0, SEEK_SET);
5a43b8
+
5a43b8
+    if (fstat(fd_in, &stat) == -1) {
5a43b8
+        perror("fstat");
5a43b8
+        exit(EXIT_FAILURE);
5a43b8
+    }
5a43b8
+
5a43b8
+    len = stat.st_size;
5a43b8
+
5a43b8
+    fd_out = open("copy_file_range_dest", O_CREAT | O_WRONLY | O_TRUNC, 0644);
5a43b8
+    if (fd_out == -1) {
5a43b8
+        perror("open copy_file_range_dest");
5a43b8
+        exit(EXIT_FAILURE);
5a43b8
+    }
5a43b8
+
5a43b8
+    /* Check copy_file_range called with the correct arguments works. */
5a43b8
+    do {
5a43b8
+        ret = copy_file_range(fd_in, NULL, fd_out, NULL, len, 0);
5a43b8
+        if (ret == -1) {
5a43b8
+            perror("copy_file_range");
5a43b8
+            exit(EXIT_FAILURE);
5a43b8
+        }
5a43b8
+
5a43b8
+        len -= ret;
5a43b8
+    } while (len > 0);
5a43b8
+
5a43b8
+    /* Check valgrind will produce expected warnings for the
5a43b8
+       various wrong arguments. */
5a43b8
+    do {
5a43b8
+        void *t;
5a43b8
+        void *z = (void *) -1;
5a43b8
+
5a43b8
+        ret = copy_file_range(fd_in, t, fd_out, NULL, len, 0);
5a43b8
+        ret = copy_file_range(fd_in, NULL, fd_out, z, len, 0);
5a43b8
+        ret = copy_file_range(- 1, NULL, - 1, NULL, len, 0);
5a43b8
+    } while (0);
5a43b8
+
5a43b8
+    close(fd_in);
5a43b8
+    close(fd_out);
5a43b8
+    unlink("copy_file_range_source");
5a43b8
+    unlink("copy_file_range_dest");
5a43b8
+    exit(EXIT_SUCCESS);
5a43b8
+}
5a43b8
diff --git a/memcheck/tests/linux/sys-copy_file_range.stderr.exp b/memcheck/tests/linux/sys-copy_file_range.stderr.exp
5a43b8
new file mode 100644
5a43b8
index 0000000..1aa4dc2
5a43b8
--- /dev/null
5a43b8
+++ b/memcheck/tests/linux/sys-copy_file_range.stderr.exp
5a43b8
@@ -0,0 +1,21 @@
5a43b8
+
5a43b8
+Syscall param copy_file_range("off_in") contains uninitialised byte(s)
5a43b8
+   ...
5a43b8
+   by 0x........: main (sys-copy_file_range.c:57)
5a43b8
+
5a43b8
+Syscall param copy_file_range(off_out) points to unaddressable byte(s)
5a43b8
+   ...
5a43b8
+   by 0x........: main (sys-copy_file_range.c:58)
5a43b8
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
5a43b8
+
5a43b8
+Warning: invalid file descriptor -1 in syscall copy_file_range(fd_in)()
5a43b8
+
5a43b8
+HEAP SUMMARY:
5a43b8
+    in use at exit: 0 bytes in 0 blocks
5a43b8
+  total heap usage: 0 allocs, 0 frees, 0 bytes allocated
5a43b8
+
5a43b8
+For a detailed leak analysis, rerun with: --leak-check=full
5a43b8
+
5a43b8
+Use --track-origins=yes to see where uninitialised values come from
5a43b8
+For lists of detected and suppressed errors, rerun with: -s
5a43b8
+ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
5a43b8
diff --git a/memcheck/tests/linux/sys-copy_file_range.vgtest b/memcheck/tests/linux/sys-copy_file_range.vgtest
5a43b8
new file mode 100644
5a43b8
index 0000000..b7741e8
5a43b8
--- /dev/null
5a43b8
+++ b/memcheck/tests/linux/sys-copy_file_range.vgtest
5a43b8
@@ -0,0 +1,2 @@
5a43b8
+prereq: test -e sys-copy_file_range
5a43b8
+prog: sys-copy_file_range
5a43b8
commit bd27ad3ff31555484b7fdb310c4b033620882e44
5a43b8
Author: Mark Wielaard <mark@klomp.org>
5a43b8
Date:   Sun May 5 16:01:41 2019 +0200
5a43b8
5a43b8
    Hook linux copy_file_range syscall on arm.
5a43b8
5a43b8
diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c
5a43b8
index 9f1bdab..9ba0665 100644
5a43b8
--- a/coregrind/m_syswrap/syswrap-arm-linux.c
5a43b8
+++ b/coregrind/m_syswrap/syswrap-arm-linux.c
5a43b8
@@ -1016,6 +1016,8 @@ static SyscallTableEntry syscall_main_table[] = {
5a43b8
    LINXY(__NR_getrandom,         sys_getrandom),        // 384
5a43b8
    LINXY(__NR_memfd_create,      sys_memfd_create),     // 385
5a43b8
 
5a43b8
+   LINX_(__NR_copy_file_range,   sys_copy_file_range),  // 391
5a43b8
+
5a43b8
    LINXY(__NR_statx,             sys_statx),            // 397
5a43b8
 };
5a43b8
 
5a43b8
commit c212b72a63e43be323a4e028bbdbe8b023c22be8
5a43b8
Author: Mark Wielaard <mark@klomp.org>
5a43b8
Date:   Wed May 15 21:30:00 2019 +0200
5a43b8
5a43b8
    Explicitly make testcase variable for sys-copy_file_range undefined.
5a43b8
    
5a43b8
    On some systems an extra warning could occur when a variable in
5a43b8
    the memcheck/tests/linux/sys-copy_file_range testcase was undefined,
5a43b8
    but (accidentially) pointed to known bad memory. Fix by defining the
5a43b8
    variable as 0, but then marking it explicitly undefined using memcheck
5a43b8
    VALGRIND_MAKE_MEM_UNDEFINED.
5a43b8
    
5a43b8
    Followup for https://bugs.kde.org/show_bug.cgi?id=407218
5a43b8
5a43b8
diff --git a/memcheck/tests/linux/sys-copy_file_range.c b/memcheck/tests/linux/sys-copy_file_range.c
5a43b8
index 83981c6..589399c 100644
5a43b8
--- a/memcheck/tests/linux/sys-copy_file_range.c
5a43b8
+++ b/memcheck/tests/linux/sys-copy_file_range.c
5a43b8
@@ -3,8 +3,8 @@
5a43b8
 #include <stdio.h>
5a43b8
 #include <stdlib.h>
5a43b8
 #include <sys/stat.h>
5a43b8
-#include <sys/syscall.h>
5a43b8
 #include <unistd.h>
5a43b8
+#include "../../memcheck.h"
5a43b8
 
5a43b8
 int main(int argc, char **argv)
5a43b8
 {
5a43b8
@@ -51,7 +51,7 @@ int main(int argc, char **argv)
5a43b8
     /* Check valgrind will produce expected warnings for the
5a43b8
        various wrong arguments. */
5a43b8
     do {
5a43b8
-        void *t;
5a43b8
+        void *t = 0; VALGRIND_MAKE_MEM_UNDEFINED (&t, sizeof (void *));
5a43b8
         void *z = (void *) -1;
5a43b8
 
5a43b8
         ret = copy_file_range(fd_in, t, fd_out, NULL, len, 0);
5a43b8
commit 033d013bebeb3471c0da47060deb9a5771e6c913
5a43b8
Author: Mark Wielaard <mark@klomp.org>
5a43b8
Date:   Fri May 24 21:51:31 2019 +0200
5a43b8
5a43b8
    Fix memcheck/tests/linux/sys-copy_file_range open call (mode).
5a43b8
    
5a43b8
    sys-copy_file_range.c calls open with O_CREAT flag and so must provide
5a43b8
    a mode argument. valgrind memcheck actually caught this ommission on
5a43b8
    some arches (fedora rawhide i686 specifically).
5a43b8
    
5a43b8
    This is a small additional fixup for
5a43b8
    https://bugs.kde.org/show_bug.cgi?id=407218
5a43b8
5a43b8
diff --git a/memcheck/tests/linux/sys-copy_file_range.c b/memcheck/tests/linux/sys-copy_file_range.c
5a43b8
index 589399c..3022fa1 100644
5a43b8
--- a/memcheck/tests/linux/sys-copy_file_range.c
5a43b8
+++ b/memcheck/tests/linux/sys-copy_file_range.c
5a43b8
@@ -12,7 +12,7 @@ int main(int argc, char **argv)
5a43b8
     struct stat stat;
5a43b8
     loff_t len, ret;
5a43b8
 
5a43b8
-    fd_in = open("copy_file_range_source", O_CREAT | O_RDWR);
5a43b8
+    fd_in = open("copy_file_range_source", O_CREAT | O_RDWR, 0644);
5a43b8
     if (fd_in == -1) {
5a43b8
         perror("open copy_file_range_source");
5a43b8
         exit(EXIT_FAILURE);