...
In this noncompliant code example, sensitive information is supposedly stored in the dynamically allocated buffer, secret
, which is processed and eventually deallocated cleared by a call to freememset_s()
. The memory page containing secret
can be swapped out to disk. If the program crashes before the call to freememset_s()
completes, the information stored in secret
may be stored in the core dump.
Code Block | ||||
---|---|---|---|---|
| ||||
char *secret;
secret = (char *)malloc(size+1);
if (!secret) {
/* Handle error */
}
/* Perform operations using secret... */
memset_s(secret, '\0', size+1);
free(secret);
secret = NULL;
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <sys/resource.h>
/* ... */
struct rlimit limit;
limit.rlim_cur = 0;
limit.rlim_max = 0;
if (setrlimit(RLIMIT_CORE, &limit) != 0) {
/* Handle error */
}
char *secret;
secret = (char *)malloc(size+1);
if (!secret) {
/* Handle error */
}
/* Perform operations using secret... */
memset_s(secret, '\0', size+1);
free(secret);
secret = NULL;
|
...
Processes with elevated privileges can disable paging by locking memory in place using the POSIX mlock()
function [Open Group 2004IEEE Std 1003.1:2013]. Disabling paging ensures that memory is never copied to the hard drive, where it may be retained indefinitely in nonvolatile storage.
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <sys/resource.h>
/* ... */
struct rlimit limit;
limit.rlim_cur = 0;
limit.rlim_max = 0;
if (setrlimit(RLIMIT_CORE, &limit) != 0) {
/* Handle error */
}
long pagesize = sysconf(_SC_PAGESIZE);
if (pagesize == -1) {
/* Handle error */
}
char *secret_buf;
char *secret;
secret_buf = (char *)malloc(size+1+pagesize);
if (!secret_buf) {
/* Handle error */
}
/* mlock() may require that address be a multiple of PAGESIZE */
secret = (char *)((((intptr_t)secret_buf + pagesize - 1) / pagesize) * pagesize);
if (mlock(secret, size+1) != 0) {
/* Handle error */
}
/* Perform operations using secret... */
if (munlock(secret, size+1) != 0) {
/* Handle error */
}
secret = NULL;
memset_s(secret_buf, '\0', size+1+pagesize);
free(secret_buf);
secret_buf = NULL;
|
...
Writing sensitive data to disk preserves it for future retrieval by an attacker, who may even be able to bypass the access restrictions of the operating system by using a disk maintenance program.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MEM06-C | Medium | Unlikely | High | P2 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Polyspace Bug Finder |
| Checks for sensitive data printed out (rec. partially covered) |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C++ |
Coding Standard | VOID MEM06-CPP. Ensure that sensitive data is not written out to disk |
ISO/IEC TR 24772:2013 | Memory Locking [XZX] |
MITRE CWE | CWE-591, Sensitive data storage in improperly locked memory CWE-528, Information leak through core dump files |
Bibliography
[ |
IEEE Std 1003.1:2013] | XSH, System Interface, mlock |
XSH, System Interface, setrlimit |
[Wheeler 2003] | Section 7.14 Section 11.4 |
...
...