Michael here.

I have written about some of the security improvements in VC++ 2010 (here and here) and want to mention another important one: improved SAL support.

The Standard Annotation Language (SAL) is a way of annotating function prototypes to help static analysis tools find bugs, including many classes of security vulnerabilities, with a low false-positive rate.

If you are not familiar with SAL, declspec versus attribute syntax, and the use of macros to implement SAL, you should read this first.

The two biggest SAL changes in VC++ 2010 are:

  • More functions (C runtime headers and Windows headers) have SAL annotations
  • Most functions use attribute SAL syntax rather than declspec syntax

What this means to you as a C or C++ developer using VC++ 2010, is that the compiler and static analysis toolset (/analyze) will find more bugs in your code. And all you did was upgrade to the newer compiler!

On a slightly different, but related topic, the advent of macros for attribute SAL (as used in VC++ 2010) is a major milestone for SAL, because it means we are in a position to make SAL a requirement for the next version of the SDL. Presently, SAL is a recommendation, although larger Microsoft teams use SAL anyway. It's important to realize that we can't make anything a requirement in the SDL unless:

  • It goes through a thorough vetting and feedback period
  • It solves a real security problem
  • It's usable by software engineers

The SAL requirement is going through the feedback period right now.

Clearly SAL can help with the second point, because SAL can help pinpoint buffer overruns in C and C++ code.

The addition of attribute SAL macros in sal.h means the third point is addressed too. Telling developers to annotate code using low-level SAL constructs in this manner:

void Func(
  [SA_Pre  (Null=SA_No,ValidBytes="cb")]
  [SA_Pre(Deref=1,Access=SA_Read)] BYTE* pBuf, size_t cb );

Is simply not going to fly!

But asking developers to annotate their code using high-level SAL macros like this:

void Foo(          
    _In_bytecount_(cb) BYTE* pBuf,
    size_t cb );

Is acceptable.