Search⌘ K
AI Features

Identify Heap Corruption

Explore how to identify heap corruption in Linux process core dumps by analyzing segmentation faults caused by dynamic memory errors. Learn to use GDB to examine threads, stack traces, and memory instructions, enabling you to detect problematic instructions and memory misuse such as write-after-free conditions.

What is heap corruption?

In a process, heap memory is used for the dynamic allocation of memory. There are several reasons why this memory can get corrupted. For example, when processes do any of the following:

  • Overwrite the allocated bounds of some variable 

  • Use pointers that point to unallocated or freed-up memory

  • Use uninitialized pointers

Application source code

We have created a multi-threaded application that encounters heap corruption.

C
// Build:
// gcc main.c -pthread -static -o App4
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
void proc()
{
sleep(1);
char *p1 = (char *) malloc (256);
char *p2 = (char *) malloc (256);
char *p3 = (char *) malloc (256);
char *p4 = (char *) malloc (256);
char *p5 = (char *) malloc (256);
char *p6 = (char *) malloc (256);
char *p7 = (char *) malloc (256);
free(p6);
free(p4);
free(p2);
strcpy(p2, "Hello Crash2! Hello Crash2! Hello Crash2! Hello Crash2! Hello Crash2!");
strcpy(p4, "Hello Crash4! Hello Crash4! Hello Crash4! Hello Crash4! Hello Crash4! Hello Crash4!");
strcpy(p6, "Hello Crash6! Hello Crash6! Hello Crash6! Hello Crash6! Hello Crash6! Hello Crash6! Hello Crash6!");
p2 = (char *) malloc (256);
p4 = (char *) malloc (256);
p6 = (char *) malloc (256);
sleep(300);
free (p7);
free (p6);
free (p5);
free (p4);
free (p3);
free (p2);
free (p1);
sleep(-1);
}
#define THREAD_DECLARE(num,func) void bar_##num()\
{\
func;\
}\
\
void foo_##num()\
{\
bar_##num();\
}\
\
void * thread_##num (void *arg)\
{\
foo_##num();\
\
return 0;\
}
THREAD_DECLARE(one,sleep(-1))
THREAD_DECLARE(two,sleep(-1))
THREAD_DECLARE(three,proc())
THREAD_DECLARE(four,sleep(-1))
THREAD_DECLARE(five,sleep(-1))
#define THREAD_CREATE(num) {pthread_t threadID_##num; pthread_create (&threadID_##num, NULL, thread_##num, NULL);}
int main(int argc, const char * argv[])
{
THREAD_CREATE(one)
THREAD_CREATE(two)
THREAD_CREATE(three)
THREAD_CREATE(four)
THREAD_CREATE(five)
sleep(-1);
return 0;
}

Loading the core dump

The first step, as we already know, is to load the core dump file in GDB and see what actually caused our application to run into a segmentation fault. ...