From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4.1) Gecko/20031114 Description of problem: I have discovered a probable problem with sscanf() from glibc-2.3.4-2.13. Valgrind reports that sscanf() reads past the end of a dynamicly created structure. I have already submitted this report to the valgrind developers (in case it was a valgrind bug) and they believe that it is a sscanf bug. Please see ftp://ftp.crc.ca/crc/ravs/sscanf_bug.c for a complete explanation and demonstration of this bug. Here is a code example which generates the error when compiled and run under valgrind: // sscanf_bug.c #define FIELD_SZ 8 #define RES_SZ (512 - FIELD_SZ) // File header is 512 bytes struct FILEHEADER { char type[FIELD_SZ]; // this will be " TYP" char reserved[RES_SZ]; // this will be all spaces }; #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { struct FILEHEADER *header; char type[FIELD_SZ+1]; int i=0; char *typedata = " TYP"; // create header if ((header = (struct FILEHEADER *)malloc(sizeof(struct FILEHEADER))) == NULL) { fprintf(stderr,"can't allocate header"); exit(1); } // initialize the header with data strncpy(header->type,typedata,FIELD_SZ); // don't copy the \0 for(i = 0; i < RES_SZ; i++) { header->reserved[i]=' '; // reserved is all spaces (valgrind ERROR) //header->reserved[i]='\0'; // reserved is all nulls (** NO valgrind ERROR **) } //////////////////////////////////////////////////// // now sscan the type into a static char array. // the %8s should skip the initial 5 spaces and stop after 8 chars are read sscanf (header->type,"%8s",type); // valgrind error is here //printf("\n%s\n",type); // should print out: \nTYP\n free(header); exit(1); } Version-Release number of selected component (if applicable): glibc-2.3.4-2.13 How reproducible: Always Steps to Reproduce: 1.Compile the above code with: gcc -O0 -g -o sscanf_bug sscanf_bug.c 2.Run under valgrind with: valgrind --tool=memcheck ./sscanf_bug 3.Note the overrun error reported by valgrind Actual Results: The following is valgrind output: ==30482== Memcheck, a memory error detector. ==30482== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al. ==30482== Using LibVEX rev 1471, a library for dynamic binary translation. ==30482== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP. ==30482== Using valgrind-3.1.0, a dynamic binary instrumentation framework. ==30482== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al. ==30482== For more details, rerun with: -v ==30482== ==30482== Invalid read of size 1 ==30482== at 0x40068EC: rawmemchr (mac_replace_strmem.c:519) ==30482== by 0xAB686F: _IO_str_init_static_internal (in /lib/tls/libc-2.3.2.so) ==30482== by 0xAAA330: vsscanf (in /lib/tls/libc-2.3.2.so) ==30482== by 0xAA548C: sscanf (in /lib/tls/libc-2.3.2.so) ==30482== by 0x8048567: main (tst.c:52) ==30482== Address 0x401C228 is 0 bytes after a block of size 512 alloc'd ==30482== at 0x4004639: malloc (vg_replace_malloc.c:149) ==30482== by 0x80484EE: main (tst.c:35) ==30482== ==30482== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 14 from 1) ==30482== malloc/free: in use at exit: 0 bytes in 0 blocks. ==30482== malloc/free: 1 allocs, 1 frees, 512 bytes allocated. ==30482== For counts of detected errors, rerun with: -v ==30482== No malloc'd blocks -- no leaks are possible. Expected Results: Valgrind should have reported no errors. Additional info: I have also tried this under Fedora core 1 (glibc-2.3.2) with the same result. Valgrind 2.2.0 and 3.1.0 both report the same error. I have not tried glibc 2.3.6 which is the current release from GNU.
That testcase is invalid. See ISO C99 7.19.6.7. The first argument to sscanf is string, rather than a char array. Now, 7.1.1 says that a string is a contiguous sequence of characters terminated by and including the first null character. In your testcase you don't pass a string pointer as the first sscanf argument, but a pointer to character array, not terminated by null.