Unsafe Rust is een uitbreiding van de veilige subset van Rust die het mogelijk maakt om operaties uit te voeren die de compiler niet kan controleren op correctheid van eigendom, levensduur en aliasing. De belangrijkste toepassingsgebieden zijn: interactie met low-level bibliotheken, FFI, handmatige geheugentoewijzing, implementatie van abstracties die niet binnen het veilige model van Rust passen.
Belangrijkste kenmerken van unsafe:
unsafe { ... } of de functie: unsafe fn some_func()Voorbeeld:
let x: i32 = 10; let ptr: *const i32 = &x as *const i32; unsafe { println!("Value: {}", *ptr); // dereferencen van raw pointer }
Is de code binnen een unsafe-blok volledig onveilig en niet gecontroleerd door de compiler, of past de compiler nog steeds de regels van de borrow checker en andere controles toe?
Antwoord: Nee, binnen een unsafe-blok blijft de compiler een aantal regels van Rust controleren (bijvoorbeeld typechecking, eigendomregels, syntaxis), maar staat alleen die acties toe die anders niet zouden zijn toegestaan. Je kunt de borrow checker niet volledig uitschakelen!
Voorbeeld:
let mut x = 0; let r1 = &mut x as *mut i32; // Verboden: let r2 = &mut x as *mut i32; // zelfs binnen unsafe zullen er fouten optreden als de mutabiliteit wordt geschonden
Geschiedenis
In een asynchrone bestandsbibliotheek werd een raw pointer gebruikt voor het controleren van een buffer, maar men vergat de levensduur van de buffer correct te volgen. Hierdoor, bij het sluiten van het bestand, werd de pointer "hangend" en toegang leidde tot undefined behavior (de unsafe-sectie redde niet van use-after-free).
Geschiedenis
In een eigen implementatie van een Vec-achtige structuur breidde de programmeur handmatig de buffer uit via unsafe. Een offsetfout leidde tot onjuiste kopieën van elementen en datacorruptie, omdat alignment en layout van types niet in aanmerking waren genomen.
Geschiedenis
In een thread descriptor werd een statische mutable pointer (static mut) gebruikt zonder de juiste synchronisatie. Hierdoor ontstond er per ongeluk een data race in multi-threaded modus, wat leidde tot sporadische crashes van de applicatie, alleen opgevangen door fuzzing.