From: Paul Floyd Date: Sun, 12 Nov 2023 17:07:52 +0000 (+0100) Subject: Bug 476780 - Extend strlcat and strlcpy wrappers to GNU libc X-Git-Tag: VALGRIND_3_23_0~277 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d154591f595cf052bdc0aa9820c44365a46c6864;p=thirdparty%2Fvalgrind.git Bug 476780 - Extend strlcat and strlcpy wrappers to GNU libc Will add Linux regtest soon --- diff --git a/.gitignore b/.gitignore index 8fc5bfd774..b48622c5b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1406,6 +1406,7 @@ /memcheck/tests/freebsd/stat /memcheck/tests/freebsd/statfs /memcheck/tests/freebsd/static_allocs +/memcheck/tests/freebsd/strlcat_strlcpy /memcheck/tests/freebsd/timerfd /memcheck/tests/freebsd/timing_safe /memcheck/tests/freebsd/utimens diff --git a/NEWS b/NEWS index 79482f2076..5578caf4df 100644 --- a/NEWS +++ b/NEWS @@ -29,6 +29,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 475498 Add reallocarray wrapper 476320 Build failure with GCC 476535 Difference in allocation size for massif/tests/overloaded-new between clang++/libc++ and g++/libstdc++ +476780 Extend strlcat and strlcpy wrappers to GNU libc 476787 Build of Valgrind 3.21.0 fails when SOLARIS_PT_SUNDWTRACE_THRP is defined To see details of a given bug, visit diff --git a/configure.ac b/configure.ac index 62d83371c1..5d491b9c3b 100755 --- a/configure.ac +++ b/configure.ac @@ -4923,7 +4923,7 @@ AC_CHECK_FUNCS([ \ pwritev2 \ rawmemchr \ readlinkat \ - reallocarray \ + reallocarray \ semtimedop \ setcontext \ signalfd \ @@ -4937,6 +4937,8 @@ AC_CHECK_FUNCS([ \ syscall \ utimensat \ mempcpy \ + strlcat \ + strlcpy \ stpncpy \ strchrnul \ memrchr \ @@ -4976,6 +4978,10 @@ AM_CONDITIONAL([HAVE_REALLOCARRAY], [test x$ac_cv_func_reallocarray = xyes]) AM_CONDITIONAL([HAVE_WCSNCPY], [test x$ac_cv_func_wcsncpy = xyes]) +AM_CONDITIONAL([HAVE_STRLCAT], + [test x$ac_cv_func_strlcat = xyes]) +AM_CONDITIONAL([HAVE_STRLCPY], + [test x$ac_cv_func_strlcpy = xyes]) if test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX \ -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX \ diff --git a/memcheck/tests/freebsd/Makefile.am b/memcheck/tests/freebsd/Makefile.am index 0e45aeab61..fb1149f98b 100644 --- a/memcheck/tests/freebsd/Makefile.am +++ b/memcheck/tests/freebsd/Makefile.am @@ -115,6 +115,8 @@ EXTRA_DIST = \ statfs.stderr.exp \ static_allocs.vgtest \ static_allocs.stderr.exp \ + strlcat_strlcpy.vgtest \ + strlcat_strlcpy.stderr.exp \ supponlyobj.vgtest \ supponlyobj.stderr.exp \ supponlyobj.supp \ @@ -148,6 +150,7 @@ check_PROGRAMS = \ stat \ statfs \ static_allocs \ + strlcat_strlcpy \ timing_safe \ utimens \ utimes diff --git a/memcheck/tests/freebsd/strlcat_strlcpy.c b/memcheck/tests/freebsd/strlcat_strlcpy.c new file mode 100644 index 0000000000..4d07b5ad2e --- /dev/null +++ b/memcheck/tests/freebsd/strlcat_strlcpy.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include + +int main(void) +{ + const size_t dstsize = 100U; + char *dst = malloc(dstsize); + // normal use + strlcpy(dst, "test1", dstsize); + assert(!strcmp(dst, "test1")); + strcat(dst, "test2"); + // overlap, source starts within dst string + strlcpy(dst+4, dst+9, dstsize-4); + sprintf(dst, "test1test2"); + // overlap, dst starts within src string + strlcpy(dst+9, dst+4, dstsize-9); + sprintf(dst, "test1"); + // overlap, dst points to nul terminator of src + strlcpy(dst+5, dst+4, dstsize-5); + sprintf(dst, "test1"); + // as above but incorrect length (1 too long) + // since src nul is overwritten this will + // keep reading from src until the length limit + // is reached + // since the length is wrong this will result + // in an invalid read and write 1 byte + // beyond the end of the buffer + strlcpy(dst+5, dst+4, dstsize-4); + + sprintf(dst, "test1"); + strlcat(dst, "test2", dstsize); + assert(!strcmp(dst, "test1test2")); + + strlcat(dst+5, dst+7, dstsize-5); + sprintf(dst, "test1test2"); + // we can't really control 'dst' since + // the destination id the end of the string + strlcat(dst+7, dst+5, dstsize-7); + + // again wrong dstsize + sprintf(dst, "test1"); + strlcpy(dst+3, dst+4, dstsize-2); + free(dst); +} + diff --git a/memcheck/tests/freebsd/strlcat_strlcpy.stderr.exp b/memcheck/tests/freebsd/strlcat_strlcpy.stderr.exp new file mode 100644 index 0000000000..0737f7b72b --- /dev/null +++ b/memcheck/tests/freebsd/strlcat_strlcpy.stderr.exp @@ -0,0 +1,42 @@ +Source and destination overlap in strlcpy(0x........, 0x........, 96) + at 0x........: strlcpy (vg_replace_strmem.c:...) + by 0x........: main (strlcat_strlcpy.c:15) + +Source and destination overlap in strlcpy(0x........, 0x........, 91) + at 0x........: strlcpy (vg_replace_strmem.c:...) + by 0x........: main (strlcat_strlcpy.c:18) + +Source and destination overlap in strlcpy(0x........, 0x........, 95) + at 0x........: strlcpy (vg_replace_strmem.c:...) + by 0x........: main (strlcat_strlcpy.c:21) + +Source and destination overlap in strlcpy(0x........, 0x........, 96) + at 0x........: strlcpy (vg_replace_strmem.c:...) + by 0x........: main (strlcat_strlcpy.c:30) + +Invalid write of size 1 + at 0x........: strlcpy (vg_replace_strmem.c:...) + by 0x........: main (strlcat_strlcpy.c:30) + Address 0x........ is 0 bytes after a block of size 100 alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (strlcat_strlcpy.c:9) + +Invalid read of size 1 + at 0x........: strlcpy (vg_replace_strmem.c:...) + by 0x........: main (strlcat_strlcpy.c:30) + Address 0x........ is 0 bytes after a block of size 100 alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (strlcat_strlcpy.c:9) + +Source and destination overlap in strlcat(0x........, 0x........, 95) + at 0x........: strlcat (vg_replace_strmem.c:...) + by 0x........: main (strlcat_strlcpy.c:36) + +Source and destination overlap in strlcat(0x........, 0x........, 93) + at 0x........: strlcat (vg_replace_strmem.c:...) + by 0x........: main (strlcat_strlcpy.c:40) + +Source and destination overlap in strlcpy(0x........, 0x........, 98) + at 0x........: strlcpy (vg_replace_strmem.c:...) + by 0x........: main (strlcat_strlcpy.c:44) + diff --git a/memcheck/tests/freebsd/strlcat_strlcpy.vgtest b/memcheck/tests/freebsd/strlcat_strlcpy.vgtest new file mode 100644 index 0000000000..d29afe087e --- /dev/null +++ b/memcheck/tests/freebsd/strlcat_strlcpy.vgtest @@ -0,0 +1,3 @@ +prog: strlcat_strlcpy +vgopts: -q + diff --git a/shared/vg_replace_strmem.c b/shared/vg_replace_strmem.c index 747b903fef..9a2eda6737 100644 --- a/shared/vg_replace_strmem.c +++ b/shared/vg_replace_strmem.c @@ -431,6 +431,7 @@ static inline void my_exit ( int x ) } #if defined(VGO_linux) + STRLCAT(VG_Z_LIBC_SONAME, strlcat) #elif defined(VGO_freebsd) STRLCAT(VG_Z_LD_ELF_SO_1, strlcat) @@ -660,11 +661,8 @@ static inline void my_exit ( int x ) #if defined(VGO_linux) -#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ - || defined(VGPV_mips32_linux_android) #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO STRLCPY(VG_Z_LIBC_SONAME, strlcpy); -#endif #elif defined(VGO_freebsd) #define STRLCPY_CHECK_FOR_DSTSIZE_ZERO