Wrong memory access with strlen()

Bug #839001 reported by Removed by request
6
Affects Status Importance Assigned to Milestone
eglibc (Ubuntu)
Fix Released
Undecided
Unassigned

Bug Description

I'm using Ubuntu 11.10 dev with libc6 2.13-17ubuntu2 and Valgrind 1:3.6.1-0ubuntu2. strlen() is accessing in some cases the wrong memory. I have written example code that shows the problem. The code was compiled with "gcc -O3 -Wall -Wextra -o test -pedantic test.c" (the error appears on -O2 too but not on -O1). The application was executed with "valgrind ./test".

This is the code:

#include <stdlib.h>
#include <string.h>

int main()
{
 char *buffer;

 buffer = malloc(7);
 strcpy(buffer, "1234");
 buffer = realloc(buffer, strlen(buffer) + 1024);
 free(buffer);
 return 0;
}

And this is the output of a run:

==203489== Memcheck, a memory error detector
==203489== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==203489== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==203489== Command: ./test
==203489==
==203489== Invalid read of size 4
==203489== at 0x4004BB: main (in /home/sworddragon/data/test)
==203489== Address 0x51ce044 is 4 bytes inside a block of size 7 alloc'd
==203489== at 0x4C28F9F: malloc (vg_replace_malloc.c:236)
==203489== by 0x4004AD: main (in /home/sworddragon/data/test)
==203489==
==203489==
==203489== HEAP SUMMARY:
==203489== in use at exit: 0 bytes in 0 blocks
==203489== total heap usage: 2 allocs, 2 frees, 1,035 bytes allocated
==203489==
==203489== All heap blocks were freed -- no leaks are possible
==203489==
==203489== For counts of detected and suppressed errors, rerun with: -v
==203489== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)

Revision history for this message
Kees Cook (kees) wrote :

Gcc seems to be generating a 4-byte wide strlen scanner during -O3 which is tripping up valgrind. I'm not sure if this should be considered a gcc bug or a valgrind bug:

-O1:
  4005a2: b8 00 00 00 00 mov $0x0,%eax
  4005a7: 48 c7 c1 ff ff ff ff mov $0xffffffffffffffff,%rcx
  4005ae: f2 ae repnz scas %es:(%rdi),%al
  4005b0: 48 f7 d1 not %rcx

-O3:
  4004b8: 48 89 c6 mov %rax,%rsi
  4004bb: 8b 0e mov (%rsi),%ecx
  4004bd: 48 83 c6 04 add $0x4,%rsi
  4004c1: 8d 91 ff fe fe fe lea -0x1010101(%rcx),%edx
  4004c7: f7 d1 not %ecx
  4004c9: 21 ca and %ecx,%edx
  4004cb: 81 e2 80 80 80 80 and $0x80808080,%edx
  4004d1: 74 e8 je 4004bb <main+0x1b>
  4004d3: 89 d1 mov %edx,%ecx
  4004d5: 48 89 c7 mov %rax,%rdi
  4004d8: c1 e9 10 shr $0x10,%ecx
  4004db: f7 c2 80 80 00 00 test $0x8080,%edx
  4004e1: 0f 44 d1 cmove %ecx,%edx
  4004e4: 48 8d 4e 02 lea 0x2(%rsi),%rcx
  4004e8: 48 0f 44 f1 cmove %rcx,%rsi
  4004ec: 00 d2 add %dl,%dl
  4004ee: 48 83 de 03 sbb $0x3,%rsi
  4004f2: 48 29 c6 sub %rax,%rsi

Revision history for this message
Removed by request (removed3425744) wrote :

I can't reproduce this bug anymore with GCC 4.7 (but still with GCC 4.6). So it seems this was a GCC bug which is now fixed.

Changed in eglibc (Ubuntu):
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.