Take the following example code: // Uses various wchar_t * functions that have hand written SSE assembly // implementations in glibc. wcslen, wcscpy, wcscmp, wcsrchr, wcschr. #include <stdio.h> #include <stdlib.h> #include <wchar.h> int main(int argc, char **argv) { wchar_t a[] = L"The spazzy orange tiger jumped over the tawny jaguar."; wchar_t *b, *c; wchar_t *d, *e; size_t l = wcslen (a); fprintf (stderr, "wcslen: %zd\n", l); // wcslen: 53 b = (wchar_t *) malloc((l + 1) * sizeof (wchar_t)); c = wcscpy (b, a); fprintf (stderr, "wcscmp equal: %d\n", wcscmp (a, b)); // wcscmp equal: 0 d = wcsrchr (a, L'd'); e = wcschr (a, L'd'); fprintf (stderr, "wcsrchr == wcschr: %d\n", d == e); // wcsrchr == wcschr: 1 free (c); // b == c return 0; } On Fedora 17, x86_64 this triggers: wcslen: 53 ==9250== Conditional jump or move depends on uninitialised value(s) ==9250== at 0x4F88914: __wcscpy_ssse3 (wcscpy-ssse3.S:156) ==9250== by 0x4007AB: main (wcs.c:18) ==9250== ==9250== Conditional jump or move depends on uninitialised value(s) ==9250== at 0x4F8897E: __wcscpy_ssse3 (wcscpy-ssse3.S:191) ==9250== by 0x4007AB: main (wcs.c:18) ==9250== ==9250== Conditional jump or move depends on uninitialised value(s) ==9250== at 0x4F88D68: __wcscpy_ssse3 (wcscpy-ssse3.S:499) ==9250== by 0x4007AB: main (wcs.c:18) ==9250== ==9250== Conditional jump or move depends on uninitialised value(s) ==9250== at 0x4F88D6C: __wcscpy_ssse3 (wcscpy-ssse3.S:501) ==9250== by 0x4007AB: main (wcs.c:18) ==9250== ==9250== Invalid read of size 8 ==9250== at 0x4ECD799: wcscmp (wcscmp.S:435) ==9250== by 0x4007C5: main (wcs.c:20) ==9250== Address 0x51e6118 is 0 bytes after a block of size 216 alloc'd ==9250== at 0x4C286FC: malloc (vg_replace_malloc.c:270) ==9250== by 0x400791: main (wcs.c:17) ==9250== ==9250== Conditional jump or move depends on uninitialised value(s) ==9250== at 0x4ECD7AC: wcscmp (wcscmp.S:439) ==9250== by 0x4007C5: main (wcs.c:20) ==9250== ==9250== Conditional jump or move depends on uninitialised value(s) ==9250== at 0x4ECDD74: wcscmp (wcscmp.S:834) ==9250== by 0x4007C5: main (wcs.c:20) ==9250== ==9250== Conditional jump or move depends on uninitialised value(s) ==9250== at 0x4ECDD79: wcscmp (wcscmp.S:836) ==9250== by 0x4007C5: main (wcs.c:20) ==9250== wcscmp equal: 0 ==9250== Conditional jump or move depends on uninitialised value(s) ==9250== at 0x4ECE678: wcsrchr (wcsrchr.S:112) ==9250== by 0x4007F4: main (wcs.c:22) ==9250== ==9250== Conditional jump or move depends on uninitialised value(s) ==9250== at 0x4ECE6C3: wcsrchr (wcsrchr.S:135) ==9250== by 0x4007F4: main (wcs.c:22) ==9250== wcsrchr == wcschr: 1 And on Fedora 17, i686: wcslen: 53 ==9242== Conditional jump or move depends on uninitialised value(s) ==9242== at 0x41B3F34: __wcscpy_ssse3 (in /usr/lib/libc-2.15.so) ==9242== by 0x4076634: (below main) (in /usr/lib/libc-2.15.so) ==9242== ==9242== Conditional jump or move depends on uninitialised value(s) ==9242== at 0x41B3E8B: __wcscpy_ssse3 (in /usr/lib/libc-2.15.so) ==9242== by 0x4076634: (below main) (in /usr/lib/libc-2.15.so) ==9242== ==9242== Conditional jump or move depends on uninitialised value(s) ==9242== at 0x41B3F77: __wcscpy_ssse3 (in /usr/lib/libc-2.15.so) ==9242== by 0x4076634: (below main) (in /usr/lib/libc-2.15.so) ==9242== ==9242== Conditional jump or move depends on uninitialised value(s) ==9242== at 0x41B3F93: __wcscpy_ssse3 (in /usr/lib/libc-2.15.so) ==9242== by 0x4076634: (below main) (in /usr/lib/libc-2.15.so) ==9242== wcscmp equal: 0 ==9242== Conditional jump or move depends on uninitialised value(s) ==9242== at 0x41B3804: __wcsrchr_sse2 (in /usr/lib/libc-2.15.so) ==9242== by 0x4076634: (below main) (in /usr/lib/libc-2.15.so) ==9242== ==9242== Conditional jump or move depends on uninitialised value(s) ==9242== at 0x41B3842: __wcsrchr_sse2 (in /usr/lib/libc-2.15.so) ==9242== by 0x4076634: (below main) (in /usr/lib/libc-2.15.so) ==9242== wcsrchr == wcschr: 1 This is an extended bug report from Fedora: https://bugzilla.redhat.com/show_bug.cgi?id=755242
Created attachment 74332 [details] Patch that implements overrides in mc_replace_strmem.c plus example code as test case
A similar problem happens with memcpy (a ka bcopy). If I compile and run the program below and run it under valgrind, I got the following error shown below. It seems to access outside the allocated area (by malloc()). Now, in the real world example, I think I saw a case where the memory AFTER allocated area is accessed. I am not sure if this is the problem of gnu libc itself or the emulation of CPU hardware done in valgrind. *IF* bcopy under linux (GNU libc that is) does access outside the properly allocated (or mapped) area, this may indeed cause a problem under certain circumstances. (If the copied area is near the end of area obtained by brk(), the access beyond that would cause segmentation error.) I wonder if this is a real bug, but something that is an arti-fact caused by valgrind. TIA --- begin quote --- #include <stdio.h> #include <stdlib.h> #include <strings.h> main() { #define SIZE (32 * 1024) char *sp; char *dp; int i; int j; int k; for (j = 246; j < 279; j++) { for (i = 0; i < 33; i ++ ) { for(k = 0; k < 24; k++) { printf("i, j, k = %d, %d, %d\n", i, j, k); fflush(stdout); sp = malloc(j + 64 + 8); dp = malloc(j + 64 + 8); bzero(&sp[i], j); bcopy(&sp[i], &dp[k], j); free(sp); free(dp); } } } } --- end quote ==6952== Memcheck, a memory error detector ==6952== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. ==6952== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==6952== Command: ./a.out ==6952== i, j, k = 0, 246, 0 i, j, k = 0, 246, 1 ==6952== Invalid read of size 8 ==6952== at 0x4166029: __bcopy_ssse3 (memcpy-ssse3.S:1026) ==6952== by 0x4062E45: (below main) (libc-start.c:228) ==6952== Address 0x41ab300 is 8 bytes before a block of size 318 alloc'd ==6952== at 0x40271C4: malloc (vg_replace_malloc.c:270) ==6952== by 0x80485AC: main (test-copy.c:22) ==6952== i, j, k = 0, 246, 2 ==6952== Invalid read of size 8 ==6952== at 0x4165F99: __bcopy_ssse3 (memcpy-ssse3.S:981) ==6952== by 0x4062E45: (below main) (libc-start.c:228) ==6952== Address 0x41ab5e0 is 8 bytes before a block of size 318 alloc'd ==6952== at 0x40271C4: malloc (vg_replace_malloc.c:270) ==6952== by 0x80485AC: main (test-copy.c:22) ==6952== i, j, k = 0, 246, 3 ==6952== Invalid read of size 8 ==6952== at 0x4165F09: __bcopy_ssse3 (memcpy-ssse3.S:936) ==6952== by 0x4062E45: (below main) (libc-start.c:228) ==6952== Address 0x41ab8c0 is 8 bytes before a block of size 318 alloc'd ==6952== at 0x40271C4: malloc (vg_replace_malloc.c:270) ==6952== by 0x80485AC: main (test-copy.c:22) ==6952== i, j, k = 0, 246, 4 ==6952== Invalid read of size 8 ==6952== at 0x4165E79: __bcopy_ssse3 (memcpy-ssse3.S:891) ==6952== by 0x4062E45: (below main) (libc-start.c:228) ==6952== Address 0x41abba0 is 8 bytes before a block of size 318 alloc'd ==6952== at 0x40271C4: malloc (vg_replace_malloc.c:270) ==6952== by 0x80485AC: main (test-copy.c:22) ==6952== i, j, k = 0, 246, 5 ==6952== Invalid read of size 8 ==6952== at 0x4165DE9: __bcopy_ssse3 (memcpy-ssse3.S:846) ==6952== by 0x4062E45: (below main) (libc-start.c:228) ==6952== Address 0x41abe80 is 8 bytes before a block of size 318 alloc'd ==6952== at 0x40271C4: malloc (vg_replace_malloc.c:270) ==6952== by 0x80485AC: main (test-copy.c:22) ==6952== i, j, k = 0, 246, 6 ==6952== Invalid read of size 8 ==6952== at 0x4165D59: __bcopy_ssse3 (memcpy-ssse3.S:801) ==6952== by 0x4062E45: (below main) (libc-start.c:228) ==6952== Address 0x41ac160 is 8 bytes before a block of size 318 alloc'd ==6952== at 0x40271C4: malloc (vg_replace_malloc.c:270) ==6952== by 0x80485AC: main (test-copy.c:22) ==6952== i, j, k = 0, 246, 7 ==6952== Invalid read of size 8 ==6952== at 0x4165CC9: __bcopy_ssse3 (memcpy-ssse3.S:756) ==6952== by 0x4062E45: (below main) (libc-start.c:228) ==6952== Address 0x41ac440 is 8 bytes before a block of size 318 alloc'd ==6952== at 0x40271C4: malloc (vg_replace_malloc.c:270) ==6952== by 0x80485AC: main (test-copy.c:22) ==6952== i, j, k = 0, 246, 8 ... i, j, k = 32, 278, 23 ==6952== ==6952== HEAP SUMMARY: ==6952== in use at exit: 0 bytes in 0 blocks ==6952== total heap usage: 52,272 allocs, 52,272 frees, 17,458,848 bytes allocated ==6952== ==6952== All heap blocks were freed -- no leaks are possible ==6952== ==6952== For counts of detected and suppressed errors, rerun with: -v ==6952== ERROR SUMMARY: 1176 errors from 7 contexts (suppressed: 11 from 6)
(In reply to comment #1) > Patch that implements overrides in mc_replace_strmem.c plus example code as > test case Committed, r13162. Thanks.
(In reply to comment #2) > A similar problem happens with memcpy (a ka bcopy). I can't reproduce this on Ubuntu 10.04.4 LTS (x86_64). If you can still reproduce it, please open a new bug report add enough details so we can reproduce the problem. (distro, version, gcc version, glibc version)
(In reply to comment #4) > (In reply to comment #2) > > A similar problem happens with memcpy (a ka bcopy). > > I can't reproduce this on Ubuntu 10.04.4 LTS (x86_64). If you can > still reproduce it, please open a new bug report add enough details > so we can reproduce the problem. (distro, version, gcc version, > glibc version) I am still seeing this on my PC. So I filed a new bug report, Bug 311407 - ssse3 bcopy (actually converted memcpy) causes invalid read of size 8 under Debian GNU/Linux 32 bits TIA
*** Bug 326955 has been marked as a duplicate of this bug. ***