Monday, February 25, 2008

Memory CORRUPTION

From Wikipedia, the free encyclopedia

Memory corruption happens when the contents of a memory location are unintentionally modified due to programming errors. When the corrupted memory contents are used later in the computer program, it leads either to program crash or to strange and bizarre program behavior.

Modern programming languages like C and C++ have powerful features of explicit memory management and pointer arithmetic. These features are designed for developing efficient applications and system software. But when these features are used incorrectly, it may lead to memory corruption errors.

Memory corruption is one of the most intractable class of programming errors because of two reasons. First, the source of the memory corruption and its manifestation may be far apart making it hard to correlate the cause and the effect. Second, symptoms appear under unusual conditions, making it hard to consistently reproduce the error.

Memory corruption errors can be broadly classified into four categories:

1. Using un-initialized memory: Contents of un-initialized memory are considered
to be garbage values and using these values can lead to unpredictable program
behavior.
2. Using un-owned memory: It is common to use pointers for accessing and modifying
memory. If a pointer happens to be a null pointer, dangling pointer (pointing
to memory that has already been freed), or to a memory location outside of
current stack or heap bounds, it is referring to memory that is not currently
possessed by the program. And using such pointer is a serious programming
flaw. Writing to such memory can crash another program or even the operating
system.
3. Using beyond allocated memory (buffer overflow): If an array is used in a
loop, with incorrect terminating condition, memory beyond the array bounds may
be manipulated. Buffer overflow is one of the most common programming flaw
exploited by computer viruses causing serious computer security issues (e.g.
Return-to-libc attack, Stack-smashing protection) in widely used programs.
4. Faulty heap memory management: Memory leaks and freeing non-heap or unallocated
memory are the most frequent errors caused by faulty heap memory management.

Many memory debuggers such as Purify, Valgrind, Insure++ are available for detecting memory corruption errors.

Memory is said to be corrupted if we try one of the following :

* Free a dynamic variable that has already been freed

char *str = new char[100];
delete [] str;
delete [] str;

* Free a dynamic variable that has not been yet allocated

char *str;
delete str;

* Assign a certain value to a dynamic variable that was never allocated

char *str;
strcpy(str, "error");

The previous three examples will most probably cause the application to crash. However the next two "bugs" are harder to detect :

* Assign a certain value to a dynamic variable, after it has been freed (this may also affect other data stored in the heap)

char *str = new char[100];
delete [] str;
char *test = new char[100];
strcpy(str, "surprise !");
cout << test;
delete [] test;

* Access an element with an index out of range

char *str = new char[30];
str[40] = 'C';