ProgramlamaSistem Program Mühendisi / Rust Kıdemli Geliştirici

Unsafe Rust nedir, neden gereklidir, kuralları nelerdir ve güvenlik risklerini en aza indirmek için unsafe blokları nasıl doğru kullanılır?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

Unsafe Rust, derleyicinin sahiplik, yaşam süresi ve aliasing doğruluğunu kontrol edemediği işlemleri kullanmaya olanak tanıyan, Rust'ın güvenli alt kümesinin bir genişletmesidir. Temel kullanım alanları: düşük seviyeli kütüphanelerle etkileşim, FFI, manuel bellek yönetimi, güvenli Rust modeline uymayan soyutlamaların uygulanması.

Unsafe'ın ana özellikleri:

  • Kullanmak için blokun açıkça belirtilmesi gerekir: unsafe { ... } veya fonksiyon: unsafe fn some_func()
  • Unsafe blokta güvensiz işlemlere izin verilir: raw pointer dereference, güvensiz fonksiyon ve metodların çağrılması, union erişimi, statik değişkenlere erişim, yapılandırılmamış belleği yönetme yöntemlerinin uygulanması
  • Unsafe kullanımı, blok içindeki tüm kodu dil açısından tehlikeli hale getirmez — yalnızca doğruluğu manuel olarak garanti etmeyi taahhüt eder.

Örnek:

let x: i32 = 10; let ptr: *const i32 = &x as *const i32; unsafe { println!("Değer: {}", *ptr); // raw pointer dereference }

Aldatmaca Soru

Uygulanan kod, unsafe blok içinde tamamen güvensiz midir ve derleyici tarafından kontrol edilmez, yoksa derleyici hala borrow checker ve diğer kontrolleri mi uygular?

Cevap: Hayır, unsafe blok içinde derleyici, Rust'ın birçok kuralını (örneğin, tip kontrolü, sahiplik kuralları, sözdizimi) kontrol etmeye devam eder, ancak aksi takdirde izin verilmeyen yalnızca o eylemleri gerçekleştirmeye izin verir. Borrow checker'ı tamamen devre dışı bırakmak mümkün değildir!

Örnek:

let mut x = 0; let r1 = &mut x as *mut i32; // Yasak: let r2 = &mut x as *mut i32; // unsafe içinde bile, değiştirilebilirlik ihlal edilirse hatalar oluşacaktır.

Gerçek Hatalara Dair Örnekler


Hikaye

Asenkron dosya kütüphanesinde bir buffer kontrolü için raw pointer kullanıldı, ancak buffer'ın yaşam süresini doğru izlemeyi unuttular. Sonuç olarak, dosya kapatıldığında pointer "sarkık" hale geldi ve erişim, undefined behavior'a neden oldu (unsafe bölge use-after-free'den kurtaramadı).


Hikaye

Kendi Vec-benzeri bir yapı implementasyonunda, programcı buffer'ı unsafe ile manuel olarak genişletti. Offset hatası, alignment ve tiplerin düzeni dikkate alınmadığı için, elemanların hatalı kopyalanmasına ve veri bozulmasına yol açtı.


Hikaye

Thread descriptor'unda, uygun senkronizasyon olmadan statik değiştirilebilir bir pointer (static mut) kullanıldı. Bu durum çoklu iş parçacığı modunda rastgele bir data race'e yol açtı ve uygulamanın ara sıra çökmesine neden oldu, yalnızca fuzzing ile tespit edildi.