Kural
Yaygın segmentasyon hatası kalıplarını önleyin.
Null pointer başvuruları, arabellek taşmaları
ve use-after-free hataları çökmelere ve güvenlik açıklarına yolaçar.
Desteklenen diller: C/C++Giriş
Segmentasyon hataları, C/C++ uygulamalarındaki çökme ve istismar edilebilir açıkların en yaygın kaynağı olmaya devam etmektedir. Bu bellek erişim ihlalleri, kod kendisine ait olmayan bir belleği okumaya veya yazmaya çalıştığında (tipik olarak null pointer başvuruları, arabellek taşmaları, sarkık pointer'lar veya serbest bırakılmış belleğe erişim yoluyla) meydana gelir. Tek bir segfault bile prodüksiyon sunucularını çökletebilir, ancak daha da kötüsü, birçok segfault kalıbı rastgele kod çalıştırmak üzere istismar edilebilir.
Neden önemli?
Güvenlik etkileri: Arabellek taşmaları ve use-after-free güvenlik açıkları, çoğu bellek bozulması istismarının (exploit) temelini oluşturur. Saldırganlar geri dönüş adreslerinin üzerine yazmak, shellcode enjekte etmek veya program kontrol akışını manipüle etmek için bunlardan yararlanır. 2014 yılındaki Heartbleed açığı bir arabellek aşırı okuma (buffer over-read) vakasıydı. Modern istismarlar hâlâ bu kalıpları hedef almaktadır çünkü saldırganlara doğrudan bellek erişimi sağlarlar.
Sistem kararlılığı: Segmentasyon hataları (segfault), uygulamanızı zararsız bir düşüş yaşatmadan doğrudan çöktürür. Prodüksiyon sistemlerinde bu durum; düşen istekler, kesintiye uğrayan işlemler ve bozulmuş durumlar anlamına gelir. Yakalanabilen üst düzey dil istisnalarının aksine, segfault'lar süreci sonlandırarak yeniden başlatma ve kurtarma prosedürleri gerektirir.Saldırı yüzeyinin genişlemesi: Kontrol edilmeyen her işaretçi (pointer) başvuru kaldırma işlemi, strcpy, memcpyveya sınır denetimi yapılmayan dizi erişimleri, istismar için potansiyel birer giriş noktasıdır. Saldırganlar bu güvenlik açığını birleştirerek, belleği birini istismar etmek amacıyla diğerini bozacak şekilde kullanır.
Kod örnekleri
❌ Kural dışı:
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
}Güvensiz olma nedeni: The strcpy() çağrısı, girdi 63 baytı aşarsa arabellek taşmasına (buffer overflow) neden olarak saldırganların yığın (stack) belleğinin üzerine yazmasına olanak tanır. get_config_value() fonksiyonu, her çağrıda bellek sızıntısına yol açar ve diğer kodlar hala başvururken çağıran taraf belleği serbest bırakırsa sarkık işaretçi (dangling pointer) riski oluşturur.
✅ Kurallara uygun:
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
}Neden güvenli? Null işaretçi kontrolleri, başvuru kaldırma çökmelerini önler. Dinamik tahsis, sabit arabellek boyutu sınırlarını ortadan kaldırır. Sınır denetimli kopyalama strncpy() taşmayı önler. Şu dosyadaki net sahiplik kuralları: get_config_value() ile taşmalar engellenir. Çağıranın belleği sağladığı ve tahsis karmaşası ile sızıntıların önlendiği durumlarda net sahiplik semantiği kullanılır.
Sonuç
C ve C++ dillerinde bellek güvenliği, her işaretçi işleminde ve bellek tahsisinde savunmacı programlama gerektirir. Segmentasyon hataları kaçınılmaz değildir; tutarlı null kontrolleri, sınır doğrulama ve net bellek sahipliği kalıplarıyla önlenebilir. Bu kalıpların prodüksiyon öncesinde yakalanması, hem çökmeleri hem de istismar edilebilir açıkları engeller.

