Unsafe Rust es una extensión del subconjunto seguro de Rust que permite realizar operaciones que el compilador no puede verificar en cuanto a la propiedad, el tiempo de vida y el aliasing. Las áreas principales de aplicación son: la interacción con bibliotecas de bajo nivel, FFI, control manual de memoria, implementación de abstracciones que no se ajustan al modelo de Rust seguro.
Características clave de unsafe:
unsafe { ... } o la función: unsafe fn some_func()Ejemplo:
let x: i32 = 10; let ptr: *const i32 = &x as *const i32; unsafe { println!("Valor: {}", *ptr); // desreferenciación de puntero crudo }
¿Es el código dentro de un bloque unsafe completamente inseguro y no verificado por el compilador, o el compilador aún aplica las reglas del borrow checker y otras comprobaciones?
Respuesta: No, dentro de un bloque unsafe, el compilador sigue verificando muchas reglas de Rust (por ejemplo, tipado, reglas de propiedad, sintaxis), pero permite realizar solo aquellas acciones que de otro modo no estarían permitidas. ¡No se puede desactivar completamente el borrow checker!
Ejemplo:
let mut x = 0; let r1 = &mut x as *mut i32; // Prohibido: let r2 = &mut x as *mut i32; // incluso dentro de unsafe habrá errores si se viola la mutabilidad
Historia
En una biblioteca de archivos asincrónica, se utilizó un puntero crudo para el control de un búfer, pero se olvidaron de rastrear correctamente el tiempo de vida del búfer. Como resultado, al cerrar el archivo, el puntero se volvió "colgante" y el acceso provocó un comportamiento indefinido (la sección unsafe no salvó de use-after-free).
Historia
En una implementación propia de una estructura similar a Vec, el programador expandía manualmente el búfer a través de unsafe. Un error de desplazamiento provocó una copia incorrecta de elementos y corrupción de datos, porque no se tuvieron en cuenta la alineación y el diseño de los tipos.
Historia
En un descriptor de hilos se utilizó un puntero estático mutable (static mut) sin la sincronización adecuada. Debido a esto, en modo multihilo, se produjo accidentalmente una condición de carrera de datos, lo que provocó un fallo esporádico de la aplicación, que solo fue detectado por fuzzing.