In this section:

Overview

This error is generated whenever a read operation would access a piece of memory beyond the valid range for a block.

CodeDescriptionEnabledReportedPlatform
READ_OVERFLOW
(error)RuntimeWindows/Unix
(normal)Reading overflow's memory(tick)RuntimeWindows/Unix
(nonull)

String is not NULL-terminated within range

(tick)RuntimeWindows/Unix
(string)

Alleged string does not begin within legal range

(tick)RuntimeWindows/Unix
(struct)

Structure reference out of range

(tick)RuntimeWindows/Unix


Problem 1

The following code attempts to copy a string into the array b. Although the array is large enough, the memcpy operation will fail because it attempts to read past the end of the string a.

/*
 * File: readovr1.c
 */
main()
{
	char *a = "TEST";
	char b[20];

	memcpy(b, a, sizeof(b));
	return (0);
}

Diagnosis at Runtime

[readovr1.c:9] **READ_OVERFLOW**
>>			 memcpy(b, a, sizeof(b));
	Reading overflows memory: <argument 2>
			bbbbb
			| 5 |     15   |
			rrrrrrrrrrrrrrrr
	Reading (r): 0x00012218 thru 0x0001222b (20 bytes)
From block(b): 0x00012218 thru 0x0001221c (5 bytes)
			a, declared at readovr1.c, 6
	Stack trace where the error occurred:
			memcpy() (interface)
			main() readovr1.c, 9
  • Line 2: Source line at which the problem was detected.
  • Line 3: Description of the problem and the expression that is in error.
  • Line 4: Schematic showing the relative layout of the actual memory block (b) and region being read (r) (see Overflow Diagrams).
  • Line 8: Range of memory being read and description of the block from which the read is taking place, including its size and the location of its declaration.
  • Line 10: Stack trace showing the function call sequence leading to the error.

Problem 2

A common case also arises when strings are not terminated properly. The following code copies a string using the strncpy routine, which leaves it non-terminated because the buffer is too short. When we attempt to print this message, an error results.

/*
 * File: readovr2.c
 */
main()
{
	char junk;
	char b[8];
	strncpy(b, "This is a test",
		sizeof(b));
	printf("%s\n", b);
	return (0);
}

Diagnosis at Runtime

[readovr2.c:10] **READ_OVERFLOW**
>>		 printf("%s\n", b);
String is not null terminated within range: b
Reading				 : 0xf7fffb50
From block:	 0xf7fffb50 thru 0xf7fffb57 (8 bytes)
					b, declared at readovr2.c, 7
Stack trace where the error occurred:
			main() readovr2.c, 10
  • Line 2: Source line at which the problem was detected.
  • Line 3: Description of the problem and the expression that is in error.
  • Line 4: Pointer being used as a string.
  • Line 5: Block from which the read is taking place, including its size and the location of its declaration.
  • Line 8: Stack trace showing the function call sequence leading to the error.

A slight variation on this misuse of strings occurs when the pointer, passed as a string, lies completely outside the range of its buffer. In this case, the diagnostics will appear as above except that the description line will contain the following message:

Alleged string does not begin within legal range

Problem 3

The following code shows a typical example of allocating a block of memory with one heap handle and then freeing it with another heap handle.

/*
 * File: readovr3.c
 */
#include <stdlib.h>

struct small {
	int x;
};

struct big {
	double y;
};


union two
{
	struct small a;
	struct big b;
};

int main()
{
	struct small *var1;
	union two *ptr;
	double d;

	var1 = (struct small *)malloc (sizeof(struct small));
	ptr = (union two *) var1;
	d = ptr->b.y;
	return (0);
}

Diagnosis at Runtime

[readovr3.c:28] **READ_OVERFLOW**
>>			 d = ptr->b.y;
Structure reference out of range: ptr
			bbbbb
			| 4 | 4 |
			rrrrrrrrr
Reading (r):	 0x0001fce0 thru 0x0001fce7 (8 bytes)
From block(b):	 0x0001fce0 thru 0x0001fce3 (4 bytes)
					block allocated at:
						malloc() (interface)
						main() readovr3.c, 26
	Stack trace where the error occurred:
			main() readovr3.c, 28
  • Line 2: Source line at which the problem was detected.
  • Line 3: Description of the problem and the expression that is in error.
  • Line 4: Schematic showing the relative layout of the actual memory block (b) and region being read (r) (see Overflow Diagrams).
  • Line 8: Range of memory being read and description of the block from which the read is taking place, including its size and the location of its declaration.
  • Line 12: Stack trace showing the function call sequence leading to the error.

Problem 4

The following code shows a C++ problem that can occur when using inheritance and casting pointers incorrectly.

/*
 * File: readover.cpp
 */
#include <stdlib.h>

class small
{
	public:
		int x;
};

class big : public small
{
	public:
		double y;
};

int main()
{
	small *var1;
	big *var2;
	double d;

	var1 = new small;
	var2 = (big *) var1;
	d = var2->y;
	return (0);
}

Diagnosis at Runtime

[readover.cpp:26] **READ_OVERFLOW**
>>			 d = var2->y;
Structure reference out of range: var2
			bbbbb
			| 4 | 4 |  8  |
					rrrrrrr
Reading (r): 	0x0001fce0 thru 0x0001fce7 (8 bytes)
From block(b): 	0x0001fce0 thru 0x0001fce3 (4 bytes)
						var1, allocated at:
					operator new()
						main() readover.cpp, 24
Stack trace where the error occurred:
			main() readover.cpp, 26
  • Line 2: Source line at which the problem was detected.
  • Line 3: Description of the problem and the expression that is in error.
  • Line 4: Schematic showing the relative layout of the actual memory block (b) and region being read (r) (see Overflow Diagrams).
  • Line 8: Range of memory being read and description of the block from which the read is taking place, including its size and the location of its declaration.
  • Line 13: Stack trace showing the function call sequence leading to the error.

Repair

These errors often occur when reading past the end of a string or using the sizeof operator incorrectly. In most cases, the indicated source line contains a simple error. The code for Problem 1 could, for example, be corrected by changing line 9 to the following:

memcpy(b, a, strlen(a)+1); 

  • No labels