From bb178889c739203464242c60161927c07bf94722 Mon Sep 17 00:00:00 2001 From: Paul Floyd Date: Sat, 11 Dec 2021 12:32:08 +0100 Subject: [PATCH] Bug 446823 FreeBSD - missing syscalls when using libzm4 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. --- NEWS | 1 + configure.ac | 31 ++++ coregrind/m_libcfile.c | 4 + coregrind/m_syswrap/priv_syswrap-freebsd.h | 9 +- coregrind/m_syswrap/syswrap-freebsd.c | 48 +++++- include/vki/vki-scnums-freebsd.h | 5 - memcheck/tests/freebsd/Makefile.am | 16 +- memcheck/tests/freebsd/eventfd1.c | 58 +++++++ memcheck/tests/freebsd/eventfd1.stderr.exp | 0 memcheck/tests/freebsd/eventfd1.stdout.exp | 4 + memcheck/tests/freebsd/eventfd1.vgtest | 5 + memcheck/tests/freebsd/eventfd2.c | 99 +++++++++++ memcheck/tests/freebsd/eventfd2.stderr.exp | 0 memcheck/tests/freebsd/eventfd2.stdout.exp | 26 +++ memcheck/tests/freebsd/eventfd2.vgtest | 3 + memcheck/tests/freebsd/realpathat.c | 33 ++++ memcheck/tests/freebsd/realpathat.stderr.exp | 162 ++++++++++++++++++ memcheck/tests/freebsd/realpathat.vgtest | 3 + memcheck/tests/freebsd/scalar.c | 3 + memcheck/tests/freebsd/scalar.stderr.exp | 26 +++ memcheck/tests/freebsd/scalar_13_plus.c | 15 ++ .../tests/freebsd/scalar_13_plus.stderr.exp | 16 ++ memcheck/tests/freebsd/scalar_13_plus.vgtest | 12 ++ 23 files changed, 560 insertions(+), 19 deletions(-) create mode 100644 memcheck/tests/freebsd/eventfd1.c create mode 100644 memcheck/tests/freebsd/eventfd1.stderr.exp create mode 100644 memcheck/tests/freebsd/eventfd1.stdout.exp create mode 100644 memcheck/tests/freebsd/eventfd1.vgtest create mode 100644 memcheck/tests/freebsd/eventfd2.c create mode 100644 memcheck/tests/freebsd/eventfd2.stderr.exp create mode 100644 memcheck/tests/freebsd/eventfd2.stdout.exp create mode 100644 memcheck/tests/freebsd/eventfd2.vgtest create mode 100644 memcheck/tests/freebsd/realpathat.c create mode 100644 memcheck/tests/freebsd/realpathat.stderr.exp create mode 100644 memcheck/tests/freebsd/realpathat.vgtest create mode 100644 memcheck/tests/freebsd/scalar_13_plus.c create mode 100644 memcheck/tests/freebsd/scalar_13_plus.stderr.exp create mode 100644 memcheck/tests/freebsd/scalar_13_plus.vgtest diff --git a/NEWS b/NEWS index 5a15158403..ad49b98d3f 100644 --- 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 diff --git a/configure.ac b/configure.ac index 96df114bae..56a1d7e766 100755 --- a/configure.ac +++ b/configure.ac @@ -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. diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c index 5f9c76efe5..94c2f030ac 100644 --- a/coregrind/m_libcfile.c +++ b/coregrind/m_libcfile.c @@ -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 */ diff --git a/coregrind/m_syswrap/priv_syswrap-freebsd.h b/coregrind/m_syswrap/priv_syswrap-freebsd.h index 0b60467df1..79a1d9502f 100644 --- a/coregrind/m_syswrap/priv_syswrap-freebsd.h +++ b/coregrind/m_syswrap/priv_syswrap-freebsd.h @@ -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 diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index 5eb0b5b134..4f1574c353 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -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 diff --git a/include/vki/vki-scnums-freebsd.h b/include/vki/vki-scnums-freebsd.h index 3ea7d460e3..f3247e5376 100644 --- a/include/vki/vki-scnums-freebsd.h +++ b/include/vki/vki-scnums-freebsd.h @@ -643,11 +643,6 @@ #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 diff --git a/memcheck/tests/freebsd/Makefile.am b/memcheck/tests/freebsd/Makefile.am index e05542d818..f3bd873d76 100644 --- a/memcheck/tests/freebsd/Makefile.am +++ b/memcheck/tests/freebsd/Makefile.am @@ -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 index 0000000000..91f148f5f8 --- /dev/null +++ b/memcheck/tests/freebsd/eventfd1.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include + +#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 ...\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 index 0000000000..e69de29bb2 diff --git a/memcheck/tests/freebsd/eventfd1.stdout.exp b/memcheck/tests/freebsd/eventfd1.stdout.exp new file mode 100644 index 0000000000..f2e4280ef2 --- /dev/null +++ b/memcheck/tests/freebsd/eventfd1.stdout.exp @@ -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 index 0000000000..8e35dce8be --- /dev/null +++ b/memcheck/tests/freebsd/eventfd1.vgtest @@ -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 index 0000000000..8e2309f96d --- /dev/null +++ b/memcheck/tests/freebsd/eventfd2.c @@ -0,0 +1,99 @@ +/* EFD_SEMAPHORE */ + +#include +#include +#include +#include +#include +#include + +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 index 0000000000..e69de29bb2 diff --git a/memcheck/tests/freebsd/eventfd2.stdout.exp b/memcheck/tests/freebsd/eventfd2.stdout.exp new file mode 100644 index 0000000000..6a2cd1944e --- /dev/null +++ b/memcheck/tests/freebsd/eventfd2.stdout.exp @@ -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 index 0000000000..7dd3ad1ea8 --- /dev/null +++ b/memcheck/tests/freebsd/eventfd2.vgtest @@ -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 index 0000000000..218fd75cb2 --- /dev/null +++ b/memcheck/tests/freebsd/realpathat.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include +#include + +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 index 0000000000..575f1e6a98 --- /dev/null +++ b/memcheck/tests/freebsd/realpathat.stderr.exp @@ -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 index 0000000000..9efbcbdfcf --- /dev/null +++ b/memcheck/tests/freebsd/realpathat.vgtest @@ -0,0 +1,3 @@ +prog: realpathat +prereq: test -e ./realpathat +vgopts: -q diff --git a/memcheck/tests/freebsd/scalar.c b/memcheck/tests/freebsd/scalar.c index 140ee82568..35c3c85cf3 100644 --- a/memcheck/tests/freebsd/scalar.c +++ b/memcheck/tests/freebsd/scalar.c @@ -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 diff --git a/memcheck/tests/freebsd/scalar.stderr.exp b/memcheck/tests/freebsd/scalar.stderr.exp index 8e7f9fb145..aa214f5144 100644 --- a/memcheck/tests/freebsd/scalar.stderr.exp +++ b/memcheck/tests/freebsd/scalar.stderr.exp @@ -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 index 0000000000..1183d4e233 --- /dev/null +++ b/memcheck/tests/freebsd/scalar_13_plus.c @@ -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 index 0000000000..2df127e8a6 --- /dev/null +++ b/memcheck/tests/freebsd/scalar_13_plus.stderr.exp @@ -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 index 0000000000..09dc90e90b --- /dev/null +++ b/memcheck/tests/freebsd/scalar_13_plus.vgtest @@ -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 + -- 2.47.3