Articulo de referencia

Desinfectante de códigos

Un sanitizador de código es una herramienta de programación que detecta errores en forma de comportamiento indefinido o sospechoso mediante un compilador que inserta código de i...

Un sanitizador de código es una herramienta de programación que detecta errores en forma de comportamiento indefinido o sospechoso mediante un compilador que inserta código de instrumentación en tiempo de ejecución. Los sanitizadores han evolucionado a lo largo de varias décadas para detectar errores de memoria en lenguajes de programación inseguros, [ 1 ] comenzando con comprobaciones tempranas de acceso a punteros y matrices en 1994 [ 2 ] y la adaptación a la seguridad de tipos en 2005 [ 3 ] , seguida de una expansión significativa hacia sofisticadas herramientas de seguridad de memoria espacial y temporal entre 2009 y 2019. [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] A partir de 2024, el sanitizador más popular es ASan, diseñado originalmente por Google . Está integrado en la mayoría de los compiladores principales debido a su sobrecarga de memoria y rendimiento relativamente pequeña. [ 1 ]

Desinfectante de direcciones

ASan de Google, presentado en 2012, utiliza un esquema de memoria en la sombra para detectar errores de memoria. Está disponible en:

El diseño original del sanitizador aumenta el tiempo de procesamiento en aproximadamente un 73 % y el uso de memoria en un 240 %. [ 15 ] Existe un ASan acelerado por hardware llamado HWAsan disponible para AArch64 y (de forma limitada) x86_64. [ 16 ]

AddressSanitizer no detecta lecturas de memoria no inicializadas (pero MemorySanitizer sí las detecta [ 17 ] ), y solo detecta algunos errores de uso después de retorno. [ 18 ] Tampoco es capaz de detectar todos los errores de corrupción de memoria arbitrarios, ni todos los errores de escritura arbitrarios debidos a desbordamientos/subdesbordamientos de enteros (cuando se utiliza un entero con comportamiento indefinido para calcular desplazamientos de direcciones de memoria ). Los búferes adyacentes en estructuras y clases no están protegidos contra desbordamientos, en parte para evitar romper la compatibilidad con versiones anteriores. [ 19 ]

Sanitizador de direcciones del kernel

El KernelAddressSanitizer ( KASan ) detecta errores de memoria dinámica en el kernel de Linux. [ 20 ] La instrumentación del kernel requiere una característica especial en el compilador que proporciona la -fsanitize=kernel-addressopción de línea de comandos, ya que los kernels no utilizan el mismo espacio de direcciones que los programas normales. [ 21 ] [ 22 ]

KASan también está disponible para su uso con controladores de kernel de Windows a partir de Windows 11 22H2 y versiones posteriores. [ 23 ] De manera similar a Linux, compilar un controlador de Windows con KASAN requiere pasar la /fsanitize=kernel-addressopción de línea de comandos al compilador MSVC.

Otros desinfectantes

Google también produjo LeakSanitizer (LSan, fugas de memoria ), ThreadSanitizer (TSan, condiciones de carrera y bloqueos mutuos ), MemorySanitizer (MSan, memoria no inicializada ) y UndefinedBehaviorSanitizer ( UBSan , comportamientos indefinidos , con control granular). [ 24 ] Estas herramientas están generalmente disponibles en Clang/LLVM y GCC. [ 25 ] [ 26 ] [ 27 ] De manera similar a KASan, existen versiones específicas del kernel de LSan, MSan, TSan, así como sanitizadores de kernel completamente originales como KFENCE y KCSan. [ 28 ]

Las herramientas de saneamiento adicionales (agrupadas por compiladores bajo -fsanitize o una bandera similar) incluyen: [ 25 ] [ 26 ] [ 27 ]

  • Integridad del flujo de control de LLVM y su contraparte en el kernel, que verifica las tablas virtuales y las conversiones de tipo para CFI de borde directo.
  • MemTagSanitizer, una herramienta similar a ASan que utiliza características de Armv8.5-A para una sobrecarga muy baja.
  • ShadowCallStack, una herramienta AArch64 que proporciona protección de pila de sombras
  • Scudo Hardened Allocator, un asignador de memoria alternativo que incluye GWP-ASan, un análogo probabilístico de ASan con baja sobrecarga [ 29 ]
  • libFuzzer, una herramienta LLVM que agrega cobertura de código al fuzzing [ 30 ]

Uso

