Compiler Security Enhancements in Visual Studio 11

Compiler Security Enhancements in Visual Studio 11

Rate This
  • Comments 12

Hello all – Dave here…

In chatting with our colleagues in the MSEC Security Science Team, there were a number of interesting topics that weren’t covered in our previous Code Analysis blog post – information that would help contribute to the understanding of security features and functionality in Visual Studio 11.  So after some discussion, we have decided to release a series of posts covering this important work – everyone benefits from a better understanding of future technology offerings.

So with that, I again turn the blog over to Tim Burrell to elaborate!

_______________________________________

(Note – this blog post describes a feature in an unreleased product; this feature may be changed prior to final product release.)

Microsoft is actively developing Visual Studio 11 and continually looking for ways to improve security-related functionality. As part of this we are updating the /GS compiler switch, which is on-by-default and enables a basic level of code generation security features, with some enhancements beyond the now familiar cookie-based stack overflow protection. We’ll provide some more detail on these in a later post.

The Security Development Lifecycle (SDL) includes a number of recommendations beyond the scope of /GS where the compiler is able to assist secure software development. These range from specific code generation features such as using strict_gs_check to security-related compiler warnings and more general recommendations to initialize or sanitize pointers appropriately.

For the first time we intend to provide a central mechanism for enabling such additional security support via a new /sdl switch. The impact of /sdl is twofold:

-          /sdl causes SDL mandatory compiler warnings to be treated as errors during compilation.

-          /sdl enables additional code generation features such as increasing the scope of stack buffer overrun protection and initialization or sanitization of pointers in a limited set of well-defined scenarios.

This dual approach reflects our conviction that secure software is best achieved by the combination of detecting and fixing code bugs during the development process together with the deployment of security mitigations that will significantly increase the difficulty of exploiting any residual bugs.

The /sdl compiler switch is disabled by default, and can be enabled easily in the Visual Studio UI by opening the Property Pages for the current project, and accessing the Configuration Properties -> C/C++ -> General options.


So what does the /sdl switch do?

The features enabled by the /sdl switch are a superset of those enabled by /GS i.e. enabling /sdl enables everything included in /GS. We will be providing more background and in-depth details of the additional /GS and /sdl features in future posts. For now we note that they include:

The following SDL mandatory compiler warnings are enabled and treated as errors:

Warning

Command line switch

Description

C4146

/we4146

A unary minus operator was applied to an unsigned type, resulting in an unsigned result

C4308

/we4308

A negative integral constant converted to unsigned type, resulting in a possibly meaningless result

C4532

/we4532

Use of “continue”, “break” or “goto” keywords in a __finally/finally block has undefined behavior during abnormal termination

C4533

/we4533

Code initializing a variable will not be executed

C4700

/we4700

Use of an uninitialized local variable

C4789

/we4789

Buffer overrun when specific C run-time (CRT) functions are used

C4995

/we4995

Use of a function marked with pragma deprecated

C4996

/we4996

Use of a function marked as deprecated

 

If a developer wishes to opt in to most of the /sdl functionality but exclude a given warning ID (suppose C4146 for example) then this can be achieved by using the /wd switch to disable that specific warning under C/C++ -> Command Line -> Additional Options in the Visual Studio UI:

  • ·         The strict_gs_check pragma  is applied to all C/C++ code compiled with /sdl. This instructs the compiler to consider more functions as potential candidates for stack buffer overflow protection. The GS optimization introduced in Visual Studio 2010 has been improved to work better in conjunction with strict_gs_check, specifically enabling many of the extra security checks resulting from strict_gs_check to be proven unnecessary and removed.

Additional /sdl code generation features will be covered in more detail in later posts.

Microsoft strongly recommends using the /GS switch as in previous Visual Studio releases; the new /sdl switch in Visual Studio 11 presents an opportunity for greater security coverage both during and after development: stay tuned for more details on specific security benefits of using /GS and /sdl in Visual Studio 11.

