Regola
Prevenire comune segmentazione errore .
Puntatore puntero , overflow ,
e errori di tipo "use-after-free" errori causano arresti anomali e vulnerabilità vulnerabilità di sicurezza.
Linguaggi supportati: C/C++Introduzione
Gli errori di segmentazione rimangono la causa più comune di arresti anomali e vulnerabilità sfruttabili nelle applicazioni C/C++. Queste violazioni dell'accesso alla memoria si verificano quando il codice tenta di leggere o scrivere in un'area di memoria che non gli appartiene, in genere a causa di dereferenziazioni di puntatori nulli, overflow del buffer, puntatori pendenti o accesso a memoria liberata. Un singolo errore di segmentazione può causare il blocco dei server di produzione, ma, cosa ancora più grave, molti modelli di errore di segmentazione sono sfruttabili per l'esecuzione di codice arbitrario.
Perché è importante
Implicazioni per la sicurezza: gli overflow del buffer e le vulnerabilità di tipo “use-after-free” sono alla base della maggior parte degli exploit che causano la corruzione della memoria. Gli aggressori li sfruttano per sovrascrivere gli indirizzi di ritorno, iniettare shellcode o manipolare il flusso di controllo del programma. La vulnerabilità Heartbleed del 2014 era un caso di lettura eccessiva del buffer. Gli exploit moderni continuano a prendere di mira questi modelli perché garantiscono agli aggressori un accesso diretto alla memoria.
Stabilità del sistema: Gli errori di segmentazione causano l'arresto immediato dell'applicazione senza alcuna degradazione graduale. Nei sistemi di produzione, ciò comporta la perdita di richieste, l'interruzione delle transazioni e il danneggiamento dello stato. A differenza delle eccezioni dei linguaggi di alto livello, che possono essere intercettate, gli errori di segmentazione terminano il processo, rendendo necessarie procedure di riavvio e ripristino.Espansione della superficie di attacco: Ogni dereferenziazione di un puntatore non controllata, strcpy, memcpy, oppure l'accesso agli array senza controllo dei limiti rappresenta un potenziale punto di ingresso per gli attacchi. Gli aggressori concatenano queste vulnerabilità, sfruttandone una per corrompere la memoria in modo tale da consentire lo sfruttamento di un'altra.
Esempi di codice
❌ Non conforme:
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
}Perché non è sicuro: Il strcpy() La chiamata provoca un overflow del buffer se l'input supera i 63 byte, consentendo agli aggressori di sovrascrivere la memoria dello stack. Il get_config_value() La funzione causa una perdita di memoria ad ogni chiamata e comporta il rischio di puntatori pendenti se chi la chiama libera la memoria mentre altro codice continua a farvi riferimento.
✅ Conforme:
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
}Perché è sicuro: I controlli sui puntatori nulli impediscono i crash dovuti alla dereferenziazione. L'allocazione dinamica elimina i limiti fissi di dimensione del buffer. La copia con controllo dei limiti tramite strncpy() impedisce il traboccamento. Semantica di proprietà chiara in get_config_value() in cui è il chiamante a fornire la memoria, evitando così confusione nell'allocazione e perdite di memoria.
Conclusione
La sicurezza della memoria in C e C++ richiede una programmazione difensiva in ogni operazione sui puntatori e in ogni allocazione di memoria. Gli errori di segmentazione non sono inevitabili, ma possono essere prevenuti attraverso controlli sistematici del valore nullo, la verifica dei limiti e modelli chiari di gestione della memoria. Individuare questi modelli prima della messa in produzione consente di prevenire sia i crash che le vulnerabilità sfruttabili.

