Cómo difieren los CVE de seguridad de memoria entre Rust y C/C++
Rust, comportamiento indefinido y unsafe
- Algunos sostienen que el comportamiento indefinido (UB) puede ocurrir en Rust sin usar directamente
unsafeen tu crate: a través deno_std, agujeros de corrección del lenguaje, UB en dependencias o en la biblioteca estándar, o errores del compilador/LLVM. - Otros enfatizan el modelo de Rust: el UB debe originarse en algún
unsafeen alguna parte (incluidas dependencias o std); la ventaja es queunsafequeda localizado y es revisable.
Semántica del desbordamiento de enteros
- Disputa sobre el comportamiento de Rust de “panic en debug, wrap en release”.
- Los críticos dicen que tener dos comportamientos hace que el desbordamiento sea prácticamente tan poco fiable como el UB y desean que el desbordamiento siempre provocara panic.
- Otros subrayan que esto está definido por la implementación, no es UB: el comportamiento está acotado y es configurable (
overflow-checks = true), a diferencia del UB en C/C++ que puede llevar a desoptimizaciones extremas.
Cómo interpretar los CVE de Rust
- Las bibliotecas de Rust tienden a tratar cualquier uso incorrecto que pueda causar UB como un CVE, incluso si la explotación es poco realista.
- Los ecosistemas de C/C++ rara vez clasifican estos problemas como CVE, así que el número bruto de “CVE” se considera una métrica engañosa para la seguridad del lenguaje.
- Algunos temen que esto pueda extenderse a que los panics se traten como vulnerabilidades DoS; otros lo ven como parte de una cultura que prioriza la corrección.
Prevalencia e importancia de los errores de seguridad de memoria
- Un comentarista afirma que los errores de memoria son una fracción diminuta de las vulnerabilidades “promedio”; otros lo disputan y citan datos (dentro del hilo) que indican que los problemas de seguridad de memoria dominan los zero-days de alto impacto.
- Se debate si portar grandes bases de código a Rust es una sobreoptimización o si está justificado para software de alto valor y muy atacado (navegadores, componentes del sistema operativo, Android).
Estrategias de seguridad en Rust frente a C++ moderno
- Una postura sostiene que C++ moderno más bibliotecas endurecidas, sanitizers y guías puede resolver en gran medida los errores de memoria si se usa de forma consistente.
- Puntos de contraste:
- En la práctica, muchas bases de código grandes en C/C++ siguen siendo inseguras (Android, Chromium, bibliotecas del sistema).
- La seguridad en Rust es el valor predeterminado; en C++ la seguridad a menudo requiere opt-in, disciplina cuidadosa y toolchains que los equipos suelen relajar bajo presión de entrega.
- Se citan informes del mundo real (por ejemplo, Android) como evidencia de que Rust produce grandes reducciones en vulnerabilidades de memoria frente al código heredado en C/C++.
Nulls, assertions y contratos
- Discusión en torno a funciones como
curl_getenvy si conviene usarassertsobre entradas nulas. - Algunos defienden comprobaciones de precondiciones en todas partes; otros argumentan que en C esto se vuelve ruidoso y a menudo degenera en “crashear igual por una desreferencia nula”.
- Se contrasta
Option<T>de Rust y las referencias no anulables: las APIs deben optar explícitamente porNone, y el uso incorrecto lleva a panics con trazas claras en lugar de UB.
Rendimiento y tendencias de adopción
- Ejemplos como la reescritura del parser HTML de Ladybird muestran Rust sustituyendo a C++ con rendimiento igual o mejor.
- Se debate si las ganancias de velocidad provienen de Rust en sí o de las oportunidades de rediseño durante las reescrituras.
- Se considera que C y C++ están perdiendo terreno en algunos dominios (navegadores, kernels), aunque muchos ámbitos (HPC, HFT, stacks guiados por estándares) todavía giran en torno a C/C++.
Complejidad de Rust y preocupaciones sobre dependencias
- Los críticos destacan la complejidad conceptual de Rust (ownership, lifetimes, tipos avanzados) y el esfuerzo dedicado a dar forma a los tipos para satisfacer al borrow checker.
- Los partidarios lo presentan como “hacer explícita la complejidad” en lugar de ocultarla, logrando código más seguro y más fácil de depurar.
- Hay una preocupación general por árboles de dependencias grandes y profundos en Rust (stdlib delgada, muchos crates,
build.rs, publicación ligada a GitHub) y el riesgo correspondiente para la cadena de suministro. - Los defensores señalan que C/C++ a menudo “resuelven” esto vendorizando o copiando y pegando código, lo que oculta las dependencias en lugar de eliminarlas.