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.

  • No labels