Of course the Security Development Lifecycle (SDL) is an entire process and methodology for developing secure software and as such includes much more than just using specific compiler switches – read more and find additional resources related to SDL here.

Tim Burrell, MSEC security science.

Comments
  • Why not treat it as a breaking-change-but-still-a-Good-Thing and have it on by default in new projects, but unchanged in legacy projects? and possibly prompt to turn it on when moving to the new version?

  • I suggest that you give the /sdl switch a version number, like /sdl:11 .  Then, when VS12 comes out, people can upgrade to the new compiler without having to disable /sdl until they can get all the new-to-VS12 sdl warnings cleaned up.  Then they can bump the switch up to /sdl:12 .

  • Yet another nice thing in the VC11 compiler, that we can't use for years...

    The reason, why we can't use it? Well just take a look at: connect.microsoft.com/.../690617

  • The /sdl compiler switch is disabled by default. Is there specific reason for this?

  • Yet another feature that breaks ANSI C / POSIX compatibility.

  • you lost The Goal.

  • Squizzle and Jangid - We are considering the final default settings and keeping these under review, in particular for new code. Note that we are making some updates to the on-by-default /GS behavior: more of that in a later post. We need to balance how much additional new on-by-default behavior we introduce in a single release.

  • Jeffrey - We are monitoring the feedback on new switch names, so thank you. There has been feedback in the past about the number of switches in general and number of security switches in particular being too great, hence the principle of a ‘one-stop shop’ for compiler security. I agree that we need to take care how we update that switch in future releases – though for warnings specifically the post above highlights how one can selectively disable one or two problematic warnings while keeping the remaining benefits of /sdl. We’ll be expanding on these shortly.

  • Consider a compiler switch to set pointers to null after they are free'd or disposed of.  This should have been in the C/C++ language many years ago.

  • Tom - Thanks for the comment.

    The Security Development Lifecycle (SDL) recommends doing something similar to this – for example note the following from SDL 5.1:

    • NULL out free'd memory pointers in new code. This helps reduce the severity of double-free bugs and bugs that overwrite "dangling" pointers. For example:

    char *p = new char[N];

    ...

    delete [] p;

    Add this statement after the delete operator:

    p = NULL;

    The same process applies to any dynamic allocation and freeing pattern (for example, using malloc/free, GlobalAlloc/GlobalFree, or VirtuaAlloc/VirtualFree).

    A common approach that we’ve seen developers take is to define macros such as

    #define SAFE_DELETE(p)      if( NULL != p ) { delete p; p = NULL; }

    #define SAFE_ARRAYDELETE(p) if( NULL != p ) { delete [] p; p = NULL; }

    and use these in their code in preference to calling the deallocating function directly.

    However, as the comment points out, it’s always good to get the development tools to support such recommendations where possible rather than the onus being on the developer; indeed we have been looking at something similar to this: it’s not trivial to do this in a way that might not break valid C++ code constructs – we intend to provide more detail in a later post in this series… stay tuned!

  • Please add detection and warning on a free/dispose of memory that does not have setting the pointer to NULL in the same code block.  A better method would be to allow free/dispose release the memory and also set the pointer to null in a single operation (abet non-standard language extension).

  • "NULL out free'd memory pointers in new code. This helps reduce the severity of double-free bugs and bugs that overwrite "dangling" pointers"

    Ouch. This (1) converts immediate failure into armed bomb going off later at unrelated place and time, and (2) greatly increases the complexity of the code, thus increasing the likelihood of other bugs. It's also just extremely annoying when library writers follow such advice, such as for the OpenCV library where you can't just release a pointer value, but have to have on hand a variable.

    Adding complexity is NOT the way to get things simple and robust.

    It would be nice if those designing the tools knew how to use them, like, know how to drive a car before designing one.

Page 1 of 1 (12 items)
Leave a Comment
  • Please add 5 and 2 and type the answer here:
  • Post