From fd7a6b53635da65baf3942bcc622f92a06a90a58 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Tue, 13 Nov 2007 20:52:29 +0000 Subject: [PATCH] Intercept __memcpy_chk, which appears in glibc-2.6.1. Also fix some backslash uglyness. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7155 --- memcheck/mc_replace_strmem.c | 80 ++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 18 deletions(-) diff --git a/memcheck/mc_replace_strmem.c b/memcheck/mc_replace_strmem.c index 4bc2798efd..0d4d7aa410 100644 --- a/memcheck/mc_replace_strmem.c +++ b/memcheck/mc_replace_strmem.c @@ -171,7 +171,7 @@ STRCHR(m_ld_linux_x86_64_so_2, index) while (*dst) dst++; \ while (*src) *dst++ = *src++; \ *dst = 0; \ - \ + \ /* This is a bit redundant, I think; any overlap and the strcat will */ \ /* go forever... or until a seg fault occurs. */ \ if (is_overlap(dst_orig, \ @@ -179,7 +179,7 @@ STRCHR(m_ld_linux_x86_64_so_2, index) (Addr)dst-(Addr)dst_orig+1, \ (Addr)src-(Addr)src_orig+1)) \ RECORD_OVERLAP_ERROR("strcat", dst_orig, src_orig, 0); \ - \ + \ return dst_orig; \ } @@ -195,11 +195,11 @@ STRCAT(m_libc_soname, strcat) const Char* src_orig = src; \ Char* dst_orig = dst; \ SizeT m = 0; \ - \ + \ while (*dst) dst++; \ while (m < n && *src) { m++; *dst++ = *src++; } /* concat <= n chars */ \ *dst = 0; /* always add null */ \ - \ + \ /* This checks for overlap after copying, unavoidable without */ \ /* pre-counting lengths... should be ok */ \ if (is_overlap(dst_orig, \ @@ -207,7 +207,7 @@ STRCAT(m_libc_soname, strcat) (Addr)dst-(Addr)dst_orig+1, \ (Addr)src-(Addr)src_orig+1)) \ RECORD_OVERLAP_ERROR("strncat", dst_orig, src_orig, n); \ - \ + \ return dst_orig; \ } @@ -250,10 +250,10 @@ STRLEN(m_ld_linux_x86_64_so_2, strlen) { \ const Char* src_orig = src; \ Char* dst_orig = dst; \ - \ + \ while (*src) *dst++ = *src++; \ *dst = 0; \ - \ + \ /* This checks for overlap after copying, unavoidable without */ \ /* pre-counting length... should be ok */ \ if (is_overlap(dst_orig, \ @@ -261,7 +261,7 @@ STRLEN(m_ld_linux_x86_64_so_2, strlen) (Addr)dst-(Addr)dst_orig+1, \ (Addr)src-(Addr)src_orig+1)) \ RECORD_OVERLAP_ERROR("strcpy", dst_orig, src_orig, 0); \ - \ + \ return dst_orig; \ } @@ -277,7 +277,7 @@ STRCPY(m_libc_soname, strcpy) const Char* src_orig = src; \ Char* dst_orig = dst; \ SizeT m = 0; \ - \ + \ while (m < n && *src) { m++; *dst++ = *src++; } \ /* Check for overlap after copying; all n bytes of dst are relevant, */ \ /* but only m+1 bytes of src if terminator was found */ \ @@ -303,10 +303,10 @@ STRNCPY(m_libc_soname, strncpy) if (*s1 == 0 && *s2 == 0) return 0; \ if (*s1 == 0) return -1; \ if (*s2 == 0) return 1; \ - \ + \ if (*(unsigned char*)s1 < *(unsigned char*)s2) return -1; \ if (*(unsigned char*)s1 > *(unsigned char*)s2) return 1; \ - \ + \ s1++; s2++; n++; \ } \ } @@ -362,13 +362,13 @@ MEMCHR(m_libc_soname, memchr) { \ register char *d; \ register char *s; \ - \ + \ if (len == 0) \ return dst; \ - \ + \ if (is_overlap(dst, src, len, len)) \ RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \ - \ + \ if ( dst > src ) { \ d = (char *)dst + len - 1; \ s = (char *)src + len - 1; \ @@ -423,7 +423,7 @@ MEMCPY(NONE, _intel_fast_memcpy) unsigned char b0; \ unsigned char* s1 = (unsigned char*)s1V; \ unsigned char* s2 = (unsigned char*)s2V; \ - \ + \ while (n != 0) { \ a0 = s1[0]; \ b0 = s2[0]; \ @@ -450,10 +450,10 @@ MEMCMP(m_ld_so_1, bcmp) { \ const Char* src_orig = src; \ Char* dst_orig = dst; \ - \ + \ while (*src) *dst++ = *src++; \ *dst = 0; \ - \ + \ /* This checks for overlap after copying, unavoidable without */ \ /* pre-counting length... should be ok */ \ if (is_overlap(dst_orig, \ @@ -461,7 +461,7 @@ MEMCMP(m_ld_so_1, bcmp) (Addr)dst-(Addr)dst_orig+1, \ (Addr)src-(Addr)src_orig+1)) \ RECORD_OVERLAP_ERROR("stpcpy", dst_orig, src_orig, 0); \ - \ + \ return dst; \ } @@ -677,6 +677,50 @@ GLIBC25_MEMPCPY(m_libc_soname, mempcpy) GLIBC25_MEMPCPY(m_ld_so_1, mempcpy) /* ld.so.1 */ +#define GLIBC26___MEMCPY_CHK(soname, fnname) \ + void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ + (void* dst, const void* src, SizeT len, SizeT dstlen ); \ + void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \ + (void* dst, const void* src, SizeT len, SizeT dstlen ) \ + { \ + extern void _exit(int status); \ + register char *d; \ + register char *s; \ + \ + if (dstlen < len) goto badness; \ + \ + if (len == 0) \ + return dst; \ + \ + if (is_overlap(dst, src, len, len)) \ + RECORD_OVERLAP_ERROR("memcpy_chk", dst, src, len); \ + \ + if ( dst > src ) { \ + d = (char *)dst + len - 1; \ + s = (char *)src + len - 1; \ + while ( len-- ) { \ + *d-- = *s--; \ + } \ + } else if ( dst < src ) { \ + d = (char *)dst; \ + s = (char *)src; \ + while ( len-- ) { \ + *d++ = *s++; \ + } \ + } \ + return dst; \ + badness: \ + VALGRIND_PRINTF_BACKTRACE( \ + "*** memcpy_chk: buffer overflow detected ***: " \ + "program terminated"); \ + _exit(127); \ + /*NOTREACHED*/ \ + return NULL; \ + } + +GLIBC26___MEMCPY_CHK(m_libc_soname, __memcpy_chk) + + /*------------------------------------------------------------*/ /*--- Improve definedness checking of process environment ---*/ /*------------------------------------------------------------*/ -- 2.47.2