Dangling pointer¶
Artık geçerli olmayan (free edilmiş ya da scope dışı kalmış) belleğe hâlâ referans veren bir pointer.
Mechanism¶
Bir dangling pointer, daha önce geçerli olan ancak artık olmayan belleğin adresini
tutar — çünkü object free() edilmiş ya da lexical scope'u sona ermiştir. Allocator
bu arada o belleği başka bir object'e yeniden vermiş olabilir. Dolayısıyla dangling
pointer'ı dereference etmek, o slot'u artık her ne işgal ediyorsa ona dokunur.
Note
MITRE hiyerarşisinde CWE-825 (Expired Pointer Dereference) hem CWE-416
(use-after-free) hem de CWE-415 (double-free)'in parent'ıdır (ikisi de
"Variant" seviyesinde ParentOf çocukları). Kavramsal olarak dangling pointer
bu iki saldırının üstüne bindiği durumdur: CWE-416 reclaim edilmiş slot'un
dereference'ı, CWE-415 aynı chunk'ın tekrar free'lenmesi olarak bu durumun
spesifik manifestasyonlarıdır. Bir dangling pointer üzerinden okumak yeni
sakini leak'ler; yazmak onu corrupt eder — ve eğer yeni object bir function
pointer veya vtable tutuyorsa, bu arbitrary code execution'a dönüşür.
Walkthrough¶
Kanonik bug: bir pointer free edilir (ya da scope dışına çıkar) ama daha sonra yeniden kullanılır.
char *ptr = malloc(SIZE);
if (err) {
free(ptr); // ptr is now dangling
}
// ...
if (abrt) {
log_error("operation aborted", ptr); // expired pointer dereferenced
}
free(ptr)'den sonra chunk allocator'ın freelist'ine döner. Eğer attacker input'u
arada aynı boyutta bir allocation tetiklerse, o chunk yeniden verilir ve attacker
byte'larıyla doldurulur; ptr'nin sonraki dereference'ı artık attacker-controlled
veriyi okur/yazar. Beklenen davranış bir leak'ten (read) bir crash/DoS'a, reclaim
edilen object bir ops/vtable struct olduğunda da control-flow hijack'e kadar
uzanır — yani klasik use-after-free chain'i.
Detection¶
ASan / KASAN free edilmiş bölgeleri poison'lar ve bir sonraki erişimde
use-after-free raporlar; valgrind --tool=memcheck free edilmiş blok'larda "Invalid
read/write" işaretler. Static analyzer'lar free-then-use dataflow'unu izler.
Mitigation¶
free()'den hemen sonra pointer'ı NULL yap (bir UAF'ı NULL-deref'e çevirir), tüm
alias'ları null'la ya da RAII / memory-safe bir dil kullan. Allocator hardening
(quarantine, delayed reuse, MTE) bar'ı yükseltir ama sınıfı ortadan kaldırmaz.