C++ Buffer Overflows: Causes, Safe APIs, and Security Impact

C++ Buffer Overflows: Causes, Safe APIs, and Security Impact

이 글의 핵심

Practical guide to buffer overflows: causes, fixes, and detection tools.

What is a buffer overflow?

Writing past the end of a fixed buffer—stack, heap, or global.

char buffer[10];
strcpy(buffer, "This is too long");  // overflow

Common causes

char buf[10];
strcpy(buf, "Long string");
gets(buf);  // never use

int arr[10];
arr[15] = 42;

char* ptr = buffer;
ptr[20] = 'x';

char src[20] = "Hello";
char dst[5];
memcpy(dst, src, 20);

Security impact

void vulnerable(const char* input) {
    char buffer[64];
    strcpy(buffer, input);
}

void heapOverflow() {
    char* buffer = new char[64];
    strcpy(buffer, longString);
    delete[] buffer;
}

Examples

Example 1: String APIs

#include <cstring>
#include <string>

void unsafeCopy(const char* src) {
    char buffer[10];
    strcpy(buffer, src);
}

void safeCopy(const char* src) {
    char buffer[10];
    strncpy(buffer, src, sizeof(buffer) - 1);
    buffer[sizeof(buffer) - 1] = '\0';
}

void useString(const char* src) {
    std::string str = src;
}

Example 2: Array access

#include <vector>
#include <stdexcept>

void unsafeAccess(int index) {
    int arr[10];
    arr[index] = 42;
}

void safeAccess(int index) {
    int arr[10];
    if (index >= 0 && index < 10) {
        arr[index] = 42;
    }
}

void vectorAccess(int index) {
    std::vector<int> vec(10);
    try {
        vec.at(index) = 42;
    } catch (const std::out_of_range& e) {
        std::cerr << "Out of range: " << e.what() << std::endl;
    }
}

Example 3: User input

#include <iostream>
#include <string>

void safeInput() {
    char buffer[64];
    if (fgets(buffer, sizeof(buffer), stdin)) {
        buffer[strcspn(buffer, "\n")] = '\0';
    }
}

void cppInput() {
    std::string input;
    std::getline(std::cin, input);
}

Example 4: Memory copy

#include <cstring>
#include <algorithm>

void safeCopy(const char* src, size_t srcLen) {
    char dst[64];
    size_t copySize = std::min(srcLen, sizeof(dst) - 1);
    memcpy(dst, src, copySize);
    dst[copySize] = '\0';
}

Common pitfalls

Pitfall 1: sprintf vs snprintf

void safeFormat(int value) {
    char buffer[10];
    snprintf(buffer, sizeof(buffer), "Value: %d", value);
}

Pitfall 2: Concatenation

void cppConcat() {
    std::string str = "Hello";
    str += " World";
}

Pitfall 3: Uninitialized buffers

char buffer[64] = {0};
std::array<char, 64> buffer2{};

Pitfall 4: Off-by-one and null terminator

char buffer[6];
strncpy(buffer, "Hello", 5);
buffer[5] = '\0';

Mitigation

strncpy(dst, src, sizeof(dst) - 1);
snprintf(buffer, sizeof(buffer), format, args);
fgets(buffer, sizeof(buffer), stdin);

Detection tools

g++ -fsanitize=address -g program.cpp
valgrind --tool=memcheck ./program
clang-tidy program.cpp
cppcheck program.cpp

Secure patterns

void validateInput(const char* input, size_t maxLen) {
    if (strlen(input) > maxLen) {
        throw std::invalid_argument("input too long");
    }
}

template<typename T, size_t N>
class SafeArray {
    T data[N];
public:
    T& operator[](size_t index) {
        if (index >= N) {
            throw std::out_of_range("index out of bounds");
        }
        return data[index];
    }
};

class Buffer {
    std::unique_ptr<char[]> data;
    size_t size;
public:
    Buffer(size_t s) : data(std::make_unique<char[]>(s)), size(s) {}
    
    void write(const char* src, size_t len) {
        if (len > size) {
            throw std::length_error("buffer overflow");
        }
        std::memcpy(data.get(), src, len);
    }
};

FAQ

Q1: When do overflows happen?

A: Unsafe C APIs, bad indices, missing validation.

Q2: Security risk?

A: Code execution, privilege escalation, data corruption.

Q3: Prevention?

A: Sized APIs, containers, bounds checks.

Q4: Detection?

A: ASan, Valgrind, static analysis.

Q5: Safer functions?

A: snprintf, fgets, std::string, std::vector.

Q6: Resources?

A: Secure Coding in C and C++, OWASP, CWE-120.


See also

  • C++ use-after-free
  • C++ heap corruption
  • C++ dangling reference

Practical tips

Debugging

  • Warnings first
  • Small repro

Performance

  • Profile before optimizing

Code review

  • Conventions

Checklist

Before coding

  • Right approach?
  • Maintainable?
  • Performance?

While coding

  • Warnings?
  • Edge cases?
  • Errors?

At review

  • Clear?
  • Tests?
  • Docs?

Keywords

C++, buffer overflow, security, memory, safety, ASan.


  • C++ use-after-free
  • C++ cache optimization
  • C++ custom allocator
  • C++ dangling reference
  • C++ flyweight pattern