Un sanitizador de código detecta comportamientos sospechosos mientras se ejecuta el programa. Una forma común de usar un sanitizador es combinarlo con fuzzing , que genera entradas que probablemente desencadenen errores. [ 31 ]

Usuarios

Los desarrolladores de Chromium y Firefox son usuarios activos de AddressSanitizer; [ 31 ] [ 32 ] la herramienta ha encontrado cientos de errores en estos navegadores web. [ 33 ] Se encontraron varios errores en FFmpeg [ 34 ] y FreeType . [ 35 ] El kernel de Linux ha habilitado AddressSanitizer para la arquitectura x86-64 a partir de la versión 4.0 de Linux.

Ejemplos

ASan: Uso de montón después de la liberación

// Para compilar: g++ -O -g -fsanitize=address heap-use-after-free.ccint main ( int argc , char ** argv ) {int * array = nuevo int [ 100 ];eliminar [] matriz ;return array [ argc ]; // ¡BOOM!}
$ ./a.out ==5587==ERROR: AddressSanitizer: uso de montón después de liberar en la dirección 0x61400000fe44 en pc 0x47b55f bp 0x7ffc36b28200 sp 0x7ffc36b281f8 LECTURA de tamaño 4 en 0x61400000fe44 hilo T0 #0 0x47b55e en main /home/test/example_UseAfterFree.cc:5 #1 0x7f15cfe71b14 en __libc_start_main (/lib64/libc.so.6+0x21b14) #2 0x47b44c en _start (/root/a.out+0x47b44c) 0x61400000fe44 se encuentra 4 bytes dentro de la región de 400 bytes [0x61400000fe40,0x61400000ffd0) liberado por el hilo T0 aquí: #0 0x465da9 en el operador delete[](void*) (/root/a.out+0x465da9) #1 0x47b529 en main /home/test/example_UseAfterFree.cc:4 previamente asignado por el hilo T0 aquí: #0 0x465aa9 en el operador new[](unsigned long) (/root/a.out+0x465aa9) #1 0x47b51e en main /home/test/example_UseAfterFree.cc:3 RESUMEN: AddressSanitizer: heap-use-after-free /home/test/example_UseAfterFree.cc:5 main Bytes de sombra alrededor de la dirección con errores: [...] 0x0c287fff9fb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x0c287fff9fc0: fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd 0x0c287fff9fd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd [...] Leyenda de bytes de sombra (un byte de sombra representa 8 bytes de la aplicación): Direccionable: 00 Parcialmente direccionable: 01 02 03 04 05 06 07 Montón a la izquierda de la zona roja: fa Zona roja derecha: fb Región de montón liberada: fd Zona roja izquierda de la pila: f1 Apila en la zona roja central: f2 Zona roja de la pila derecha: f3 Zona roja parcial de pila: f4 Pila después del retorno: f5 Uso de la pila después del ámbito: f8 Zona roja global: f9 Orden de inicialización global: f6 Envenenado por el usuario: f7 ASan interno: fe ==5587==ABORTANDO 

ASan: Desbordamiento del búfer de montón

// EJECUTAR: clang++ -O -g -fsanitize=address heap-buf-of.cc && ./a.outint main ( int argc , char ** argv ) {int * array = nuevo int [ 100 ];matriz [ 0 ] = 0 ;int res = array [ argc + 100 ]; // ¡BOOM!eliminar [] matriz ;devolver res ;}
==25372==ERROR: AddressSanitizer: desbordamiento del búfer del montón en la dirección 0x61400000ffd4 en pc 0x0000004ddb59 bp 0x7fffea6005a0 sp 0x7fffea600598 LECTURA de tamaño 4 en 0x61400000ffd4 hilo T0 #0 0x46bfee en main /tmp/main.cpp:4:13 0x61400000ffd4 se encuentra 4 bytes a la derecha de la región de 400 bytes [0x61400000fe40,0x61400000ffd0) asignado por el hilo T0 aquí: #0 0x4536e1 en el operador delete[](void*) #1 0x46bfb9 en main /tmp/main.cpp:2:16 

ASan: Desbordamiento de búfer de pila

