What is segmentation fault (or segfault)?
Out-of-bounds array access
One of the most common memory access errors is an out-of-bounds (OOB) array access (also referred to as buffer overrun or buffer overflow). Almost all C programmers have at one point tried to access a non-existent element by using an invalid index. Here’s an example of an OOB array access:
*** stack smashing detected ***: unknown terminated
Null (or uninitialized) pointer dereference
A pointer typically contains the memory address of another object or value in memory –
it “points” to another location in memory. However, pointers that are uninitialized
(not explicitly assigned a value) can have an arbitrary value that might point to valid
or invalid memory. Similarly, a pointer that is explicitly initialized to null points to
invalid memory. Dereferencing a pointer with an invalid value will result in a segmentation
fault. Occasionally, there can be conditions where a null pointer deference can be abused to
bypass security mechanisms or exploited to execute arbitrary code. Below is an example of
using an uninitialized pointer. Since a
is never initialized,
scanf() attempts to read input into an invalid memory location
and the result is a segmentation fault.
Use-after-free
In C/C++, stack allocated memory can be used even if it is out of
out-of-scope, and heap allocated memory can be used after it has
been deallocated. Consequently, reading from freed (or out-of-scope)
memory might yield undefined values or sensitive data. Writing to
freed (or out-of-scope) memory might cause a segmentation fault
or corrupt data if the memory is recycled and reused. In certain
cases, writing malicious data to freed memory can result in
arbitrary code execution. More generally, using memory after it
has been freed results in unpredictable behavior that is often
hard to diagnose.
Below is an example of a function that returns a local stack
variable. Since h
is declared
inside the function hex()
, it goes
out of scope after return is called. Use of the returned value
can lead to unpredictable results.
Double free
A double free occurs when there is an attempt to deallocate memory after it has already been deallocated (calling free() twice on the same pointer). When free() is called on the same value, it can lead to corruption of memory management data structures (i.e. malloc’s internal data structures). Double frees often happen during error conditions where the code execution path isn’t properly anticipated. Similar to use-after-free bugs, corruption of memory management data structures can lead to arbitrary code execution. In the example below, free() is called twice on the variable y.
Constant data corruption
In C/C++, constant data is mapped to a read-only region of memory. Since constant data
is read-only, attempting to write data to this region of memory results in a
segmentation fault. In the example below,
name1
points to the constant string “Franz”.
However, the attempt to assign a value to the first character of name1 will
result in a segmentation fault