Null Pointer Dereference
Null Pointer Dereference, bir işaretçinin (pointer) NULL (0x0) adresini göstermesine rağmen, bu işaretçi üzerinden veri okunmaya veya yazılmaya çalışılması sonucu oluşan bir yazılım hatasıdır.Basitçe ifade etmek gerekirse, geçersiz bir bellek adresine erişilmeye çalışılmasıdır.
Örneğin;
C:
int *ptr = NULL;
*ptr = 10;
Burada ptr herhangi bir geçerli belleği göstermemektedir. Buna rağmen üzerine veri yazılmaya çalışıldığı için program çöker.
Arka Planda Ne Olur?
Modern işletim sistemleri (Linux ve Windows), her proses için Sanal Bellek (Virtual Memory) kullanır.C dilinde;
C:
void *ptr = NULL;
Bir pointer NULL değerini gösterirken;
C:
*ptr
C:
ptr->member
Fakat modern işletim sistemlerinde sanal adres alanındaki ilk sayfa (0x0 adresi) kasıtlı olarak eşlenmez (unmapped). Böylece NULL adresine erişim yapılmaya çalışıldığında işlemci bir Page Fault (#PF) istisnası oluşturur.
Çekirdek (Kernel) bu istisnayı yakalar ve kullanıcı modundaki proses için genellikle SIGSEGV (Segmentation Fault) sinyalini gönderir.
Sonuç olarak program anında sonlandırılır.
Kernel Açısından Neden Önemlidir?
Kullanıcı modundaki (User Mode) uygulamalarda Null Pointer Dereference çoğunlukla yalnızca programın çökmesine neden olur.Ancak Kernel tarafında durum çok daha kritiktir.
Kernel içerisinde meydana gelen bir NULL Pointer Dereference;
- Kernel Panic
- Sistem çökmesi
- Mavi ekran (Windows)
- Hizmet dışı kalma (Denial of Service)
Bu nedenle kernel geliştirme sürecinde NULL kontrolleri son derece önemlidir.
Null Pointer Dereference Nasıl Oluşur?
Bu hata yalnızca tek bir sebepten kaynaklanmaz.En yaygın nedenler şunlardır:
- malloc() veya calloc() başarısız olduğunda dönen NULL değerinin kontrol edilmemesi
- Dosya veya sistem kaynağının açılamaması
- Başarısız fonksiyon dönüşlerinin kontrol edilmemesi
- Yanlış başlatılmış pointerlar
- Serbest bırakılmış (free edilmiş) pointerların yanlış kullanılması
- Hatalı hata yönetimi (Error Handling)
malloc() Örneği
Bellek ayırma fonksiyonları yeterli bellek bulamazsa NULL döndürür.Eğer bu durum kontrol edilmezse program çöker.
#
C:
include <stdio.h>
#include <stdlib.h>
#include <string.h>
void process_data(size_t size)
{
char *buffer = malloc(size);
// HATA:
// malloc() başarısız olabilir.
// NULL kontrolü yapılmıyor.
strcpy(buffer, "Bayazor burada");
printf("%s\n", buffer);
free(buffer);
}
int main()
{
process_data(SIZE_MAX);
return 0;
}
Ardından;
strcpy(buffer, "Bayazor burada");
çalıştırıldığında buffer artık NULL olduğu için program Segmentation Fault ile sonlanacaktır.
Doğru kullanım ise şöyledir:
C:
char *buffer = malloc(size);
if (buffer == NULL)
{
perror("malloc");
return;
}
CPU ve MMU Tarafında Neler Oluyor?
Program;
C:
*ptr = 10;
Kabaca süreç şu şekilde ilerler:
- CPU ilgili bellek adresini hesaplar.
- Pointer değeri NULL olduğu için adres 0x0 olur.
- MMU (Memory Management Unit) bu sanal adres için sayfa tablosunu kontrol eder.
- İlk sayfanın eşlenmediğini (Present = 0) görür.
- İşlemci bir Page Fault (#PF) istisnası oluşturur.
- Çekirdek bu istisnayı yakalar.
- Kullanıcı modundaki programa SIGSEGV sinyali gönderilir.
- Program sonlandırılır.
Kod:
NULL Pointer
│
▼
CPU adresi hesaplar (0x0)
│
▼
MMU sayfa tablosunu kontrol eder
│
▼
Sayfa mevcut değil (Present = 0)
│
▼
Page Fault (#PF)
│
▼
Kernel
│
▼
SIGSEGV
│
▼
Program çöker.
Oluşabilecek Sonuçlar
Null Pointer Dereference her zaman yalnızca programın çökmesine neden olmaz.Duruma göre;
- Denial of Service (DoS)
- Bilgi sızıntısı (Information Leak)
- Kernel Panic
- Ayrıcalık yükseltme (Bazı kernel senaryolarında)
Özellikle geçmiş yıllarda NULL sayfasının kullanıcı tarafından eşlenebildiği eski işletim sistemlerinde bu durum çeşitli ayrıcalık yükseltme (Privilege Escalation) zafiyetlerine neden olmuştur.
Gerçek Dünya Örneği
2025 yılı içerisinde BoxStrike ekibi tarafından açık kaynaklı iki farklı projede Null Pointer Dereference zafiyetleri tespit edilmiş ve ilgili geliştiricilere sorumlu açıklama (Responsible Disclosure) kapsamında bildirilmiştir.Bu örnek, günümüzde bile NULL kontrollerinin ihmal edilmesinin gerçek güvenlik açıklarına yol açabildiğini göstermektedir.
https://github.com/yaml/libyaml/issues/337
https://github.com/DaveGamble/cJSON/issues/1040
Bu küçük kontrol, hem kullanıcı modunda oluşabilecek çökmeleri hem de kernel seviyesinde meydana gelebilecek ciddi güvenlik problemlerini önleyebilir.