Export (0) Print
Expand All
Expand Minimize
7 out of 7 rated this helpful - Rate this topic

/GS (Buffer Security Check)

/GS

The /GS option detects some buffer overruns, which overwrite the return address — a common technique for exploiting code that does not enforce buffer size restrictions. This is achieved by injecting security checks into the compiled code.

/GS only attempts to detect direct buffer overruns into the return address.

Buffer overruns are more easily exploited on machines with calling conventions that pass the return address of function calls on the stack. For example, x86 uses calling conventions that pass the return address of function calls on the stack.

On functions that the compiler thinks might be subject to buffer overrun problems, the compiler will allocate space on the stack before the return address. On function entry, the allocated space is loaded with a security cookie that is computed once at module load. Then, on function exit, a compiler helper is called to make sure the cookie's value is still the same.

If the value is not the same, an overwrite of the return address has potentially occurred, and so an error will be reported and the process terminated.

Unless an alternative handler has been supplied with _set_security_error_handler, a message box alerting the user to a potential security problem will be displayed and ExitProcess called.

When statically linking to the CRT, each program image will have its own handler. When dynamic linking is used, every component will share a common handler.

/GS requires CRT startup code. This raises an issue with /GS when used to compile a DLL. The security cookie's expected value is reset by the CRT in the CRT_INIT function. If you have a function that is compiled with /GS (and thus has the security cookie) that in turn calls CRT_INIT, the expected security cookie value will change and the program will think that it has had a buffer overrun. The solutions are to:

  • Not use arrays in any functions that call (or end up calling) CRT_INIT, for example, use _alloca instead.
  • Let the CRT initialize normally. Don't specify your own entry point, use DllMain instead (and don't call CRT_INIT).

/GS is not supported with /clr.

/GS does not protect against all buffer overrun security attacks. For example, buffer overrun attacks are still possible by overwriting into the parameters area.

Even if you use /GS, you should strive to write secure code. That is, make sure that your code has no buffer overruns. /GS might protect your application from buffer overruns that do remain in your code.

To set this compiler option in the Visual Studio development environment

  1. Open the project's Property Pages dialog box. For details, see Setting Visual C++ Project Properties.
  2. Click the C/C++ folder.
  3. Click the Code Generation property page.
  4. Modify the Buffer Security Check property.

To set this compiler option programmatically

See BufferSecurityCheck Property.

Example

This sample overruns a buffer. It will display a message box and terminate the process when built with /GS.

#include <cstring>

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

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

See Also

Compiler Options | Setting Compiler Options

Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.