
...
Code Block | ||||
---|---|---|---|---|
| ||||
void getPassword(void) {
char pwd[64];
if (retrievePassword(pwd, sizeof(pwd))) {
/* Checking of password, secure operations, etc. */
}
memset(pwd, 0, sizeof(pwd));
*(volatile char*)pwd= *(volatile char*)pwd;
}
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
void getPassword(void) { char pwd[64]; if (retrievePassword(pwd, sizeof(pwd))) { /* Checking of password, secure operations, etc. */ } #pragma optimize("", off) memset(pwd, 0, sizeof(pwd)); #pragma optimize("", on) } |
Compliant Solution (C99)
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 because of 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 that are much more efficient than the memset()
implementation. Implementing a memset_s()
function as shown in the example may prevent the compiler from using the optimal assembly instructions and can result in less efficient code. Check compiler documentation and the assembly output from the compiler.
Code Block | ||||
---|---|---|---|---|
| ||||
/* memset_s.c */ errno_t memset_s(void *v, rsize_t smax, int c, rsize_t n) { if (v == NULL) return EINVAL; if (smax > RSIZE_MAX) return EINVAL; if (n > smax) return EINVAL; volatile unsigned char *p = v; while (smax-- && n--) { *p++ = c; } return 0; } /* getPassword.c */ extern errno_t memset_s(void *v, rsize_t smax, int c, rsize_t n); void getPassword(void) { char pwd[64]; if (retrievePassword(pwd, sizeof(pwd))) { /* Checking of password, secure operations, etc. */ } if (memset_s(pwd, sizeof(pwd), 0, sizeof(pwd)) != 0) { /* Handle error */ } } |
...
However, note that both calling functions and accessing volatile
-qualified objects can still be optimized out (while maintaining strict conformance to the standard), so without a C-conforming implementation, this so this compliant solution still might not work in some cases.
Compliant Solution (C11)
The C Standard includes a The memset_s()
function . Subclause K.3.7.4.1, paragraph 4 [ISO/IEC 9899:2011], states:
Unlike
memset
, any call to thememset_s
function shall be evaluated strictly according to the rules of the abstract machine as described in (5.1.2.3). That is, any call to thememset_s
function shall assume that the memory indicated bys
andn
may be accessible in the future and thus must contain the values indicated byc
.
...
bgColor | #ccccff |
---|---|
lang | c |
...
introduced in C11 is the preferred solution (see the following solution for more information). If memset_s()
function is not yet available on your implementation, this compliant solution is the best alternative, and can be discarded once supported by your implementation.
Noncompliant Code Example
...
If the compiler optimizes out memory-clearing code, an attacker can gain access to sensitive data.
Recommendation | Severity | Likelihood | Detectable |
---|
Repairable | Priority | Level | |
---|---|---|---|
MSC06-C | Medium | Probable | Yes |
Yes |
P12 |
L1 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
CodeSonar |
| BADFUNC.MEMSET | Use of memset | ||||||
LDRA tool suite |
| 35 S, 57 S, 8 D, 65 D, 76 D, 105 D, I J, 3 J | Partially implemented | ||||||
Parasoft C/C++test |
| CERT_C-MSC06-a | Avoid calls to memory-setting functions that can be optimized out by the compiler | ||||||
PC-lint Plus |
| 586 | Assistance provided | ||||||
PVS-Studio |
| V597, V712, V1001 |
Related Guidelines
SEI CERT C++ |
Bibliography
[ISO/IEC 9899:2011] | Subclause 6.8.5, "Iteration Statements" Subclause K.3.7.4.1, "The memset_s Function" |
[MSDN] | "SecureZeroMemory" "Optimize (C/C++)" |
"Safe Clearing of Private Data" | |
[US-CERT] | "MEMSET" |
[Wheeler 2003] | Section 11.4, "Specially Protect Secrets (Passwords and Keys) in User Memory" |
...
...