The following example program concatenates the arguments given on the command line and prints the resulting string.
/* * File: hello.c */ #include <string.h> main(argc, argv) int argc; char *argv[]; { int i; char str[16]; str[0] = '\0'; for(i=0; i<argc; i++) { strcat(str, argv[i]); if(i < (argc-1)) strcat(str, " "); } printf("You entered: %s\n", str); return (0); }
If you compile and run this program with your normal compiler, you would not likely notice any problems. For example:
$ cc -g hello.c -o hello $ ./hello You entered :./hello $ ./hello world You entered: ./hello world $ ./hello cruel world You entered: ./hello cruel world
If this were the extent of your test procedures, you would probably conclude that this program works correctly, despite the fact that it has a very serious memory corruption bug. If you compile with Insure++, the command hello cruel world
generates the errors shown below. This is because the string that is being concatenated becomes longer than the 16 characters allocated in the declaration at line 11.
[hello.c:15] **WRITE_OVERFLOW** >> strcat(str, argv[i]); Writing overflows memory: <argument 1> bbbbbbbbbbbbbbbbbbbbbbbbbb | 16 | 2 | wwwwwwwwwwwwwwwwwwwwwwwwwwwwww Writing (w) : 0xbfffeed0 thru 0xbfffeee1 (18 bytes) To block (b) : 0xbfffeed0 thru 0xbfffeedf (16 bytes) str, declared at hello.c, 11 Stack trace where the error occurred: strcat() (interface) main() hello.c, 15 **Memory corrupted. Program may crash!!** [hello.c:18] **READ_OVERFLOW** >> printf("You entered: %s\n", str); String is not null terminated within range: str Reading : 0xbfffeed0 From block: 0xbfffeed0 thru 0xbfffeedf (16 bytes) str, declared at hello.c, 11 Stack trace where the error occurred: main() hello.c, 18 You entered: hello cruel world
Insure++ finds all problems related to overwriting memory or reading past the legal bounds of an object, regardless of whether it is allocated statically (global variable), locally on the stack, dynamically (with malloc
or new
), or even as a shared memory block. Insure++ also detects situations where a pointer crosses from one block of memory into another and starts to overwrite memory there, even if the memory blocks are adjacent.