]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 446823 FreeBSD - missing syscalls when using libzm4
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 11 Dec 2021 11:32:08 +0000 (12:32 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 11 Dec 2021 11:32:08 +0000 (12:32 +0100)
Adds syscall wrappers for __specialfd and __realpathat.
Also remove kernel dependency on COMPAT_FREEBSD10.

This change also reorganizes somewhat the scalar test
and adds configure time checks for the FreeBSD version,
allowing regression tests to be compiled depending on the
FreeBSD release.

From now on, scalar.c will contain syscalls for FreeBSD 11 and 12
and subsequent releases will get their own scalar, starting with
scalar_13_plus.c.

23 files changed:
NEWS
configure.ac
coregrind/m_libcfile.c
coregrind/m_syswrap/priv_syswrap-freebsd.h
coregrind/m_syswrap/syswrap-freebsd.c
include/vki/vki-scnums-freebsd.h
memcheck/tests/freebsd/Makefile.am
memcheck/tests/freebsd/eventfd1.c [new file with mode: 0644]
memcheck/tests/freebsd/eventfd1.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/eventfd1.stdout.exp [new file with mode: 0644]
memcheck/tests/freebsd/eventfd1.vgtest [new file with mode: 0644]
memcheck/tests/freebsd/eventfd2.c [new file with mode: 0644]
memcheck/tests/freebsd/eventfd2.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/eventfd2.stdout.exp [new file with mode: 0644]
memcheck/tests/freebsd/eventfd2.vgtest [new file with mode: 0644]
memcheck/tests/freebsd/realpathat.c [new file with mode: 0644]
memcheck/tests/freebsd/realpathat.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/realpathat.vgtest [new file with mode: 0644]
memcheck/tests/freebsd/scalar.c
memcheck/tests/freebsd/scalar.stderr.exp
memcheck/tests/freebsd/scalar_13_plus.c [new file with mode: 0644]
memcheck/tests/freebsd/scalar_13_plus.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/scalar_13_plus.vgtest [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 5a151584033febb6870f334f8cb075a6e3213796..ad49b98d3f8c6e4dc1e34380bb14eab13a8eb3ce 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -59,6 +59,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 446138  DRD/Helgrind with std::timed_mutex::try_lock_until false positives
 446281  Add a DRD suppression for fwrite
 446103  Memcheck: `--track-origins=yes` causes extreme slowdowns for large mmap/munmap
+446823  FreeBSD - missing syscalls when using libzm4
 
 To see details of a given bug, visit
   https://bugs.kde.org/show_bug.cgi?id=XXXXXX
index 96df114baeca0cee8c332ec35e69b74ce1e7fa4d..56a1d7e766fcf2add18bb56732a2ef197c071cbf 100755 (executable)
@@ -387,11 +387,17 @@ case "${host_os}" in
         AC_MSG_RESULT([ok (${host_os})])
         VGCONF_OS="freebsd"
         AC_DEFINE([FREEBSD_10], 1000, [FREEBSD_VERS value for FreeBSD 10.x])
+        freebsd_10=1000
         AC_DEFINE([FREEBSD_11], 1100, [FREEBSD_VERS value for FreeBSD 11.x])
+        freebsd_11=1100
         AC_DEFINE([FREEBSD_12], 1200, [FREEBSD_VERS value for FreeBSD 12.0 to 12.1])
+        freebsd_12=1200
         AC_DEFINE([FREEBSD_12_2], 1220, [FREEBSD_VERS value for FreeBSD 12.2])
+        freebsd_12_2=1220
         AC_DEFINE([FREEBSD_13], 1300, [FREEBSD_VERS value for FreeBSD 13.x])
+        freebsd_13=1300
         AC_DEFINE([FREEBSD_14], 1400, [FREEBSD_VERS value for FreeBSD 14.x])
+        freebsd_14=1400
 
         AC_MSG_CHECKING([for the kernel version])
         kernel=`uname -r`
@@ -400,30 +406,36 @@ case "${host_os}" in
         10.*)
            AC_MSG_RESULT([FreeBSD 10.x (${kernel})])
            AC_DEFINE([FREEBSD_VERS], FREEBSD_10, [FreeBSD version])
+           freebsd_vers=$freebsd_10
            ;;
         11.*)
            AC_MSG_RESULT([FreeBSD 11.x (${kernel})])
            AC_DEFINE([FREEBSD_VERS], FREEBSD_11, [FreeBSD version])
