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 (GetPassword(pwd, sizeof(pwd))) {
    /* checkingChecking of password, secure operations, etc. */
  }
  memset(pwd, 0, sizeof(pwd));
}

...

Code Block
bgColor#FFCCCC
langc
void getPassword(void) {
  char pwd[64];
  if (retrievePassword(pwd, sizeof(pwd))) {
    /*checkingChecking of password, secure operations, etc. */
  }
  memset(pwd, 0, sizeof(pwd));
  *(volatile char*)pwd= *(volatile char*)pwd;
}

...

Code Block
bgColor#FFCCCC
langc
void getPassword(void) {
  char pwd[64];
  if (retrievePassword(pwd, sizeof(pwd))) {
    /* checkingChecking of password, secure operations, etc. */
  }
  ZeroMemory(pwd, sizeof(pwd));
}

...

Code Block
bgColor#ccccff
langc
void getPassword(void) {
  char pwd[64];
  if (retrievePassword(pwd, sizeof(pwd))) {
    /* checkingChecking of password, secure operations, etc. */
  }
  SecureZeroMemory(pwd, sizeof(pwd));
}

...

Code Block
bgColor#ccccff
langc
void getPassword(void) {
  char pwd[64];
  if (retrievePassword(pwd, sizeof(pwd))) {
    /* checkingChecking of password, secure operations, etc. */
  }
#pragma optimize("", off)
  memset(pwd, 0, sizeof(pwd));
#pragma optimize("", on)
}

...

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 Checking of password, secure operations, etc. */
  }
  if (memset_s(pwd, sizeof(pwd), 0, sizeof(pwd)) != 0) {
    /* Handle error */
  }
}

...

Code Block
bgColor#ccccff
langc
void getPassword(void) {
  char pwd[64];

  if (retrievePassword(pwd, sizeof(pwd))) {
     /* checkingChecking of password, secure operations, etc. */
  }
  memset_s(pwd, 0, sizeof(pwd));
}

...

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

Related Guidelines

...

...

...

...

Compiler removal of code to clear buffers

...

...

Bibliography

[ISO/IEC 9899:2011]Section K.3.7.4.1, "The memset_s

...

Function"
[

...

...

...

Protect Secrets (

...

Passwords and

...

Keys) in

...

User Memory"

 

...