Versions Compared

Key

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

...

Code Block
bgColor#FFCCCC
langc
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
bgColor#ccccff
langc
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
bgColor#ccccff
langc
/* 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 the memset_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 the memset_s function shall assume that the memory indicated by s and n may be accessible in the future and thus must contain the values indicated by c.

...

bgColor#ccccff
langc

...

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

Remediation Cost

Repairable

Priority

Level

MSC06-C

Medium

Probable

Yes

Medium

Yes

P8

P12

L2

L1

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Automated Detection

ToolVersionCheckerDescription
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V
BADFUNC.MEMSETUse of memset
LDRA tool suite
Include Page
LDRA_V
LDRA_V
35 S, 57 S, 8 D,
65 D, 76 D, 105 D,
I J, 3 J
Partially implemented
Parasoft C/C++test

Include Page
Parasoft_V
Parasoft_V

CERT_C-MSC06-aAvoid calls to memory-setting functions that can be optimized out by the compiler
PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

586

Assistance provided

PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V597, V712, V1001

Related Guidelines

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++)"

[PVS-Studio]

"Safe Clearing of Private Data"
[US-CERT]"MEMSET"
[Wheeler 2003]Section 11.4, "Specially Protect Secrets (Passwords and Keys) in User Memory"

...


...

Image Modified Image Modified Image Modified