+           freebsd_vers=$freebsd_11
            ;;
         12.*)
            case "${kernel}" in
            12.[[0-1]]-*)
               AC_MSG_RESULT([FreeBSD 12.x (${kernel})])
               AC_DEFINE([FREEBSD_VERS], FREEBSD_12, [FreeBSD version])
+              freebsd_vers=$freebsd_12
               ;;
            *)
               AC_MSG_RESULT([FreeBSD 12.x (${kernel})])
               AC_DEFINE([FREEBSD_VERS], FREEBSD_12_2, [FreeBSD version])
+              freebsd_vers=$freebsd_12_2
               ;;
            esac
            ;;
         13.*)
            AC_MSG_RESULT([FreeBSD 13.x (${kernel})])
            AC_DEFINE([FREEBSD_VERS], FREEBSD_13, [FreeBSD version])
+           freebsd_vers=$freebsd_13
            ;;
         14.*)
            AC_MSG_RESULT([FreeBSD 14.x (${kernel})])
            AC_DEFINE([FREEBSD_VERS], FREEBSD_14, [FreeBSD version])
+           freebsd_vers=$freebsd_14
            ;;
         *)
            AC_MSG_RESULT([unsupported (${kernel})])
@@ -4602,6 +4614,25 @@ AM_CONDITIONAL(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR, false)
 AM_CONDITIONAL(SOLARIS_SYSTEM_STATS_SYSCALL, false)
 fi # test "$VGCONF_OS" = "solaris"
 
+#----------------------------------------------------------------------------
+# FreeBSD-specific checks.
+#----------------------------------------------------------------------------
+
+# Rather than having a large number of feature test as above with Solaris
+# these tests are per-version. This may not be entirely relialable for
+# FreeBSD development branches (XX.Y-CURRENT) or pre-release branches
+# (XX.Y-STABLE) but it should work for XX-Y-RELEASE
+
+if test "$VGCONF_OS" = "freebsd" ; then
+
+AM_CONDITIONAL(FREEBSD_VERS_13_PLUS, test $freebsd_vers -ge $freebsd_13)
+
+else
+
+AM_CONDITIONAL(FREEBSD_VERS_13_PLUS, false)
+
+fi # test "$VGCONF_OS" = "freebsd"
+
 
 #----------------------------------------------------------------------------
 # Checks for C header files.
index 5f9c76efe5f97f929b1dc4c182f36f415c841eae..94c2f030aca8da769fdfb0e7f66888b055a5a9ac 100644 (file)
@@ -331,11 +331,15 @@ Int VG_(pipe) ( Int fd[2] )
    SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
    return sr_isError(res) ? -1 : 0;
 #  elif defined(VGO_freebsd)
+#if defined(__NR_pipe2)
+   SysRes res = VG_(do_syscall2)(__NR_pipe2, (UWord)fd, 0);
+#else
    SysRes res = VG_(do_syscall0)(__NR_freebsd10_pipe);
    if (!sr_isError(res)) {
       fd[0] = sr_Res(res);
       fd[1] = sr_ResHI(res);
    }
+#endif
    return sr_isError(res) ? -1 : 0;
 #  elif defined(VGO_darwin)
    /* __NR_pipe is UX64, so produces a double-word result */
index 0b60467df135287f0589f4271531f1324f9235b2..79a1d9502ff03510ce1f1321ab309be4b742c5fb 100644 (file)
@@ -526,7 +526,7 @@ DECL_TEMPLATE(freebsd, sys___sysctlbyname) // 570
 // unimpl __NR_shm_open2           571
 // unimpl __NR_shm_rename          572
 // unimpl __NR_sigfastblock        573
-// unimpl __NR___realpathat        574
+DECL_TEMPLATE(freebsd, sys___realpathat) // 574
 // unimpl __NR_close_range         575
 
 #endif
@@ -534,12 +534,7 @@ DECL_TEMPLATE(freebsd, sys___sysctlbyname) // 570
 #if (FREEBSD_VERS >= FREEBSD_13)
 
 // unimpl __NR_rpctls_syscall      576
