It is possible, since freeing memory doesn't necessarily mean that it gets cleared.
For example, given the following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i, len = 20;
char *p = malloc(len);
strcpy(p, "this is a test!!");
printf("&p=%p, p=%s\n", &p, p);
for (i=0; i<len; i++) {
printf("%02x ", p[i]);
}
printf("\n");
free(p);
// undefined behavior below: dereferencing freed memory
printf("p=%s\n", p);
for (i=0; i<len; i++) {
printf("%02x ", p[i]);
}
printf("\n");
return 0;
}
My system outputs the following:
&p=0x7ffd24e08290, p=this is a test!!
74 68 69 73 20 69 73 20 61 20 74 65 73 74 21 21 00 00 00 00
p=
00 00 00 00 00 00 00 00 61 20 74 65 73 74 21 21 00 00 00 00
So if your program had a security flaw that allowed an attacker to take control of it, they could dump the contents of this freed memory and expose sensitive data.
For this reason, memory containing secret data should be wiped as soon as it is no longer needed. The naive approach to this would be to call memset
on the block of memory, however many compilers will optimize it out if it sees that the memory is no longer used after that point.
There is a function defined in the C standard called memset_s
which is guaranteed not to be optimized out, however not all implementations have it. You'll need to find some library call that will clear memory that won't me optimized out. Libraries like OpenSSL will do this for you when you call their cleanup routines (see this post as a example).