/memcheck/tests/wcs
/memcheck/tests/weirdioctl
/memcheck/tests/with space
+/memcheck/tests/wcsncpy
/memcheck/tests/wmemcmp
/memcheck/tests/wrap1
/memcheck/tests/wrap2
/memcheck/tests/freebsd/statfs
/memcheck/tests/freebsd/static_allocs
/memcheck/tests/freebsd/timerfd
-/memcheck/tests/freebsd/timingsafe
+/memcheck/tests/freebsd/timing_safe
/memcheck/tests/freebsd/utimens
/memcheck/tests/freebsd/utimes
473944 Handle mold linker split RW PT_LOAD segments correctly
474332 aligned_alloc under Valgrind returns nullptr when alignment is not a multiple of sizeof(void *)
475650 DRD does not work with C11 threads
+475652 Missing suppression for __wcsncpy_avx2 (strncpy-avx2.S:308)?
n-i-bz Allow arguments with spaces in .valgrindrc files
n-i-bz FreeBSD fixed reading of Valgrind tools own debuginfo
strchrnul \
memrchr \
strndup \
- close_range
+ close_range \
+ wcsncpy
])
# AC_CHECK_LIB adds any library found to the variable LIBS, and links these
[test x$ac_cv_func_getaddrinfo = xyes])
AM_CONDITIONAL([HAVE_CLOSE_RANGE],
[test x$ac_cv_func_close_range = xyes])
+AM_CONDITIONAL([HAVE_WCSNCPY],
+ [test x$ac_cv_func_wcsncpy = xyes])
if test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX \
-o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX \
vcpu_fnfns.stdout.exp-darwin vcpu_fnfns.stdout.exp-solaris \
vcpu_fnfns.stderr.exp vcpu_fnfns.vgtest \
wcs.vgtest wcs.stderr.exp wcs.stdout.exp \
+ wcsncpy.vgtest wcsncpy.stderr.exp \
wmemcmp.vgtest wmemcmp.stderr.exp \
wrap1.vgtest wrap1.stdout.exp wrap1.stderr.exp \
wrap2.vgtest wrap2.stdout.exp wrap2.stderr.exp \
check_PROGRAMS += threadname
endif
+# are there still pre-C99 C compilers?
+if HAVE_WCSNCPY
+check_PROGRAMS += wcsncpy
+endif
+
AM_CFLAGS += $(AM_FLAG_M3264_PRI)
AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
timerfd.vgtest \
timerfd.stderr.exp \
timerfd.stdout.exp \
- timingsafe.vgtest \
- timingsafe.stderr.exp \
+ timing_safe.vgtest \
+ timing_safe.stderr.exp \
utimens.vgtest \
utimens.stderr.exp \
utimes.vgtest \
stat \
statfs \
static_allocs \
- timingsafe \
+ timing_safe \
utimens \
utimes
--- /dev/null
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: timingsafe_bcmp (vg_replace_strmem.c:...)
+ by 0x........: main (timing_safe.c:30)
+
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: timingsafe_bcmp (vg_replace_strmem.c:...)
+ by 0x........: main (timing_safe.c:30)
+
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: timingsafe_memcmp (vg_replace_strmem.c:...)
+ by 0x........: main (timing_safe.c:31)
+
+Conditional jump or move depends on uninitialised value(s)
+ at 0x........: timingsafe_memcmp (vg_replace_strmem.c:...)
+ by 0x........: main (timing_safe.c:31)
+
+Invalid read of size 1
+ at 0x........: timingsafe_bcmp (vg_replace_strmem.c:...)
+ by 0x........: main (timing_safe.c:35)
+ Address 0x........ is 0 bytes after a block of size 12 alloc'd
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ ...
+ by 0x........: main (timing_safe.c:33)
+
+Invalid read of size 1
+ at 0x........: timingsafe_memcmp (vg_replace_strmem.c:...)
+ by 0x........: main (timing_safe.c:36)
+ Address 0x........ is 0 bytes after a block of size 12 alloc'd
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ ...
+ by 0x........: main (timing_safe.c:33)
+
+Invalid read of size 1
+ at 0x........: timingsafe_bcmp (vg_replace_strmem.c:...)
+ by 0x........: main (timing_safe.c:40)
+ Address 0x........ is 0 bytes inside a block of size 12 free'd
+ at 0x........: free (vg_replace_malloc.c:...)
+ by 0x........: main (timing_safe.c:38)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ ...
+ by 0x........: main (timing_safe.c:33)
+
+Invalid read of size 1
+ at 0x........: timingsafe_memcmp (vg_replace_strmem.c:...)
+ by 0x........: main (timing_safe.c:41)
+ Address 0x........ is 0 bytes inside a block of size 12 free'd
+ at 0x........: free (vg_replace_malloc.c:...)
+ by 0x........: main (timing_safe.c:38)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ ...
+ by 0x........: main (timing_safe.c:33)
+
--- /dev/null
+prog: timing_safe
+vgopts: -q
+
+++ /dev/null
-Conditional jump or move depends on uninitialised value(s)
- at 0x........: timingsafe_bcmp (vg_replace_strmem.c:1228)
- by 0x........: main (timingsafe.c:30)
-
-Conditional jump or move depends on uninitialised value(s)
- at 0x........: timingsafe_bcmp (vg_replace_strmem.c:0)
- by 0x........: main (timingsafe.c:30)
-
-Conditional jump or move depends on uninitialised value(s)
- at 0x........: timingsafe_memcmp (vg_replace_strmem.c:1227)
- by 0x........: main (timingsafe.c:31)
-
-Conditional jump or move depends on uninitialised value(s)
- at 0x........: timingsafe_memcmp (vg_replace_strmem.c:0)
- by 0x........: main (timingsafe.c:31)
-
-Invalid read of size 1
- at 0x........: timingsafe_bcmp (vg_replace_strmem.c:1228)
- by 0x........: main (timingsafe.c:35)
- Address 0x........ is 0 bytes after a block of size 12 alloc'd
- at 0x........: malloc (vg_replace_malloc.c:...)
- ...
- by 0x........: main (timingsafe.c:33)
-
-Invalid read of size 1
- at 0x........: timingsafe_memcmp (vg_replace_strmem.c:1227)
- by 0x........: main (timingsafe.c:36)
- Address 0x........ is 0 bytes after a block of size 12 alloc'd
- at 0x........: malloc (vg_replace_malloc.c:...)
- ...
- by 0x........: main (timingsafe.c:33)
-
-Invalid read of size 1
- at 0x........: timingsafe_bcmp (vg_replace_strmem.c:1228)
- by 0x........: main (timingsafe.c:40)
- Address 0x........ is 0 bytes inside a block of size 12 free'd
- at 0x........: free (vg_replace_malloc.c:...)
- by 0x........: main (timingsafe.c:38)
- Block was alloc'd at
- at 0x........: malloc (vg_replace_malloc.c:...)
- ...
- by 0x........: main (timingsafe.c:33)
-
-Invalid read of size 1
- at 0x........: timingsafe_memcmp (vg_replace_strmem.c:1227)
- by 0x........: main (timingsafe.c:41)
- Address 0x........ is 0 bytes inside a block of size 12 free'd
- at 0x........: free (vg_replace_malloc.c:...)
- by 0x........: main (timingsafe.c:38)
- Block was alloc'd at
- at 0x........: malloc (vg_replace_malloc.c:...)
- ...
- by 0x........: main (timingsafe.c:33)
-
+++ /dev/null
-prog: timingsafe
-vgopts: -q
-
--- /dev/null
+/* Test strncpy functions.
+ Copyright (C) 1999-2023 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
+ <https://www.gnu.org/licenses/>. */
+
+/* This code is copied from GNU libc 2.38 string/test-strncpy.c
+ * Necessary bits have been copied from other headers in GNU libc.
+ * The code has been de-MACROed a bit and made specific for
+ * wcsncpy. And re-indented. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <wchar.h>
+#include <unistd.h>
+
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+
+size_t page_size;
+unsigned char buf1[10240];
+unsigned char buf2[10240];
+
+typedef wchar_t *(*impl_t)(wchar_t *, const wchar_t *, size_t);
+
+static void do_one_test(impl_t impl, wchar_t *dst, const wchar_t *src, size_t len, size_t n)
+{
+ if (impl(dst, src, n) != dst)
+ {
+ fprintf(stderr, "Wrong result in function wscncpy %p %p", impl(dst, src, n), dst);
+ return;
+ }
+
+ if (memcmp(dst, src, (len > n ? n : len) * sizeof(wchar_t)) != 0)
+ {
+ fprintf(stderr, "Wrong result in function wcsncpy");
+ return;
+ }
+
+ if (n > len)
+ {
+ size_t i;
+
+ for (i = len; i < n; ++i)
+ {
+ if (dst[i] != '\0')
+ {
+ fprintf(stderr, "Wrong result in function wcsncpy");
+ return;
+ }
+ }
+ }
+}
+
+static void do_test(size_t align1, size_t align2, size_t len, size_t n, int max_char)
+{
+ size_t i;
+ wchar_t *s1, *s2;
+
+ /* For wcsncpy: align1 and align2 here mean alignment not in bytes,
+ but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)). */
+ align1 &= 7;
+ if ((align1 + len) * sizeof(wchar_t) >= page_size)
+ return;
+
+ align2 &= 7;
+ if ((align2 + len) * sizeof(wchar_t) >= page_size)
+ return;
+
+ s1 = (wchar_t *)(buf1) + align1;
+ s2 = (wchar_t *)(buf2) + align2;
+
+ for (i = 0; i < len; ++i)
+ s1[i] = 32 + 23 * i % (max_char - 32);
+ s1[len] = 0;
+ for (i = len + 1; (i + align1) * sizeof(wchar_t) < page_size && i < len + 64; ++i)
+ s1[i] = 32 + 32 * i % (max_char - 32);
+
+ do_one_test(wcsncpy, s2, s1, len, n);
+}
+
+int main(void)
+{
+ wchar_t *bar = calloc(121, sizeof(wchar_t));
+ wmemset(bar, 1, 120);
+
+ wchar_t *foo = calloc(256, sizeof(wchar_t));
+ wcsncpy(foo, bar, 255);
+
+ page_size = sysconf (_SC_PAGE_SIZE);
+
+ size_t i;
+ for (i = 1; i < 8; ++i)
+ {
+ do_test(i, i, 16, 16, SMALL_CHAR);
+ do_test(i, i, 16, 16, BIG_CHAR);
+ do_test(i, 2 * i, 16, 16, SMALL_CHAR);
+ do_test(2 * i, i, 16, 16, BIG_CHAR);
+ do_test(8 - i, 2 * i, 1 << i, 2 << i, SMALL_CHAR);
+ do_test(2 * i, 8 - i, 2 << i, 1 << i, SMALL_CHAR);
+ do_test(8 - i, 2 * i, 1 << i, 2 << i, BIG_CHAR);
+ do_test(2 * i, 8 - i, 2 << i, 1 << i, BIG_CHAR);
+ }
+
+ for (i = 1; i < 8; ++i)
+ {
+ do_test(0, 0, 4 << i, 8 << i, SMALL_CHAR);
+ do_test(0, 0, 16 << i, 8 << i, SMALL_CHAR);
+ do_test(8 - i, 2 * i, 4 << i, 8 << i, SMALL_CHAR);
+ do_test(8 - i, 2 * i, 16 << i, 8 << i, SMALL_CHAR);
+ }
+}
--- /dev/null
+prereq: test -e ./wcsncpy
+prog: wcsncpy
+vgopts: -q
20450 WSTRNCMP
20460 MEMMEM
20470 WMEMCMP
+ 20480 WCSNCPY
*/
#if defined(VGO_solaris)
WMEMCHR(VG_Z_LIBC_SONAME, wmemchr)
#endif
+/*---------------------- wmemcmp ----------------------*/
#define WMEMCMP(soname, fnname) \
int VG_REPLACE_FUNCTION_EZU(20470,soname,fnname) \
return 0; \
}
-#if defined(VGO_linux)
+#if defined(VGO_linux) || defined(VGO_freebsd)
WMEMCMP(VG_Z_LIBC_SONAME, wmemcmp)
#endif
+/*---------------------- wcsncpy ----------------------*/
+
+ // This is a wchar_t equivalent to strncpy. We don't
+ // have wchar_t available here, but in the GNU C Library
+ // wchar_t is always 32 bits wide.
+
+#define WCSNCPY(soname, fnname) \
+ Int* VG_REPLACE_FUNCTION_EZU(20480,soname,fnname) \
+ ( Int* dst, const Int* src, SizeT n ); \
+ Int* VG_REPLACE_FUNCTION_EZU(20480,soname,fnname) \
+ ( Int* dst, const Int* src, SizeT n ) \
+ { \
+ const Int* src_orig = src; \
+ Int* dst_orig = dst; \
+ SizeT m = 0; \
+ \
+ while (m < n && *src) { \
+ m++; \
+ *dst++ = *src++; \
+ } \
+ \
+ /* This checks for overlap after copying, unavoidable without */ \
+ /* pre-counting length... should be ok */ \
+ /* +4 because sizeof(wchar_t) == 4 */ \
+ SizeT srclen = ((m < n) ? m+1 : n)*4; \
+ RECORD_COPY(srclen); \
+ if (is_overlap(dst_orig, \
+ src_orig, \
+ n*4, \
+ srclen)) \
+ RECORD_OVERLAP_ERROR("wcsncpy", dst_orig, src_orig, 0); \
+ \
+ while (m++ < n) { \
+ *dst++ = 0; \
+ } \
+ \
+ return dst_orig; \
+ }
+
+#if defined(VGO_linux) || defined(VGO_freebsd)
+ WCSNCPY(VG_Z_LIBC_SONAME, wcsncpy)
+#endif
/*------------------------------------------------------------*/
/*--- Improve definedness checking of process environment ---*/