AddressSanitizer (o ASan ) es una herramienta de programación de código abierto que detecta errores de corrupción de memoria , como desbordamientos de búfer o accesos a un puntero colgante (use-after-free). AddressSanitizer se basa en la instrumentación del compilador y la memoria de sombra mapeada directamente . AddressSanitizer está actualmente implementado en Clang (a partir de la versión 3.1 [1] ), GCC (a partir de la versión 4.8 [2] ), Xcode (a partir de la versión 7.0 [3] ) y MSVC (ampliamente disponible a partir de la versión 16.9 [4] ). En promedio, la instrumentación aumenta el tiempo de procesamiento en aproximadamente un 73% y el uso de memoria en un 240%. [5]
Usuarios
Los desarrolladores de Chromium y Firefox son usuarios activos de AddressSanitizer; [6] [7] la herramienta ha encontrado cientos de errores en estos navegadores web. [8] Se encontraron varios errores en FFmpeg [9] y FreeType . [10] El kernel de Linux ha habilitado AddressSanitizer para la arquitectura x86-64 a partir de la versión 4.0 de Linux.
KernelAddressSanitizer
El KernelAddressSanitizer ( KASAN ) detecta errores de memoria dinámica en el núcleo de Linux. [11] La instrumentación del núcleo requiere una característica especial en el compilador que proporciona la -fsanitize=kernel-addressopción de línea de comandos, ya que los núcleos no utilizan el mismo espacio de direcciones que los programas normales. [12] [13]
Ejemplos de
Heap-use-after-free
// Para compilar: g ++ -O -g -fsanitize = address heap-use-after-free.ccint main ( int argc , char ** argv ) { int * matriz = nuevo int [ 100 ]; eliminar [] matriz ; return array [ argc ]; // BOOM}
$ ./a.out== 5587 == ERROR: AddressSanitizer: heap-use-after-free en la dirección 0x61400000fe44 en pc 0x47b55f bp 0x7ffc36b28200 sp 0x7ffc36b281f8LEER de tamaño 4 a 0x61400000fe44 rosca T0 # 0 0x47b55e en /home/test/example_UseAfterFree.cc:5 principal # 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 eliminar [] (void *) (/root/a.out+0x465da9) # 1 0x47b529 en /home/test/example_UseAfterFree.cc:4 principalpreviamente asignado por el hilo T0 aquí: # 0 0x465aa9 en el operador nuevo [] (largo sin firmar) (/root/a.out+0x465aa9) # 1 0x47b51e en /home/test/example_UseAfterFree.cc:3 principalRESUMEN: AddressSanitizer: heap-use-after-free /home/test/example_UseAfterFree.cc:5 principalBytes de sombra alrededor de la dirección del buggy: 0x0c287fff9f70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fff9f80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fff9f90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fff9fa0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fff9fb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa=> 0x0c287fff9fc0: fa fa 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 0x0c287fff9fe0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c287fff9ff0: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa 0x0c287fffa000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fffa010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa faLeyenda de bytes de sombra (un byte de sombra representa 8 bytes de aplicación): Direccionable: 00 Parcialmente direccionable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Región de montón liberada: fd Pila de zona roja izquierda: f1 Stack mid redzone: f2 Stack right redzone: f3 Apilar zona roja parcial: f4 Pila después de la devolución: f5 Uso de la pila después del alcance: f8 Zona roja global: f9 Orden de inicio global: f6 Envenenado por el usuario: f7 ASan interno: fe== 5587 == ABORTANDO
Heap-buffer-overflow
// EJECUTAR: clang ++ -O -g -fsanitize = dirección% t && ./a.outint main ( int argc , char ** argv ) { int * matriz = nuevo int [ 100 ]; matriz [ 0 ] = 0 ; int res = matriz [ argc + 100 ]; // BOOM eliminar [] matriz ; return res ;}
== 25372 == ERROR: AddressSanitizer: heap-buffer-overflow en la dirección 0x61400000ffd4 en pc 0x0000004ddb59 bp 0x7fffea6005a0 sp 0x7fffea600598LEER de tamaño 4 a 0x61400000ffd4 rosca T0 # 0 0x46bfee en /tmp/main.cpp:4:13 principal0x61400000ffd4 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 eliminar [] (nulo *) # 1 0x46bfb9 en /tmp/main.cpp:2:16 principal
Desbordamiento de búfer de pila
// EJECUTAR: clang -O -g -fsanitize = dirección% t && ./a.outint main ( int argc , char ** argv ) { int stack_array [ 100 ]; stack_array [ 1 ] = 0 ; return stack_array [ argc + 100 ]; // BOOM}
== 7405 == ERROR: AddressSanitizer: stack-buffer-overflow en la dirección 0x7fff64740634 en pc 0x46c103 bp 0x7fff64740470 sp 0x7fff64740468LEER de tamaño 4 a 0x7fff64740634 rosca T0 # 0 0x46c102 en el /tmp/example_StackOutOfBounds.cc:5 principalLa dirección 0x7fff64740634 está ubicada en la pila del hilo T0 en el desplazamiento 436 en el marco # 0 0x46bfaf en el /tmp/example_StackOutOfBounds.cc:2 principal Este marco tiene 1 objeto (s): [32, 432) 'stack_array' <== El acceso a la memoria en el desplazamiento 436 desborda esta variable
Desbordamiento de búfer global
// EJECUTAR: clang -O -g -fsanitize = dirección% t && ./a.out int global_array [ 100 ] = { -1 }; int main ( int argc , char ** argv ) { return global_array [ argc + 100 ]; // BOOM }
== 7455 == ERROR: AddressSanitizer: global-buffer-overflow en la dirección 0x000000689b54 en pc 0x46bfd8 bp 0x7fff515e5ba0 sp 0x7fff515e5b98LEER de tamaño 4 en 0x000000689b54 rosca T0 # 0 0x46bfd7 en /tmp/example_GlobalOutOfBounds.cc:4 principal0x000000689b54 se encuentra 4 bytes a la derecha de variable global 'global_array' de 'example_GlobalOutOfBounds.cc' (0x6899c0) de tamaño 400
Limitaciones
AddressSanitizer no detecta ninguna lectura de memoria no inicializada (pero esto es detectado por MemorySanitizer [14] ), y solo detecta algunos errores de uso después de retorno. [15] Tampoco es capaz de detectar todos los errores de corrupción de memoria arbitrarios, ni todos los errores de escritura arbitrarios debidos a subdesbordamientos / desbordamientos de enteros (cuando el entero con comportamiento indefinido se usa para calcular los desplazamientos de direcciones de memoria). Los búferes adyacentes en estructuras y clases no están protegidos contra el desbordamiento, en parte para evitar romper la compatibilidad con versiones anteriores. [dieciséis]
Ver también
- Intel MPX
- Verificador de aplicaciones (AppVerif.exe) en el SDK de Microsoft Windows
Referencias
- ^ "Notas de la versión LLVM 3.1" . LLVM . Consultado el 8 de febrero de 2014 .
- ^ "Notas de la versión 4.8 de GCC" . GCC . Consultado el 8 de febrero de 2014 .
- ^ "Address Sanitizer | Documentación para desarrolladores de Apple" .
- ^ "Notas de la versión 16.9 de Visual Studio 2019" . Microsoft . Consultado el 5 de marzo de 2021 .
- ^ Konstantin Serebryany; Derek Bruening; Alexander Potapenko; Dmitry Vyukov. "AddressSanitizer: un verificador de cordura de direcciones rápido" (PDF) . Actas de la conferencia USENIX de 2012 sobre la conferencia técnica anual .
- ^ Abhishek Arya; Cris Neckar; Equipo de seguridad de Chrome. "Fuzzing for Security" .
- ^ "Asegurar Firefox: probando nuevas técnicas de análisis de código" . Archivado desde el original el 7 de marzo de 2016 . Consultado el 18 de junio de 2018 .
- ^ "Algunos de los errores encontrados por AddressSanitizer" .
- ^ Mateusz Jurczyk; Gynvael Coldwind (10 de enero de 2014). "FFmpeg y mil arreglos" .
- ^ "Resultados de la búsqueda de AddressSanitizer en FreeType Bugs" .
- ^ "KernelAddressSanitizer (KASAN)" . Archivado desde el original el 15 de septiembre de 2015.
- ^ Jake Edge. "El desinfectante de direcciones del kernel" .
- ^ Jonathan Corbet. "3.20 parte 2 de la ventana de fusión" .
- ^ "MemorySanitizer" .
- ^ "ComparisonOfMemoryTools" . Wiki de AddressSanitizer . Consultado el 1 de diciembre de 2017 .
- ^ "Omitiendo AddressSanitizer" (PDF) . Eric Wimberley . Consultado el 1 de julio de 2014 .
enlaces externos
- AddressSanitizer Google Group (sin lista de correo)
- Página del proyecto AddressSanitizer
- Documentación de AddressSanitizer (Clang)