Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This clause gives compilers the leeway to remove code deemed unused or unneeded when building a program. While this is usually beneficial, sometimes the compiler removes code that it thinks is not needed but which that has been added with security in mind. An example of this is overwriting the memory of a buffer that is used to store sensitive data. As a result, care must always be taken when dealing with sensitive data to ensure that operations on it always execute as intended.

...

Some compiler optimization modes may remove code sections if the optimizer determines that doing so will not alter the behavior of the program. In this non-compliant code example, optimization may remove the call to memset() (which the programmer had hoped would clear sensitive memory) to be removed because the variable is not accessed following the write. Check compiler documentation for information about this compiler-specific behavior and which optimization levels can cause this behavior to occur.

...

A call to ZeroMemory() may be optimized out in a similar manner as a call to memset().

...

The #pragma directives in this compliant solution instructs instruct the compiler to avoid optimizing the enclosed code. This #pragma directive is supported on some versions of Microsoft Visual Studio , and may be supported on other compilers. Check compiler documentation to ensure its availability and its optimization guarantees.

...

This compliant solution uses the volatile type qualifier to inform the compiler that the memory should be overwritten and that the call to the memset_s() function should not be optimized out. Unfortunately, this compliant solution may not be as efficient as possible due to the nature of the volatile type qualifier preventing the compiler from optimizing the code at all. Typically, some compilers are smart enough to replace calls to memset() with equivalent assembly instructions which that are much more efficient than the memset() implementation. Implementing a memset_s() function as below shown in the example may prevent the compiler from using the optimal assembly instructions and may result in less efficient code. Check compiler documentation and the assembly output from the compiler.

...

If the compiler optimizes out memory-clearing code, an attacker could gain access to sensitive data.

...

Wiki Markup
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.7.3, "Type qualifiers"
\[[US-CERT|https://buildsecurityin.us-cert.gov/daisy/bsi-rules/home/g1/771.html]\], "MEMSET"
\[[MSDN|AA. C References#MSDN]\], "[SecureZeroMemory|http://msdn.microsoft.com/en-us/library/aa366877.aspx]"
\[[MSDN|AA. C References#MSDN]\], "[Optimize (C/C++)|http://msdn.microsoft.com/en-us/library/chh3fb0k(VS.80).aspx]"
\[[Wheeler 03|AA. C References#Wheeler 03]\] [Section 11.4|http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/protect-secrets.html]\], "SecureSpecially ProgrammingProtect forSecrets Linux(Passwords and Unix HOWTO". Section 11.4.Keys) in User Memory"

...

MSC05-A. Do not manipulate time_t typed values directly      13. Miscellaneous (MSC)       MSC07-A. Detect and remove dead code