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. String is not Alleged string does not begin within legal range Structure reference out of rangeCode Description Enabled Reported Platform READ_OVERFLOW Runtime Windows/Unix (normal) Reading overflow's memory Runtime Windows/Unix (nonull) NULL
-terminated within rangeRuntime Windows/Unix (string) Runtime Windows/Unix (struct) Runtime Windows/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> ---- Associated Common Weakness Enumerations ---- CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer CWE-120: Buffer copy without checking size of input CWE-788: Access of memory location after end of buffer CWE-125: Out-of-bounds read CWE-126: Buffer over-read CWE-170: Improper NULL termination 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 5-11: CWEs associated with this problem.
- Line 13: Schematic showing the relative layout of the actual memory block (
b
) and region being read (r
) (see Overflow Diagrams). - Line 17: 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 19: 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 ---- Associated Common Weakness Enumerations ---- CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer CWE-120: Buffer copy without checking size of input CWE-788: Access of memory location after end of buffer CWE-125: Out-of-bounds read CWE-126: Buffer over-read CWE-170: Improper NULL termination 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 5-11: CWEs associated with this problem.
- Line 13: Pointer being used as a string.
- Line 14: Block from which the read is taking place, including its size and the location of its declaration.
- Line 16: 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 ---- Associated Common Weakness Enumerations ---- CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer CWE-120: Buffer copy without checking size of input CWE-788: Access of memory location after end of buffer CWE-125: Out-of-bounds read CWE-126: Buffer over-read CWE-170: Improper NULL termination 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 5-11: CWEs associated with this problem.
- Line 13: Schematic showing the relative layout of the actual memory block (
b
) and region being read (r
) (see Overflow Diagrams). - Line 16: 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 21: 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 ---- Associated Common Weakness Enumerations ---- CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer CWE-120: Buffer copy without checking size of input CWE-788: Access of memory location after end of buffer CWE-125: Out-of-bounds read CWE-126: Buffer over-read CWE-170: Improper NULL termination 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 5-11: CWEs associated with this problem.
- Line 13: Schematic showing the relative layout of the actual memory block (
b
) and region being read (r
) (see Overflow Diagrams). - Line 17: 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 22: 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);
References
The table below shows Common Weakness Enumerations associated with this error.