-
-#endif
-
-#if (FREEBSD_VERS >= FREEBSD_14)
-
-// unimpl __NR___specialfd         577
+DECL_TEMPLATE(freebsd, sys___specialfd) // 577
 // unimpl __NR_aio_writev          578
 // unimpl __NR_aio_readv           579
 
index 5eb0b5b134bcbcfe0413d5cba573be5d2afa2c0b..4f1574c353cab67200e6713a368343cda2712313 100644 (file)
@@ -6206,7 +6206,46 @@ POST(sys___sysctlbyname)
    }
 }
 
-#endif
+// SYS___realpathat
+// from syscalls.master
+//         int __realpathat(int fd,
+//         _In_z_ const char *path,
+//         _Out_writes_z_(size) char *buf,
+//         size_t size,
+//         int flags)
+PRE(sys___realpathat)
+{
+   PRINT("sys___realpathat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %" FMT_REGWORD "u %" FMT_REGWORD "d )",
+         SARG1,ARG2,(const char*)ARG2,ARG3,ARG4,SARG5 );
+   PRE_REG_READ5(int, "__realpathat", int, fd, const char *, path,
+                 char *, buf, vki_size_t, size, int, flags);
+   PRE_MEM_RASCIIZ("__realpathat(path)", (Addr)ARG2);
+   PRE_MEM_WRITE("__realpathat(buf)", (Addr)ARG3, ARG4);
+}
+
+POST(sys___realpathat)
+{
+   POST_MEM_WRITE((Addr)ARG3, ARG4);
+}
+
+#endif // (FREEBSD_VERS >= FREEBSD_12_2)
+
+#if (FREEBSD_VERS >= FREEBSD_13)
+
+// SYS___specialfd
+// syscalls.master
+// int __specialfd(int type,
+//                _In_reads_bytes_(len) const void *req,
+//                 size_t len);
+PRE(sys___specialfd)
+{
+   PRINT("sys___specialfd ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
+         SARG1,ARG2,(const char*)ARG2,ARG3 );
+   PRE_REG_READ3(int, "__specialfd", int, type, const void *, req, vki_size_t, len);
+   PRE_MEM_READ("__specialfd(req)", (Addr)ARG2, ARG3);
+}
+
+#endif // (FREEBSD_VERS >= FREEBSD_13)
 
 #undef PRE
 #undef POST