// EJECUTAR: clang -O -g -fsanitize=address stack-buf-of.cc && ./a.outint main ( int argc , char ** argv ) {int pila_array [ 100 ];pila_array [ 1 ] = 0 ;return stack_array [ argc + 100 ]; // ¡BOOM!}
==7405==ERROR: AddressSanitizer: desbordamiento de búfer de pila en la dirección 0x7fff64740634 en pc 0x46c103 bp 0x7fff64740470 sp 0x7fff64740468 LECTURA de tamaño 4 en 0x7fff64740634 hilo T0 #0 0x46c102 en main /tmp/example_StackOutOfBounds.cc:5 La dirección 0x7fff64740634 se encuentra en la pila del hilo T0 en el desplazamiento 436 del marco. #0 0x46bfaf en main /tmp/example_StackOutOfBounds.cc:2 Este marco tiene 1 objeto(s): [32, 432) 'stack_array' <== El acceso a la memoria en el desplazamiento 436 desborda esta variable 

ASan: Desbordamiento de búfer global

// EJECUTAR: clang -O -g -fsanitize=address global-buf-of.cc && ./a.out int global_array [ 100 ] = { -1 }; int main ( int argc , char ** argv ) { return global_array [ argc + 100 ]; // ¡BOOM! }
==7455==ERROR: AddressSanitizer: desbordamiento de búfer global en la dirección 0x000000689b54 en pc 0x46bfd8 bp 0x7fff515e5ba0 sp 0x7fff515e5b98 LECTURA de tamaño 4 en 0x000000689b54 hilo T0 #0 0x46bfd7 en main /tmp/example_GlobalOutOfBounds.cc:4 0x000000689b54 se encuentra 4 bytes a la derecha de Variable global 'global_array' de 'example_GlobalOutOfBounds.cc' (0x6899c0) de tamaño 400 

UBSan: desreferenciación de nullptr

// EJECUTAR: g++ -O -g -fsanitize=null null-dereference.c && ./a.out int main ( int argc , char ** argv ) { const char * ptr = nullptr ; return * ptr ; // BOOM }
null-dereference.c:4:10: error en tiempo de ejecución: carga de puntero nulo de tipo 'const char' Error de segmentación (volcado de memoria) 

Véase también

Referencias

  1. ^ Cho et al. 2024 , pág. 3742.
  2. ^ Austin, Breach y Sohi 1994 .
  3. Necula et al. 2005 .
  4. Nagarakatte et al. 2009 .
  5. Serebryany et al. 2012 .
  6. Lee et al. 2015 .
  7. Stepanov y Serebryany 2015 .
  8. Younan 2015 .
  9. van der Kouwe, Nigade y Giuffrida 2017 .
  10. Song et al. 2019 .
  11. "Notas de la versión LLVM 3.1" . LLVM . Consultado el 8 de febrero de 2014 .
  12. "Notas de la versión 4.8 de GCC" . GCC . Consultado el 8 de febrero de 2014 .
  13. "Desinfectante de direcciones | Documentación para desarrolladores de Apple" .
  14. "Notas de la versión 16.9 de Visual Studio 2019" . Microsoft . Consultado el 5 de marzo de 2021 .
  15. Konstantin Serebryany; Derek Bruening; Alexander Potapenko; Dmitry Vyukov. "AddressSanitizer: un verificador rápido de integridad de direcciones" (PDF) . Actas de la conferencia USENIX de 2012 sobre la Conferencia Técnica Anual .
  16. "Documentación de diseño de AddressSanitizer asistido por hardware — Documentación de Clang 17.0.0git" . clang.llvm.org .
  17. "MemorySanitizer" . GitHub .
  18. "ComparisonOfMemoryTools" . Wiki de AddressSanitizer . Consultado el 1 de diciembre de 2017 .
  19. "Cómo eludir AddressSanitizer" (PDF) . Eric Wimberley . Consultado el 1 de julio de 2014 .
  20. "KernelAddressSanitizer (KASAN)" . Archivado del original el 15 de septiembre de 2015.
  21. Jake Edge. "El sanitizador de direcciones del kernel" .
  22. Jonathan Corbet. "3.20 merge window parte 2" .
  23. "Sanitizador de direcciones del kernel (KASAN)" . Archivado del original el 4 de noviembre de 2024.
  24. Google (2 de marzo de 2023). "sanitizers: Este proyecto alberga Sanitizers: AddressSanitizer, MemorySanitizer, ThreadSanitizer, LeakSanitizer y más" . GitHub . Google.{{cite web}}: |last1=tiene nombre genérico ( ayuda )
  25. 1 2 "sanitizer - The Rust Unstable Book" . doc.rust-lang.org . Esta característica permite el uso de uno de los siguientes sanitizadores: [...] ControlFlowIntegrity LLVM Control Flow Integrity
  26. 1 2 "Manual del usuario del compilador Clang — Documentación de Clang 17.0.0git" . clang.llvm.org . -f[no-]sanitize=check1,check2,... Activa las comprobaciones en tiempo de ejecución para diversas formas de comportamiento indefinido o sospechoso
  27. 1 2 "Opciones de instrumentación (Uso de la colección de compiladores GNU (GCC))" . gcc.gnu.org .
  28. "Linux Kernel Sanitizers" . Google. 2 de marzo de 2023.
  29. "GWP-ASan — Documentación de LLVM 17.0.0git" . llvm.org .
  30. "libFuzzer: una biblioteca para pruebas de fuzzing guiadas por cobertura. — Documentación de LLVM 17.0.0git" . llvm.org .
  31. 1 2 Abhishek Arya; Cris Neckar; Equipo de seguridad de Chrome. "Fuzzing para la seguridad" .
  32. "Protegiendo Firefox: Probando nuevas técnicas de análisis de código" . Archivado del original el 7 de marzo de 2016. Consultado el 18 de junio de 2018 .
  33. "Algunos de los errores encontrados por AddressSanitizer" . GitHub .
  34. Mateusz Jurczyk; Gynvael Coldwind (10 de enero de 2014). "FFmpeg y mil correcciones" . Blog técnico de J00Ru-Vx .
  35. "Resultados de búsqueda de AddressSanitizer en FreeType Bugs" .

