Rust neye söz veriyor?
Rust’ta unsafe blok kullanmadığın sürece derleyici bellek hatalarını daha derleme anında engelliyor: Serbest bırakılmış belleği kullanmak, aynı veriye aynı anda iki yerden yazmak gibi. Bunu yapan parça, her referansın ne kadar yaşayacağını takip eden borrow checker.
Bir dilin tip sistemi bu sözü gerçekten tutuyorsa ona sound (sağlam) denir. Güvenli kodla tanımsız davranış (undefined behavior) üretilebiliyorsa sistem unsound olur. Rust ekibi bu tür hataları I-unsound etiketiyle işaretliyor. Bir derleyicide görülebilecek en ciddi hata türü bu.
Hata ne?
13 Ekim’de Rust deposunda açılan 164250 numaralı kayıt şöyle çalışıyor. Bir struct tanımlıyorsun ve içinde tuttuğu şeyin programın sonuna kadar yaşaması gerektiğini söylüyorsun. Rust’ta buna 'static sınırı deniyor. Bu struct’ın Drop fonksiyonu, yani değer yok edilirken çalışan kodu, bu söze güvenip elindeki referansı bir kenara saklıyor. Sonra main içinde kısa ömürlü bir String oluşturuyorsun, struct’ı boş yaratıyorsun ve alanına bu string’in referansını sonradan atıyorsun.
Derleyicinin bu atamayı reddetmesi gerekiyor, çünkü kısa ömürlü bir referans “sonsuza kadar yaşar” denen bir yere giriyor. Reddetmiyor. Struct yok edilirken Drop kodu, birazdan silinecek bir string’i ömür boyu geçerli sanıyor. Kayıttaki örnekte program, string’in eski yerine sonradan yazılan başka bir metni basıyor. AddressSanitizer ile çalıştırınca da “stack-use-after-scope” hatasıyla çöküyor. Yani tek satır unsafe olmadan, silinmiş belleği okuyabiliyorsun.
Kaydın başlığı sebebi de söylüyor: covariant bir alana atama. Rust, uzun ömürlü bir referansı daha kısa ömür beklenen bir yere koymana izin veriyor. Bir türün bu esnekliği içindekilere de taşımasına kovaryans deniyor. Bu esneklik, atama sırasında struct’ın kendi ömür şartının kontrol edilmeden atlanmasına yol açıyor.
11 yıl nasıl fark edilmedi?
Kaydı açan kişi hatayı 1.85 sürümüne kadar geriye doğru denedi. Sonra katkıcılar kendi varyantlarını yazdı. Biri, kendi sürümünün 2017’deki 1.18’den beri derlendiğini fark edip “Bu nasıl daha önce bulunmadı?” diye sordu. Rust’ın tip ekibinden lcnr da Compiler Explorer’da başka bir varyantın Rust 1.4’ten, yani 2015’ten beri derlendiğini gösterdi.
Ekibin değerlendirmesi önemli. Hata P-high önceliğinde. Kayda eklenen nota göre bu kadar eski olmasaydı P-critical olurdu: 11 yıl kimse denk gelmediyse, kazara tetiklemek pek kolay değil demektir. Ayrıca hatayı kullanmak için kasıtlı olarak kötü niyetli bir Drop yazman gerekiyor. Yani günlük kodunda bu yüzden bir bellek hatası çıkması düşük ihtimal.
Tek değil
Rust deposunda I-unsound etiketli 150’den fazla açık kayıt var. En ünlüsü #25860, 2015’ten beri açık. Ekip, bu tür hataların kökünü kazımak için yeni nesil trait çözücü ve ömür kısıtlarının yeniden yazımı gibi büyük projeler yürütüyor. Kayıttaki nota göre tip sistemindeki bütün sağlamlık hatalarını kapatmak, Types ekibinin en büyük önceliklerinden.
Buradan çıkan ders şu: Bellek güvenliği bir dil özelliği gibi anlatılıyor, ama aslında derleyicinin verdiği bir söz. Derleyici de kod, onun da hatası olabilir. Bu, Rust’ın vaadini boşa çıkarmıyor. Git’in Rust’ı zorunlu hâle getirmesi gibi kararların arkasında bu sözün pratikte çok iyi tutması var. Ama “güvenli Rust” da tek başına kesin bir kanıt değil, iyi bir güvence.
Düşün
- Kullandığın dilin ya da derleyicinin sana verdiği bir söz bozulsa, bunu nasıl fark ederdin?
- 11 yıl boyunca kimsenin görmediği bir hatayı bulmak için hangi tür testler işe yarar?
Videoyu izle
Kaynaklar (5, İngilizce)
- Better Stack: Rust Had a Memory Safety Bug for 11 Years (video) (yeni sekmede açılır)
- rust-lang/rust #164250: struct's lifetime requirements can be bypassed via covariant field assignment (yeni sekmede açılır)
- rust-lang/rust #25860: Implied bounds on nested references + variance = soundness hole (yeni sekmede açılır)
- Rust Reference: Behavior considered undefined (yeni sekmede açılır)
- Rust Project Goals 2026: Next-generation trait solver (yeni sekmede açılır)
Kendi cümlelerimizle yazılmış bir özettir, çeviri değildir. Tüm kaynaklar yukarıda.