@@ -6903,16 +6942,13 @@ const SyscallTableEntry ML_(syscall_table)[] = {
    // unimpl __NR_shm_open2           571
    // unimpl __NR_shm_rename          572
    // unimpl __NR_sigfastblock        573
-   // unimpl __NR___realpathat        574
+   BSDXY( __NR___realpathat,    sys___realpathat),      // 574
    // unimpl __NR_close_range         575
 #endif
 
 #if (FREEBSD_VERS >= FREEBSD_13)
    // unimpl __NR_rpctls_syscall      576
-#endif
-
-#if (FREEBSD_VERS >= FREEBSD_14)
-   // unimpl __NR___specialfd         577
+   BSDX_(__NR___specialfd,      sys___specialfd),       // 577
    // unimpl __NR_aio_writev          578
    // unimpl __NR_aio_readv           579
 #endif
index 3ea7d460e3717b760249aba9b303c95875148b33..f3247e5376d08947d0e01a712a219c4b3e3f05bb 100644 (file)
 #if (FREEBSD_VERS >= FREEBSD_13)
 
 #define __NR_rpctls_syscall      576
-
-#endif
-
-#if (FREEBSD_VERS >= FREEBSD_14)
-
 #define __NR___specialfd         577
 #define __NR_aio_writev          578
 #define __NR_aio_readv           579
index e05542d818ae10ebeb4bfd19dfa62c62d4d8aeae..f3bd873d767d33b821ec3a55a32cc5fd396d082a 100644 (file)
@@ -72,7 +72,15 @@ EXTRA_DIST = \
        static_allocs.vgtest \
        static_allocs.stderr.exp \
        fexecve.vgtest \
-       fexecve.stderr.exp
+       fexecve.stderr.exp \
+       realpathat.vgtest \
+       realpathat.stderr.exp \
+       scalar_13_plus.vgtest \
+       scalar_13_plus.stderr.exp \
+       eventfd1.vgtest \
+       eventfd1.stderr.exp eventfd1.stdout.exp \
+       eventfd2.vgtest \
+       eventfd2.stderr.exp eventfd2.stdout.exp
 
 check_PROGRAMS = \
        statfs pdfork_pdkill getfsstat inlinfo inlinfo_nested.so extattr \
@@ -92,4 +100,10 @@ inlinfo_nested_so_SOURCES = inlinfo_nested.c
 inlinfo_nested_so_CFLAGS = $(AM_CFLAGS) -fPIC @FLAG_W_NO_UNINITIALIZED@
 inlinfo_nested_so_LDFLAGS = -Wl,-rpath,$(top_builddir)/memcheck/tests/freebsd -shared -fPIC
 
+if FREEBSD_VERS_13_PLUS
+check_PROGRAMS += realpathat scalar_13_plus eventfd1 eventfd2
+
+scalar_13_plus_CFLAGS = ${AM_CFLAGS} -g
+endif
+
 scalar_CFLAGS = ${AM_CFLAGS} -g
diff --git a/memcheck/tests/freebsd/eventfd1.c b/memcheck/tests/freebsd/eventfd1.c
new file mode 100644 (file)
index 0000000..91f148f
--- /dev/null
@@ -0,0 +1,58 @@
+#include <sys/eventfd.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define handle_error(msg) \
+do { \
+perror(msg); \
+exit(EXIT_FAILURE); \
+} while (0)
+
+int
+main(int argc, char *argv[])
+{
+   eventfd_t u;
+   int efd, j;
+   int error;
+
+   if (argc < 2) {
+      fprintf(stderr, "Usage: %s <num>...\n", argv[0]);
+      exit(EXIT_FAILURE);
+   }
+
+   efd = eventfd(0, EFD_CLOEXEC);
+   if (efd == -1)
+      handle_error("eventfd");
+
+   switch (fork()) {
+   case 0:
+      for (j = 1; j < argc; j++) {
+         printf("Child writing %s to efd\n", argv[j]);
+         u = strtoull(argv[j], NULL, 0);
+
+         error = eventfd_write(efd, u);
+         if (error != 0)
+            handle_error("write");
+      }
+      printf("Child completed write loop\n");
+
+      exit(EXIT_SUCCESS);
+
+   default:
+      sleep(2);
+
+      printf("Parent about to read\n");
+      error = eventfd_read(efd, &u);
+      if (error != 0)
+         handle_error("read");
+      printf("Parent read %llu (0x%llx) from efd\n",
+             (unsigned long long) u, (unsigned long long) u);
+      exit(EXIT_SUCCESS);
+
+   case -1:
+
+      handle_error("fork");
+
+   }
+}
diff --git a/memcheck/tests/freebsd/eventfd1.stderr.exp b/memcheck/tests/freebsd/eventfd1.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/memcheck/tests/freebsd/eventfd1.stdout.exp b/memcheck/tests/freebsd/eventfd1.stdout.exp
new file mode 100644 (file)
index 0000000..f2e4280
--- /dev/null
@@ -0,0 +1,4 @@
+Child writing 2 to efd
+Child completed write loop
+Parent about to read
+Parent read 2 (0x2) from efd
diff --git a/memcheck/tests/freebsd/eventfd1.vgtest b/memcheck/tests/freebsd/eventfd1.vgtest
new file mode 100644 (file)
index 0000000..8e35dce
--- /dev/null
@@ -0,0 +1,5 @@
+prereq: test -e ./eventfd1
+prog: eventfd1
+args: 2
+vgopts: -q
+
diff --git a/memcheck/tests/freebsd/eventfd2.c b/memcheck/tests/freebsd/eventfd2.c
new file mode 100644 (file)
index 0000000..8e2309f
--- /dev/null
@@ -0,0 +1,99 @@
+/* EFD_SEMAPHORE */
+
+#include <sys/eventfd.h>
+#include <sys/wait.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static void xsem_wait(int fd)
+{
+   eventfd_t cntr;
+
+   if (eventfd_read(fd, &cntr) != 0) {
+      perror("reading eventfd");
+      exit(1);
+   }
+
+   fprintf(stdout, "wait completed on %d: count=%" PRIu64 "\n",
+           fd, cntr);
+}
+
+static void xsem_post(int fd, int count)
+{
+   eventfd_t cntr = count;
+
+   if (eventfd_write(fd, cntr) != 0) {
+      perror("writing eventfd");
+      exit(1);
+   }
+}
+
+static void sem_player(int fd1, int fd2)
+{
+   /* these printfs did contain the pid
+    * so "[%u] ... ", getpid()
+    * not good for regresson tests
+    * (also xsem_wait above)
+    */
+   fprintf(stdout, "posting 1 on %d\n", fd1);
+   xsem_post(fd1, 1);
+
+   fprintf(stdout, "waiting on %d\n", fd2);
+   xsem_wait(fd2);
+
+   fprintf(stdout, "posting 1 on %d\n", fd1);
+   xsem_post(fd1, 1);
+
+   fprintf(stdout, "waiting on %d\n", fd2);
+   xsem_wait(fd2);
+
+   fprintf(stdout, "posting 5 on %d\n", fd1);
+   xsem_post(fd1, 5);
+
+   fprintf(stdout, "waiting 5 times on %d\n", fd2);
+   xsem_wait(fd2);
+   xsem_wait(fd2);
+   xsem_wait(fd2);
+   xsem_wait(fd2);
+   xsem_wait(fd2);
+}
+
+static void usage(char const *prg)
+{
+   fprintf(stderr, "use: %s [-h]\n", prg);
+}
+
+int main(int argc, char **argv)
+{
+   int c, fd1, fd2, status;
+   pid_t cpid_poster, cpid_waiter;
+
+   while ((c = getopt(argc, argv, "h")) != -1) {
+
+      switch (c) {
+      default:
+         usage(argv[0]);
+         return 1;
+      }
+   }
+
+   if ((fd1 = eventfd(0, EFD_SEMAPHORE)) == -1 ||
+       (fd2 = eventfd(0, EFD_SEMAPHORE)) == -1) {
+      perror("eventfd");
+      return 1;
+   }
+   if ((cpid_poster = fork()) == 0) {
+      sem_player(fd1, fd2);
+      exit(0);
+   }
+   if ((cpid_waiter = fork()) == 0) {
+      sem_player(fd2, fd1);
+      exit(0);
+   }
+   waitpid(cpid_poster, &status, 0);
+   waitpid(cpid_waiter, &status, 0);
+
+   exit(0);
+}
diff --git a/memcheck/tests/freebsd/eventfd2.stderr.exp b/memcheck/tests/freebsd/eventfd2.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/memcheck/tests/freebsd/eventfd2.stdout.exp b/memcheck/tests/freebsd/eventfd2.stdout.exp
new file mode 100644 (file)
index 0000000..6a2cd19
--- /dev/null
@@ -0,0 +1,26 @@
+posting 1 on 3
+waiting on 4
+wait completed on 4: count=1
+posting 1 on 3
+waiting on 4
+wait completed on 4: count=1
+posting 5 on 3
+waiting 5 times on 4
+wait completed on 4: count=1
+wait completed on 4: count=1
+wait completed on 4: count=1
+wait completed on 4: count=1
+wait completed on 4: count=1
+posting 1 on 4
+waiting on 3
+wait completed on 3: count=1
+posting 1 on 4
+waiting on 3
+wait completed on 3: count=1
+posting 5 on 4
+waiting 5 times on 3
+wait completed on 3: count=1
+wait completed on 3: count=1
+wait completed on 3: count=1
+wait completed on 3: count=1
+wait completed on 3: count=1
diff --git a/memcheck/tests/freebsd/eventfd2.vgtest b/memcheck/tests/freebsd/eventfd2.vgtest
new file mode 100644 (file)
index 0000000..7dd3ad1
--- /dev/null
@@ -0,0 +1,3 @@
+prog: eventfd2
+prereq: test -e ./eventfd2
+vgopts: -q
diff --git a/memcheck/tests/freebsd/realpathat.c b/memcheck/tests/freebsd/realpathat.c
new file mode 100644 (file)
index 0000000..218fd75
--- /dev/null
@@ -0,0 +1,33 @@
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <sys/fcntl.h>
+
+int main(void)
+{
+   // good
+   char buf[PATH_MAX];
+   char* self_path = "../../tests/freebsd/realpath.c";
+   realpath(self_path, buf);
+   
+   // bad
+   int * bad_int1 = malloc(sizeof(char));
+   int * bad_int2 = malloc(sizeof(char));
+   *bad_int1 = AT_FDCWD;
+   *bad_int2 = 0;
+   syscall(SYS___realpathat, *bad_int1, self_path, buf, *bad_int2);
+   free(bad_int1);
+   free(bad_int2);
+   
+   // ugly
+   char * bad_buf = malloc(100);
+   char* bad_buf2 = strdup(self_path);
+   free(bad_buf);
+   free(bad_buf2);
+   // fingers crossed
+   realpath(bad_buf2, bad_buf);
+   
+   
+}
diff --git a/memcheck/tests/freebsd/realpathat.stderr.exp b/memcheck/tests/freebsd/realpathat.stderr.exp
new file mode 100644 (file)
index 0000000..575f1e6
--- /dev/null
@@ -0,0 +1,162 @@
+Invalid write of size 4
+   at 0x........: main (realpathat.c:18)
+ Address 0x........ is 0 bytes inside a block of size 1 alloc'd
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:16)
+
+Invalid write of size 4
+   at 0x........: main (realpathat.c:19)
+ Address 0x........ is 0 bytes inside a block of size 1 alloc'd
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:17)
+
+Syscall param __realpathat(fd) contains uninitialised byte(s)
+   ...
+   by 0x........: main (realpathat.c:20)
+
+Syscall param __realpathat(size) contains uninitialised byte(s)
+   ...
+   by 0x........: main (realpathat.c:20)
+
+Invalid read of size 1
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 0 bytes inside a block of size 31 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:28)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   ...
+   by 0x........: main (realpathat.c:26)
+
+Syscall param __realpathat(path) points to unaddressable byte(s)
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 0 bytes inside a block of size 31 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:28)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   ...
+   by 0x........: main (realpathat.c:26)
+
+Syscall param __realpathat(buf) points to unaddressable byte(s)
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 0 bytes inside a block of size 100 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:27)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:25)
+
+Invalid read of size 1
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 0 bytes inside a block of size 31 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:28)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   ...
+   by 0x........: main (realpathat.c:26)
+
+Syscall param __getcwd(buf) points to unaddressable byte(s)
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 0 bytes inside a block of size 100 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:27)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:25)
+
+Invalid read of size 1
+   at 0x........: strlcpy (vg_replace_strmem.c:...)
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 0 bytes inside a block of size 31 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:28)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   ...
+   by 0x........: main (realpathat.c:26)
+
+Invalid read of size 1
+   at 0x........: strlcpy (vg_replace_strmem.c:...)
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 1 bytes inside a block of size 31 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:28)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   ...
+   by 0x........: main (realpathat.c:26)
+
+Invalid read of size 1
+   at 0x........: strlcpy (vg_replace_strmem.c:...)
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 30 bytes inside a block of size 31 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:28)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   ...
+   by 0x........: main (realpathat.c:26)
+
+Invalid write of size 2
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 55 bytes inside a block of size 100 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:27)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:25)
+
+Invalid read of size 1
+   at 0x........: strlcat (vg_replace_strmem.c:...)
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 56 bytes inside a block of size 100 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:27)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:25)
+
+Invalid write of size 1
+   at 0x........: strlcat (vg_replace_strmem.c:...)
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 56 bytes inside a block of size 100 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:27)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:25)
+
+Invalid write of size 1
+   at 0x........: strlcat (vg_replace_strmem.c:...)
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 66 bytes inside a block of size 100 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:27)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:25)
+
+Syscall param fstatat(path) points to unaddressable byte(s)
+   ...
+   by 0x........: main (realpathat.c:30)
+ Address 0x........ is 56 bytes inside a block of size 100 free'd
+   at 0x........: free (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:27)
+ Block was alloc'd at
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: main (realpathat.c:25)
+
diff --git a/memcheck/tests/freebsd/realpathat.vgtest b/memcheck/tests/freebsd/realpathat.vgtest
new file mode 100644 (file)
index 0000000..9efbcbd
--- /dev/null
@@ -0,0 +1,3 @@
+prog: realpathat
+prereq: test -e ./realpathat
+vgopts: -q
index 140ee8256847cb575d3fa835841b8b0cbcc6c05c..35c3c85cf3c075eabd96ecaa95b925de15a44085 100644 (file)
@@ -2035,6 +2035,9 @@ int main(void)
 
    GO(SYS___sysctlbyname, "(putnew) 4s 2m");
    SY(SYS___sysctlbyname, x0, x0+1, NULL, NULL, x0+1, x0+2); FAIL;
