Rule
Prevent common segmentation fault patterns.
Null pointer dereferences, buffer overflows, and use-after-free errors cause crashes and security vulnerabilities.
Supported languages: C/C++Introduction
Segmentation faults remain the most common source of crashes and exploitable vulnerabilities in C/C++ applications. These memory access violations occur when code attempts to read or write memory it doesn't own, typically through null pointer dereferences, buffer overflows, dangling pointers, or accessing freed memory. A single segfault can bring down production servers, but worse, many segfault patterns are exploitable for arbitrary code execution.
Why it matters
Security implications: Buffer overflows and use-after-free vulnerabilities are the foundation of most memory corruption exploits. Attackers leverage these to overwrite return addresses, inject shellcode, or manipulate program control flow. The 2014 Heartbleed vulnerability was a buffer over-read. Modern exploits still target these patterns because they provide direct memory access to attackers.
System stability: Segmentation faults crash your application immediately with no graceful degradation. In production systems, this means dropped requests, interrupted transactions, and corrupted state. Unlike higher-level language exceptions that can be caught, segfaults terminate the process, requiring restart and recovery procedures.Attack surface expansion: Every unchecked pointer dereference, strcpy, memcpy, or array access without bounds checking is a potential entry point for exploitation. Attackers chain these vulnerabilities together, using one to corrupt memory in ways that enable exploiting another.
Code examples
❌ Non-compliant:
void process_user_data(const char* input) {
char buffer[64];
strcpy(buffer, input); // No bounds checking
char* token = strtok(buffer, ",");
while (token != NULL) {
process_token(token);
token = strtok(NULL, ",");
}
}
int* get_config_value(int key) {
int* value = (int*)malloc(sizeof(int));
*value = lookup_config(key);
return value; // Caller must free, but no documentation
}Why it's unsafe: The strcpy() call causes buffer overflow if input exceeds 63 bytes, allowing attackers to overwrite stack memory. The get_config_value() function leaks memory on every call and creates dangling pointer risk if callers free the memory while other code still references it.
✅ Compliant:
void process_user_data(const char* input) {
if (!input) return;
size_t input_len = strlen(input);
char* buffer = malloc(input_len + 1);
if (!buffer) return;
strncpy(buffer, input, input_len);
buffer[input_len] = '\0';
char* token = strtok(buffer, ",");
while (token != NULL) {
process_token(token);
token = strtok(NULL, ",");
}
free(buffer);
}
int get_config_value(int key, int* out_value) {
if (!out_value) return -1;
*out_value = lookup_config(key);
return 0; // Caller owns out_value memory
}Why it's safe: Null pointer checks prevent dereference crashes. Dynamic allocation eliminates fixed buffer size limits. Bounds-checked copying with strncpy() prevents overflow. Clear ownership semantics in get_config_value() where caller provides memory avoid allocation confusion and leaks.
Conclusion
Memory safety in C and C++ requires defensive programming at every pointer operation and memory allocation. Segmentation faults aren't inevitable, they're preventable through consistent null checks, bounds validation, and clear memory ownership patterns. Catching these patterns before production prevents both crashes and exploitable vulnerabilities.
.avif)