Fuentes

  • Cho, Kyuwon; Kim, Jongyoon; Duy, Kha Dinh; Lim, Hajeong; Lee, Hojoon (agosto de 2024). «RustSan: Adaptación de AddressSanitizer para una desinfección eficiente de Rust» . Actas del 33.er Simposio de Seguridad de USENIX . Filadelfia, PA, EE. UU.: USENIX Association. págs. 3729–3746 . ISBN  978-1-939133-44-1.
  • Austin, Todd M.; Breach, Scott E.; Sohi, Gurindar S. (junio de 1994). "Detección eficiente de todos los errores de acceso a punteros y matrices" . SIGPLAN Not . 29 (6): 290–301 .
  • Necula, George C.; Condit, Jeremy; Harren, Matthew; McPeak, Scott; Weimer, Westley (mayo de 2005). "Ccured: Adaptación segura de tipos de software heredado" (PDF) . ACM Trans. Program. Lang. Syst . 27 (3): 477– 526.
  • Nagarakatte, Santosh; Zhao, Jianzhou; Martin, Milo MK; Zdancewic, Steve (2009). "Softbound: Altamente compatible y completa seguridad de memoria espacial para C" (PDF) . Actas de la 30.ª Conferencia ACM SIGPLAN sobre Diseño e Implementación de Lenguajes de Programación . págs. 245–258 . 
  • Serebryany, Konstantin; Bruening, Derek; Potapenko, Alexander; Vyukov, Dmitriy (2012). "AddressSanitizer: Un verificador rápido de integridad de direcciones" . Conferencia Técnica Anual USENIX 2012. págs. 309–318 . 
  • Lee, Byoungyoung; Song, Chengyu; Jang, Yeongjin; Wang, Tielei (2015). "Prevención del uso después de la liberación con la anulación de punteros colgantes" . NDSS .
  • Stepanov, Evgeniy; Serebryany, Konstantin (2015). "Memorysanitizer: detector rápido del uso de memoria no inicializada en C++" . Simposio Internacional IEEE/ACM de 2015 sobre Generación y Optimización de Código . págs. 46–55 . 
  • Younan, Yves (2015). "Freesentry: protección contra vulnerabilidades de uso después de la liberación debido a punteros colgantes" . 22º Simposio Anual de Seguridad de Redes y Sistemas Distribuidos .
  • van der Kouwe, Erik; Nigade, Vinod; Giuffrida, Cristiano (2017). "Dangsan: Detección escalable de uso después de la liberación" . Actas de la Duodécima Conferencia Europea sobre Sistemas Informáticos . págs. 405–419 . 
  • Song, Dokyung; Lettner, Julian; Rajasekaran, Prabhu; Na, Yeoul (2019). "Sok: Sanitizing for security" (PDF) . Simposio IEEE de 2019 sobre seguridad y privacidad . págs. 1275–1295 . 
  • Grupo de Google AddressSanitizer (sin lista de correo)
  • Página del proyecto AddressSanitizer
  • Documentación de AddressSanitizer (Clang)