+   
+   GO(SYS___realpathat, " 5s 2m");
+   SY(SYS___realpathat, x0+0xffff, x0, x0, x0+100, x0+2); FAIL;
 
 #endif
 
index 8e7f9fb145231764c650eb881da9030785cd6c43..aa214f514475d40496a65b8163c5bb7871a56f29 100644 (file)
@@ -5310,6 +5310,32 @@ Syscall param __sysctlbyname(newp) points to unaddressable byte(s)
    ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 
+---------------------------------------------------------
+574:        SYS___realpathat  5s 2m
+---------------------------------------------------------
+Syscall param __realpathat(fd) contains uninitialised byte(s)
+   ...
+
+Syscall param __realpathat(path) contains uninitialised byte(s)
+   ...
+
+Syscall param __realpathat(buf) contains uninitialised byte(s)
+   ...
+
+Syscall param __realpathat(size) contains uninitialised byte(s)
+   ...
+
+Syscall param __realpathat(flags) contains uninitialised byte(s)
+   ...
+
+Syscall param __realpathat(path) points to unaddressable byte(s)
+   ...
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param __realpathat(buf) points to unaddressable byte(s)
+   ...
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
 ---------------------------------------------------------
   1:                SYS_exit 1s 0m
 ---------------------------------------------------------
