Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Buffer Overflow

Buffer Overflow or Buffer Overrun is a bug where the program writes data outside the allocated memory of a buffer. It can be Stack-based or Heap-based and result in risks to confidentiality, integrity or availability depending on whether this bug corrupt valid data, cause the program to crash or execute arbitrary code (CWE-121,CWE-122).

A simple example is the code below:

#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE 6

int main(void) {
    int my_array[ARRAY_SIZE] = {0};
    int modified = 0;
    int i = 0;

    for (i = 0; i <= ARRAY_SIZE; i++) { // `<=` should be `<`.
        my_array[i] = 2 * i;
    }

    printf("%d\n", modified); // Prints 12 (6 * 2).

    return EXIT_SUCCESS;
}

Detection and Debugging Tools

To detect these bugs, it is possible to use static code analysis tools such as Clang Static Analyzer, Cppcheck or Infer (for the C language) or fuzzers such as AFL++ (for the C language), although these tools do not detect all occurrences of the problem.

In the event of a failure, it is therefore also necessary to have debugging tools such as GDB or Valgrind (for the C language), that can identify the instruction causing the problem.

A more drastic solution to this bug is to use languages that perform index checking when the program tries to access the element at a certain index of a buffer, such as Kotlin, Java or Rust.

Exercise

The exercise program contains the implementation of some functions and, unfortunately, it doesn’t work. Your goal is:

  1. to find the bug using debugging tools;
  2. and to fix it.

The Case of Rust

In Rust, this bug is not possible because Rust uses a combination of static analysis and runtime index checking.

Here is an example of Rust code that shows this feature:

const ARRAY_SIZE: usize = 6;

fn main() {
    let mut my_array: [i32; ARRAY_SIZE] = [0; ARRAY_SIZE];
    let modified: i32 = 0;

    for i in 0..=ARRAY_SIZE { // Should be `0..ARRAY_SIZE`.
        my_array[i] = 2 * i as i32; // Panics here.
    }

    println!("{}", modified);
}

It is the equivalent of the C code showed in the intro.