Buğra Şıkel
Rust Borrow Checker Hatası: 11 Yıllık Unsoundness Zafiyeti

Ekim 2026 itibarıyla, rust borrow checker mekanizmasında 11 yıldır gizlenen ve hiçbir unsafe bloğu gerektirmeden bellek ihlaline (use-after-free) yol açan kritik bir unsoundness hatası doğrulandı. 13 Ekim 2026’da kamuoyuna duyurulan ve #164250 numaralı issue ile takip edilen bu zafiyet, derleyicinin tip birleştirme (type unification) mantığındaki bir kör noktadan kaynaklanıyor. Hata, Ekim 2015’te yayınlanan Rust 1.4.0 sürümünden bu yana tüm kararlı sürümlerde mevcut. Rust 1.99.1 sürümü UEFI ve gömülü hedeflerdeki wcslen sembolü eksikliklerini ve x86_64 mimarisindeki FFI bool yanlış derleme (miscompilation) sorunlarını çözdü. Ancak bu spesifik hatanın yaması halen PR aşamasında.
Sistem programcıları için asıl risk, tamamen Safe Rust kuralları içinde yazılmış kodların, derleyici hatası yüzünden tanımsız davranış (Undefined Behavior – UB) sergileme potansiyelidir. Aşağıdaki bölümlerde rustc’deki mantık hatalarının nasıl tetiklendiğini, özel Drop implementasyonlarının yarattığı riskleri ve yama (PR #164277) yayınlanana kadar production ortamlarınızı nasıl koruyacağınızı detaylandırıyoruz.
İçindekiler
- Rust Borrow Checker ve Unsoundness Kavramı
- Hata 1: Covariant Yaşam Ömürleri ve Özel Drop Çatışması
- Hata 2: Zımni Sınırlara (Implied Bounds) Aşırı Güven
- Hata 3: Bellek Analiz Araçlarını İhmal Etmek
- Hata 4: Eski API’leri ve Transmute İşlemlerini Dikkatsiz Kullanmak
- Stratejik Kod Denetimi ve Karar Matrisi
- Sık Sorulan Sorular
- Değerlendirme
Rust Borrow Checker ve Unsoundness Kavramı
Rust programlama dilinde rust bellek yönetimi, sahiplik (ownership) ve borçlanma (borrowing) kurallarına dayanır. Dilin teorik tasarımı, unsafe anahtar kelimesi kullanılmadığı sürece bellek güvenliğini garanti eder. Derleyici (rustc), bu teorik kuralları koda uygulayan karmaşık bir yazılımdır. Derleyicinin, geçersiz bir kodu geçerli kabul edip derlemesine izin vermesi durumuna unsoundness (güvensizlik) adı verilir.
Ocak 2022 ile Eylül 2025 arasında yapılan akademik analizler, rustc’de potansiyel soundness hatası bildiren 30 farklı issue raporlandığını ortaya koymuştur. Bu tür unsoundness bugs, derleyicilerin mantık hataları barındırabileceğini kanıtlar. Rust ekibi, derleyici açıklarını tamamen ortadan kaldırmak için Project Zero (2026 Roadmap) inisiyatifini başlatmıştır.
Ekim 2026’da ortaya çıkan #164250 numaralı hata, doğrudan derleyicinin tip birleştirme (type unification) algoritmasını hedef alır. Derleyici, karmaşık yaşam ömrü (lifetime) sınırlarını hesaplarken alt tipleme (subtyping) kurallarını yanlış yorumlar ve bellekten silinmiş bir veriye erişime (use-after-free) izin verir.
Hata 1: Covariant Yaşam Ömürleri ve Özel Drop Çatışması
Rust borrow checker mekanizmasındaki temel kör noktalardan biri, eşdeğişken (covariant) yaşam ömürlerinin özel Drop trait’i implementasyonlarıyla birleştiği anlardır. Jenerik bir yapı (struct) içinde bir referans tuttuğunuzda, bu referansın yaşam ömrü genellikle covariant’tır. Daha uzun ömürlü bir referans, daha kısa ömürlü bir referansın yerine geçebilir. Bu yapıya özel bir Drop trait’i yazıp yapı içindeki bir alanı önce None yapıp sonra kısa ömürlü bir referans atarsanız, derleyicinin yaşam ömrü kontrol mekanizması (dropck) atlatılır.
Kod tabanınızda Drop trait’ini implemente eden ve aynı zamanda yaşam ömrü parametresi (&'a T) barındıran jenerik struct’ları denetleyin. Bu struct’lar statik bir bağlamda (örneğin Box<dyn Any + Send> tutan global bir Mutex içinde) kullanılıyorsa doğrudan risk altındasınız. Jenerik lifetime parametrelerine sahip struct’lar için karmaşık Drop fonksiyonları yazmaktan kaçının. Struct sadece bellek yönetimi yapmıyor ve iş mantığı barındırıyorsa, temizleme işlemlerini açık bir cleanup() metodu ile yürütün.
#164250 numaralı hatanın minimal reprodüksiyonunda, tamamen Safe Rust kullanılarak bir use-after-free tetiklenmiştir. Kavramsal kanıt şöyledir:
use std::any::Any;
use std::sync::Mutex;
// Statik bir Mutex içinde Box tutuyoruz
static GLOBAL_STORE: Mutex<Option<Box<dyn Any + Send>>> = Mutex::new(None);
struct VulnerableStruct<'a, T: 'a> {
data: Option<&'a T>,
}
impl<'a, T> Drop for VulnerableStruct<'a, T> {
fn drop(&mut self) {
// Kısa ömürlü referans burada yakalanır ve dışarı sızdırılır
// Derleyici, covariant atama nedeniyle 'static sınırını kontrol etmeyi atlar
}
}
Bu kodda, data alanı kısa ömürlü bir referansla güncellendiğinde, derleyici tip birleştirme aşamasında 'static sınırını kontrol etmeyi unutur. Drop tetiklendiğinde referans sızdırılır ve bellek silindikten sonra erişim sağlanır.
Hata 2: Zımni Sınırlara (Implied Bounds) Aşırı Güven
Rust derleyicisi, kodu daha okunabilir kılmak için bazı yaşam ömrü sınırlarını açıkça belirtmeseniz bile zımni olarak (implied) varsayar. Rust derleme hataları genellikle bu varsayımların sınır durumlarında (edge cases) çöktüğü anlarda ortaya çıkar. Trait objeleri (örneğin Box<dyn Trait>) ile çalışırken, derleyici alt tipleme işlemlerinde sınırları her zaman doğru hesaplayamayabilir. 'static + Send gibi çoklu sınırlar gerektiren durumlarda, zımni sınırlara güvenmek unsoundness açıklarına zemin hazırlar.
Kodunuzda dyn Any, dyn Error veya özel trait objeleri döndüren fonksiyonları inceleyin. Yaşam ömrü sınırlarının açıkça belirtilmediği (+ 'a veya + 'static) trait objesi kullanımlarını statik analiz araçlarıyla tarayın. Trait objeleriyle çalışırken yaşam ömrü sınırlarını her zaman açıkça (explicitly) belirtin. Zımni varsayımlara güvenmek yerine, derleyicinin sınırları kesin olarak uygulamasını sağlayın.
PR #164277 yamasında düzeltilen temel sorun, derleyicinin tip birleştirme mantığının Box<dyn Any + Send> yapısındaki 'static gereksinimini, kısa ömürlü bir referans atandığında göz ardı etmesidir. Sistem programlamada bellek sınırlarını zorlarken, Sıfırdan Lock-Free Ring Buffer: C++ ile p99 Latency Optimizasyonu makalesinde işlediğimiz gibi, bellek bariyerleri ve yaşam ömürleri konusunda derleyiciye inisiyatif bırakmak risklidir.
Hata 3: Bellek Analiz Araçlarını İhmal Etmek
Rust geliştiricileri arasındaki en tehlikeli yanılgı, kod tabanında unsafe bloğu bulunmadığı sürece bellek hatası (memory leak, use-after-free, double free) yaşanmayacağına inanmaktır. Safe Rust bellek güvenliğini garanti etmeyi hedefler, ancak bu garanti derleyicinin kusursuz çalışmasına bağlıdır. Derleyicideki bir unsoundness hatası, Safe Rust kodunu doğrudan tanımsız davranışa sürükler. Geliştiriciler derleyiciye tam güven duydukları için CI/CD süreçlerine bellek analiz araçlarını entegre etmezler.
CI/CD pipeline konfigürasyonunuzu kontrol edin. Test adımlarında Miri veya AddressSanitizer (ASan) çalıştırılmıyorsa, derleyici kaynaklı kör noktalara karşı savunmasızsınız. PR #164277 (veya Rust 1.100.0) tam olarak yayınlanıp sistemlerinize entegre edilene kadar, test süreçlerinize Miri ve ASan entegrasyonunu zorunlu kılın. Birim testlerdeki mantık hatalarını bulmak için Mutation Testing vs Branch Coverage: Birim Testlerdeki Kör Noktaları Tespit Karar Matrisi makalesindeki stratejileri uyguladığınız gibi, derleyici hatalarını bulmak için de dinamik analiz araçlarını kullanın.
#164250 numaralı hata, standart cargo test komutuyla yakalanamaz. AddressSanitizer aktifleştirildiğinde anında çöker ve rapor verir.
# AddressSanitizer ile testi çalıştırmak (Nightly gerektirir)
RUSTFLAGS="-Zsanitizer=address" cargo +nightly test
# Beklenen Çıktı:
# ==12345==ERROR: AddressSanitizer: stack-use-after-scope on address ...
Rust’ın tanımsız davranış tespit aracı Miri, bu kodu çalıştırdığında bellek ihlalini anında yakalar:
cargo +nightly miri run
Hata 4: Eski API’leri ve Transmute İşlemlerini Dikkatsiz Kullanmak
Rust 1.99.1 sürümü ile birlikte standart kütüphanede ve derleyici kontrollerinde sıkılaştırmalar yapılmıştır. Eski API’lerin kullanımı ve tehlikeli tip dönüşümleri, soundness açıklarını tetikleyen diğer faktörlerdir. Uzun süredir bakımı yapılmayan (legacy) kod tabanlarında, bellek düzeni (memory layout) garantisi olmayan tipler arasında dönüşüm yapmak için std::mem::transmute kullanılır. Eski hash algoritmaları bellek adreslerini tahmin edilebilir kılarak zafiyetler yaratır.
Rust 1.99.1 derleyicisinin uyarılarını (warnings) dikkate alın. SipHasher kullanımı ve fn (fonksiyon) item tiplerinden pointer boyutlu tiplere yapılan transmute işlemleri derleyici tarafından doğrudan işaretlenir. Yakın dönem güncellemelerinde kullanımdan kalkan SipHasher API’si yerine standart hale getirilen DefaultHasher kullanımına geçin. Fonksiyon pointer’larını dönüştürürken transmute yerine as cast (as *const ()) sözdizimini tercih edin.
Stratejik Kod Denetimi ve Karar Matrisi
Derleyicideki #164250 hatasının yaması production ortamlarınıza ulaşana kadar, mevcut kod tabanınızı korumak için aşağıdaki karar matrisini uygulayın:
| Risk Faktörü | Tespit Yöntemi | Geçici Çözüm (Mitigation) |
|---|---|---|
Jenerik Drop Implementasyonları |
impl<'a, T> Drop araması yapın |
İş mantığını Drop içinden çıkarın, açık bir temizleme metodu kullanın. |
| Zımni Trait Sınırları | Box<dyn Trait> kullanımlarını tarayın |
Tüm trait objelerine + 'static veya + 'a sınırlarını açıkça ekleyin. |
| Derleyici Kör Noktaları | Mevcut CI/CD pipeline analizi | Nightly derleyici ile cargo miri test adımını pipeline’a zorunlu ekleyin. |
| Transmute İhlalleri | Rust 1.99.1 uyarı logları | fn tiplerinden pointer’a transmute işlemlerini as cast ile değiştirin. |
Sık Sorulan Sorular
Rust borrow checker nedir ve bellek güvenliğini tam olarak nasıl garanti eder?
Rust borrow checker, derleme aşamasında çalışan ve verilerin bellekteki sahiplik (ownership), borçlanma (borrowing) ve yaşam ömrü (lifetime) kurallarını statik olarak analiz eden bir mekanizmadır. Aynı veriye aynı anda birden fazla değiştirilebilir (mutable) referans verilmesini engelleyerek data race ve use-after-free gibi bellek hatalarını teorik olarak imkansız hale getirir.
Rust derleyicisinde “unsoundness bug” (güvensizlik hatası) ne anlama gelir?
Unsoundness bug, derleyicinin (rustc) mantık hataları nedeniyle, dilin güvenlik kurallarını ihlal eden geçersiz bir kodun derlenmesine izin vermesi durumudur. Bu tür hatalar, geliştirici unsafe bloğu kullanmasa bile programın çalışma zamanında tanımsız davranış (UB) sergilemesine yol açar.
İçinde unsafe bloğu bulunmayan Safe Rust kodunda use-after-free hatası mümkün müdür?
Evet, mümkündür. Safe Rust bellek güvenliğini garanti etse de, bu garanti derleyicinin kuralları kusursuz uygulamasına bağlıdır. #164250 numaralı issue gibi derleyici hataları (compiler bugs) mevcut olduğunda, tamamen Safe Rust ile yazılmış kodlarda bile use-after-free veya bellek sızıntısı yaşanabilir.
Rust #164250 numaralı borrow checker hatası production ortamımı nasıl etkiler?
Kod tabanınızda covariant yaşam ömürlerine sahip referansları özel bir Drop trait’i ile yöneten karmaşık jenerik yapılar varsa, bu hata tetiklenebilir. Hata tetiklendiğinde, production ortamınızda rastgele çökmeler (segfault), veri bozulmaları veya güvenlik zafiyetleri (bellek sızıntısı) meydana gelir.
Derleyici hatalarından kaynaklanan zafiyetleri tespit etmek için hangi araçlar kullanılmalıdır?
Derleyici kaynaklı mantık hatalarını tespit etmek için dinamik analiz araçları şarttır. Rust ekosisteminde tanımsız davranışları yakalamak için Miri (cargo miri) ve bellek ihlallerini işletim sistemi seviyesinde tespit etmek için AddressSanitizer (RUSTFLAGS="-Zsanitizer=address") en etkili araçlardır.
Değerlendirme
Rust’ın bellek güvenliği konusundaki sarsılmaz itibarı, dilin teorik tasarımının gücünden gelir. 13 Ekim 2026’da duyurulan 11 yıllık unsoundness hatası (#164250), derleyicilerin de yanılabilir olduğunu sistem programcılarına bir kez daha hatırlatmıştır. Covariant yaşam ömürleri, özel Drop implementasyonları ve zımni sınırlar bir araya geldiğinde derleyicinin tip birleştirme algoritması çöker.
PR #164277 ile sunulan yama kararlı sürüme entegre edilene kadar, “Safe Rust %100 güvenlidir” yanılgısından kurtulmak kritik önem taşır. CI/CD süreçlerinize Miri ve AddressSanitizer gibi araçları entegre ederek, derleyici kör noktalarından kaynaklanabilecek use-after-free hatalarını production ortamına ulaşmadan engellersiniz. Rust Project Zero inisiyatifi bu hataları gidermeyi hedeflerken, mühendisler olarak temel görevimiz kodumuzu derleyicinin mevcut sınırlarına göre test etmektir.
Bunları da beğenebilirsiniz

Neden Cloudflare Kullanmalıyız?
Merhabalar, bu içeriğimde sizlere Cloudflare neden kullanmalıyız, Cloudflare bize ne gibi avantajlar sağlar, faydaları nelerdir, kurulumunu nasıl yapabiliriz gibi soruları cevaplandıracağım. Öncelikle yazımızın akışını belirlemek…
Devamını Oku

Isaac Asimov “The Last Question” [Türkçe]
Bu metin Isaac Asimov tarafından 1956 yılında yayımlanmış “The Last Question” adlı kısa hikayenin Türkçeleştirilmiş ve temel özellikleri korunarak sadeleştirilmiş versiyonudur. Gidişata bakılırsa Asimov’un tahminlerinden…
Devamını Oku

Mevcut C++ Görüntü İşleme Pipeline’larına Python AI Modellerini Sıfır Kopyalama ile Entegre Etmek
Bu blog yazısı, mevcut yüksek performanslı C++ görüntü işleme boru hatlarına Python tabanlı yapay zeka modellerini entegre etmek için sıfır kopyalama yaklaşımlarını inceler. Veri kopyalama maliyetlerini ortadan kaldırarak performansı artırma ve bellek kullanımını optimize etme yöntemlerini detaylandırır.
Devamını Oku