Versions Compared

Key

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

...

In this example, sensitive information stored in the dynamically allocated memory referenced by secret is copied to the dynamically allocated buffer, new_secret, which is processed and eventually deallocated by a call to free(). Because the memory is not cleared, it may be reallocated to another section of the program where the information stored in new_secret may be unintentionally linkedleaked.

Code Block
bgColor#FFcccc
...
char *new_secret;
size_t size = strlen(secret);
if (size == SIZE_MAX) {
  /* Handle Error */
}

new_secret = malloc(size+1);
if (!new_secret) {
  /* Handle Error */
}
strcpy(new_secret, secret);

/* Process new_secret... */

free(new_secret);
...

...

Wiki Markup
The {{calloc()}} function is used in this example to ensureensures that the newly allocated memory has also be cleared. Because {{sizeof(char)}} is guaranteed to be 1, this solution does not need to check for a numeric overflow as a result of using {{calloc()}} \[[MEM37-C | MEM37-C. Ensure that size arguments to calloc() do not result in an integer overflow]\].

...

Wiki Markup
Using {{realloc()}} to resize dynamic memory may inadvertently expose sensitive information, or allow heap inspection as is described in Fortify's Taxonomy of Software Security Errors \[[vulncat|http://vulncat.fortifysoftware.com/2/HI.html]\] and NIST's Source Code Analysis Tool Functional Specification \[[SAMATE|http://samate.nist.gov/docs/SAMATE_source_code_analysis_tool_spec_09_15_06.pdf]\]. When {{realloc()}} is called it may allocate a new, larger object, copy the contents, of {{secret}} to this new object, {{free()}} the original object, and assign the newly allocated object to {{secret}}. However, the contents of the original object may remain in memory.

Code Block
bgColor#FFcccc

...
...
size_t secret_size, new_secret_size;
...
if (secret_size > SIZE_MAX/2) {
   /* handle error condition */
}

secret = realloc(secret, newsecret_size * 2);
...

Wiki Markup
A test is added at the beginning of this code to make sure that the integer multplication does not result in an integer overflow \[[INT32-C|INT32-C. Ensure that integer operations do not result in an overflow]\]. 

Compliant Solution: realloc()

A compliant program cannot rely on realloc() because it is not possible to clear the memory prior to the call.
Instead, a custom function that operates similar to realloc(), but sanitizes sensitive information as heap-based buffers are resized. Again, this is done by overwriting the space to be deallocated with '\0' characters.

Code Block
bgColor#ccccff

...
size_t secret_size, new_secret_size;
...
if (secret_size > SIZE_MAX/2) {
   /* handle error condition */
}

temp_buff = calloc(secret_size * 2, sizeof(char)); /* calloc() initializes memory to zero */
if (temp_buff == NULL) {
 /* Handle Error */
}

memcpy(temp_buff, secret, secret_size);
memset(secret, '\0', secret_size);         /* sanitize the buffer */

free(secret);
secret = temp_buff;                      /* install the resized buffer */
temp_buff = NULL;
...

Wiki Markup
NoteThe {{calloc()}} function ensures that thisthe solutionnewly mayallocated truncatememory thehas contentsalso ofbe the original buffer,cleared. Because {{secretsizeof(char)}} is guaranteed to be 1, this ifsolution thedoes sizenot ofneed theto resizedcheck bufferfor isa smaller.numeric Thisoverflow behavioras isa similarresult toof howusing {{realloccalloc()}} handles resizing to a smaller block of memory \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999\[[MEM37-C | MEM37-C. Ensure that size arguments to calloc() do not result in an integer overflow]\].

Risk Assessment

Failure to clear dynamic memory can result in leaked information.

...