Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding "Buffer Security Check /GS" compiler option in MSVC++

I was recently surprised to note that compiling with /GS (Enable buffer security check) in MSVC++ 2010 seems to have a non-negligible effect on run-time performance in some cases. Has anyone else had this experience??

For a large scientific-style application (a mesh generation library) it seems that compiling with /GS- can lead to almost 10% improvements in run-time for several of the large benchmarks in my test suite ("large" being >= 1 second worth of run-time). /GS is on by default at all levels of optimisation in MSVC++ 2010.

I must admit that I'd never paid too much attention to this option before, and I'm wanting a bit of clarification as to what it actually does. The online documentation seems to talk extensively about string buffers, but since I don't use string or char[] buffers anywhere I must be missing something.

This paragraph (from the online doc) seems to indicate that the performance degradation I'm seeing is a bit unusual:

A performance tradeoff for using security checks in an application must be made. The Visual C++ compiler team focused on making the performance degradation small. In most cases, the performance should not degrade more than 2 percent. In fact, experience has shown that most applications, including high-performance server applications, have not noticed any performance impact.

Of course I can just turn it off, and get faster code, but I want to understand the implications before I do that.

like image 403
Darren Engwirda Avatar asked Jul 07 '11 07:07

Darren Engwirda


2 Answers

I've had the same experience as you: /GS- leading to ~10% improvements in runtime. I've shared some benchmarks on my blog: The Cost of Buffer Security Checks in Visual C++

When /GS is enabled (which is the default for the VC++ Release configuration), it seems anytime you create a C-style array as a local variable, the compiler will insert a few extra instructions to ensure the 4 bytes following the array on the stack have not been modified. As you've noticed, it doesn't seem to matter if it's a char array, or an array of another type. I guess the idea behind this compiler option is that any stack buffer overflow could be exploited by hackers, regardless of type.

But if you’re developing a Visual C++ application which is not a network service, and you’re striving for maximum performance, such as in a game, editor, or benchmarking tool — and it’s unlikely to be targeted by hackers — then I'd suggest to go ahead and disable this option.

like image 81
preshing Avatar answered Oct 12 '22 12:10

preshing


/GS adds code that tries to detect if a write overrun or similar stack attack has happend during a function, and to stop execution after a write overrun. The patterns that it aims to find are ones that have been seen in real-world attacks. There are a bunch of real world security bulletins that would not have happened if today's /GS had been in use at the time.

In this case a write overrun can happen on structures, arrays and various other entities. Changes and improvements to /GS are made in each version of VS. More /GS protection generally has cost, although in some cases newer VS may have learnt how to do the same protection cheaper.

I'd recommend leaving /GS on unless your code doesn't ship to others - generally the protection is worth the cost; at most you might choose to disable it for specific functions where there is no risk and high impact - just as you might hand-optimise the most critical parts of your program in other ways.

Martyn

like image 32
Martyn Lovell Avatar answered Oct 12 '22 13:10

Martyn Lovell