diff --git a/memcheck/tests/freebsd/scalar_13_plus.c b/memcheck/tests/freebsd/scalar_13_plus.c
new file mode 100644 (file)
index 0000000..1183d4e
--- /dev/null
@@ -0,0 +1,15 @@
+#include "scalar.h"
+
+int main(void)
+{
+   long *px = malloc(2*sizeof(long));
+   x0 = px[0];
+
+   
+   /* SYS___specialfd                    574 */
+   GO(SYS___specialfd, "3s 1m");
+   SY(SYS___specialfd, x0+0xf000, x0+1, x0+10); FAIL;
+
+   return(0);
+}
+
diff --git a/memcheck/tests/freebsd/scalar_13_plus.stderr.exp b/memcheck/tests/freebsd/scalar_13_plus.stderr.exp
new file mode 100644 (file)
index 0000000..2df127e
--- /dev/null
@@ -0,0 +1,16 @@
+---------------------------------------------------------
+577:         SYS___specialfd 3s 1m
+---------------------------------------------------------
+Syscall param __specialfd(type) contains uninitialised byte(s)
+   ...
+
+Syscall param __specialfd(req) contains uninitialised byte(s)
+   ...
+
+Syscall param __specialfd(len) contains uninitialised byte(s)
+   ...
+
+Syscall param __specialfd(req) points to unaddressable byte(s)
+   ...
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
diff --git a/memcheck/tests/freebsd/scalar_13_plus.vgtest b/memcheck/tests/freebsd/scalar_13_plus.vgtest
new file mode 100644 (file)
index 0000000..09dc90e
--- /dev/null
@@ -0,0 +1,12 @@
+prereq: test -e ./scalar_13_plus
+prog: scalar_13_plus
+vgopts: -q --error-limit=no
+stderr_filter: filter_scalar
+# Remove all frames from the stack trace except the first one.
+# This is important because syscall() function on x86 isn't ABI conformant
+# which confuses the Valgrind stack unwinder.
+# Therefore x86 and amd64 stack traces are unified so that they contain only
+# 'syscall (in libc)' stack frame and this is then filtered out completely.
+stderr_filter_args: libc
+args: < scalar_13_plus.c
+