/GS (Comprobación de seguridad del búfer)

Actualización: noviembre 2007

Detecta algunas saturaciones de búfer que sobrescriben la dirección de retorno, una técnica común para aprovechar código que no aplica restricciones de tamaño de búfer. Esto se logra mediante la inserción de comprobaciones de seguridad en el código compilado.

/GS[-]

Comentarios

De manera predeterminada, /GS está habilitada. Utilice /GS- si cree que su aplicación no se va a ver expuesta a ningún riesgo de seguridad.

Para obtener más información sobre /GS, vea Compiler Security Checks In Depth.

El compilador inserta las comprobaciones en funciones con búferes de cadena locales o, en x86, en funciones con control de excepciones. Un búfer de cadena se define como una matriz cuyo tamaño de elemento es de uno o dos bytes, y cuyo tamaño total es al menos de cinco bytes, o cualquier búfer asignado con _alloca.

En todas las plataformas, el compilador inserta una cookie para proteger la dirección de retorno de la función si ésta tiene búferes de cadena locales. Esta cookie se comprueba a la salida de la función, y durante el desenredo del marco en los sistemas operativos de 64 bits o en x86 en el caso de funciones con alguna forma de control de excepciones. En x86, el compilador también inserta una cookie para proteger la dirección del controlador de excepciones de la función. Esta cookie se comprueba durante el desenredo del marco.

/GS principalmente intenta detectar saturaciones directas de búfer en la dirección de retorno. Las saturaciones de búfer se utilizan con mayor facilidad en equipos con convenciones de llamada que almacenan la dirección de retorno de llamadas a funciones en la pila. Por ejemplo, x86 utiliza convenciones de llamada que almacenan la dirección de retorno de llamadas a funciones en la pila.

En las funciones que el compilador cree susceptibles de problemas de saturación de búfer, el compilador asigna espacio en la pila antes de la dirección de retorno. En la entrada de la función, se carga una cookie de seguridad en el espacio asignado, que se procesa una vez durante la carga del módulo. Después, a la salida de la función, se llama a una función auxiliar para asegurarse de que el valor de la cookie sigue siendo el mismo.

Si el valor no es el mismo, es posible que se haya sobrescrito la pila y el proceso simplemente finaliza. Antes de Visual C++ 2005, se mostraba un cuadro de diálogo en el que se informaba de la sobrescritura de la pila.

/GS también protege frente a parámetros vulnerables pasados en una función. Un parámetro vulnerable es un puntero, referencia de C++ o estructura C (del tipo POD de C++) que contiene un puntero, búfer de cadena o referencia de C++.

Un parámetro vulnerable se asigna antes de la cookie y las variables locales. Una saturación del búfer puede sobrescribir estos parámetros. El código de la función que utiliza estos parámetros puede conducir a un ataque antes de que se devuelva la función, evitando así la comprobación de seguridad. Para reducir este riesgo, el compilador realizará una copia de los parámetros vulnerables durante el prólogo de la función y los colocará bajo el área de almacenamiento de cualquier búfer.

El compilador no proporciona protección de seguridad para los parámetros vulnerables en las siguientes situaciones:

  • Funciones que no contienen un búfer.

  • Si no se habilitan las optimizaciones (/O (Opciones) (Optimizar código)).

  • Funciones con una lista de argumentos variable (...).

  • Funciones marcadas con naked (C++).

  • Funciones que contienen código de ensamblado en línea en la primera instrucción.

  • Si un parámetro sólo se utiliza de manera que sea poco probable que se pueda usar de forma malintencionada en caso de una saturación del búfer.

/GS requiere inicialización de la cookie de seguridad. Esta cookie se debe inicializar antes de cualquier función mediante las ejecuciones de las cookies. La cookie de seguridad se debe inicializar en la entrada a un archivo EXE o DLL. Esto se realiza automáticamente cuando se utilizan los puntos de entrada CRT predeterminados (mainCRTStartup, wmainCRTStartup, WinMainCRTStartup, wWinMainCRTStartup o _DllMainCRTStartup), pero debe realizarse manualmente, mediante una llamada a __security_init_cookie, si se utiliza un punto de entrada alternativo.

/GS se admite para funciones administradas al compilar con /clr (Compilación de Common Language Runtime).

/GS no protege frente a todos los ataques a la seguridad relacionados con la saturación del búfer. Por ejemplo, si tiene un búfer y un vtable en un objeto, la saturación del búfer podría dañar el vtable y permitir que ocurriera un ataque.

Aunque utilice /GS, debería esforzarse en escribir código seguro. Es decir, compruebe que el código no tiene saturaciones del búfer. /GS podría proteger la aplicación frente a saturaciones del búfer que no permanezcan en el código.

Para establecer esta opción del compilador en el entorno de desarrollo de Visual Studio

  1. Abra el cuadro de diálogo Páginas de propiedades del proyecto. Para obtener información detallada, vea Cómo: Abrir páginas de propiedades del proyecto.

  2. Haga clic en la carpeta C/C++.

  3. Haga clic en la página de propiedades Generación de código.

  4. Modifique la propiedad Comprobación de seguridad del búfer.

Para establecer esta opción del compilador mediante programación

Ejemplo

Este ejemplo satura un búfer, lo que hace que la aplicación falle en tiempo de ejecución.

// compile with: /c /W1
#include <cstring>
#include <stdlib.h>
#pragma warning(disable : 4996)   // for strcpy use

// Vulnerable function
void vulnerable(const char *str) {
   char buffer[10];
   strcpy(buffer, str); // overrun buffer !!!

   // use a secure CRT function to help prevent buffer overruns
   // truncate string to fit a 10 byte buffer
   // strncpy_s(buffer, _countof(buffer), str, _TRUNCATE);
}

int main() {
   // declare buffer that is bigger than expected
   char large_buffer[] = "This string is longer than 10 characters!!";
   vulnerable(large_buffer);
}

Vea también

Referencia

Opciones del compilador

Establecer las opciones del compilador