¿Qué tan grande es una palabra canaria en Linux, típicamente?

38

Una canary word es una secuencia de bits colocada en el límite entre un búfer (como una pila) y controlar los datos en un programa, como una forma de detectar y reaccionar a los desbordamientos de búferes.

¿Cuántos bits de longitud tienen estos canarios en Linux, por lo general?

    
pregunta MR.X_XD 23.01.2017 - 00:38
fuente

3 respuestas

59

¡Vamos a probarlo! Aquí hay un programa de ejemplo muy simple.

int test(int a)
{
    return a;
}

Compílela con GCC e intercepte la compilación en la etapa de ensamblaje. (El indicador -S hará esto). Cambie el nombre del archivo de ensamblaje (para que no se sobrescriba) y compile nuevamente, esta vez también agregando los indicadores -fstack-protector-all y -mstack-protector-guard=global . La primera bandera permite apilar canarios para todas las funciones, la segunda selecciona un canario global en lugar de un hilo local. (El valor predeterminado de subprocesos locales es probablemente más útil en la práctica, pero el ensamblaje para la versión global es más fácil de entender).

Al comparar los dos archivos de ensamblaje generados, detectamos la siguiente adición (los comentarios son míos).

        movl %edi, -20(%rbp)                 ; save function parameter onto stack (unrelated to canary)
        movq __stack_chk_guard(%rip), %rax   ; load magic value into RAX register
        movq %rax, -8(%rbp)                  ; save RAX register onto stack (place the canary)
        movl -20(%rbp), %eax                 ; load function parameter into EAX register for return (unrelated to canary)
        movq -8(%rbp), %rcx                  ; load canary value into RCX register
        movq __stack_chk_guard(%rip), %rdx   ; load magic value into RDX register
        cmpq %rdx, %rcx                      ; compare canary value to expected value
        je .L3                               ; if they are the same, jump to label .L3 (continue)
        call __stack_chk_fail                ; otherwise (stack corruption detected), call the handler
.L3:
        leave

Podemos ver que el canario se maneja en los registros RAX, RCX y RDX que tienen 64 bits de ancho. (Sus homólogos de 32 bits se llamarían EAX, EBX y EDX. Las versiones de 16 bits se denominan AX, BX y CX. Las variantes de 8 bits AL, BL y CL.) Otra pista es que las operaciones para almacenar, cargar y comparar canary (MOVQ y CMPQ) tienen un sufijo 'Q' que identifica una instrucción de 64 bits. (Las instrucciones de 32 bits tienen un sufijo 'L', las instrucciones de 16 bits a 'W' y las versiones de 8 bits a 'B'.)

Por lo tanto, llegamos a la conclusión de que el canario es un valor de 64 bits, lo que tiene sentido en una arquitectura de 64 bits (x86_64 GNU / Linux en mi caso). Espero que siempre usen el tamaño de palabra nativo ya que tiene más sentido para mí. Puedes probar el mismo experimento en tus máquinas y ver lo que obtendrás.

    
respondido por el 5gon12eder 23.01.2017 - 01:21
fuente
24

Como puedo leer en esta página: Stack Smashing Protector

  

El canario de pila tiene un tamaño de palabra nativa y, si se elige al azar, un atacante tendrá que adivinar el valor correcto entre 2 ^ 32 o 2 ^ 64 combinaciones

    
respondido por el Fernando Sanchiz 23.01.2017 - 00:58
fuente
2

El número de bits utilizados debe ser igual al tamaño de palabra del procesador. Así que si tienes un procesador de 32 bits, su tamaño de palabra es de 32, por lo tanto, la palabra canaria tiene una longitud de 32 bits.

    
respondido por el async3 23.01.2017 - 17:17
fuente

Lea otras preguntas en las etiquetas