Static Analysis Problem Type Reference

SAL Writable Size Constraint Violation

A call to an SAL-annotated subroutine has violated a writable size constraint.

Microsoft has defined a standard source annotation language (SAL) that can describe constraints on legal argument values. This error indicates that the call in question violates one such constraint. Specifically, a constraint on the writable size of an output or inout parameter.

SAL can be used to indicate that a particular input pointer must point to a buffer of a certain size. The size can either be a constant or the value of another integer parameter, and may be expressed in elements or in bytes. The error message text identifies the parameter at fault, the expected size, and the actual size.

A writable size constraint violation indicates that the call will result in a bounds violation within the called routine. This could result in memory corruption because the storage after the end of the buffer would be overwritten. Replace the actual parameter with one that meets the requirements of the called routine.

SAL allows detection of this error even when the source of the called routine is not available for analysis. Note that the annotations themselves will appear on the declaration of the called routine, which is likely in an include file.

ID

Code Location

Description

1

Buffer overflow

The call site where the invalid argument was passed

Example

          
#include <malloc.h>
#include <sal.h>

// This annotation indicates that the second parameter expects a
// pointer to an array of characters whose size is the first parameter.
// Typically such a routine would use the first parameter
// as a loop bound as it loops over the elements of the array.
extern void annotated_function(int size, _Out_bytecount_(size) char* a);

int main(int argc, char **argv)
{
   char buff[3];
   char *p = buff;
   
   annotated_function(sizeof(buff) - 1, p); // good
   annotated_function(sizeof(buff), p);     // good
   annotated_function(sizeof(buff) + 1, p); // bad
   return (buff[0] + buff[1] + buff[2]);
}