You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 33 Next »

Freeing memory that is not allocated dynamically can lead to serious errors. The specific consequences of this error depend on the compiler, but they range from nothing to abnormal program termination. Regardless of the compiler, avoid calling free() on non-dynamic memory.

A similar situation arises when realloc() is supplied a pointer to non-dynamically allocated memory. The realloc() function is used to resize a block of dynamic memory. If realloc() is supplied a pointer to memory not allocated by a memory allocation function, such as malloc(), the program may terminate abnormally.

Non-Compliant Code Example

This piece of code validates the number of command line arguments. If the correct number of commmand line arguments have been specified, the requested amount of memory is validated to ensure that it is an acceptable size, and the memory is allocated with malloc(). Next, the second command line argument is copied into str for further processing. Once this processing is complete, str is freed. However, if the incorrect number of arguments have been specified, str is set to a string literal and printed. Because str now references memory that was not dynamically allocated, an error will occur when str memory is freed.

#define MAX_ALLOCATION 1000

int main(int argc, char *argv[]) {
  char *str = NULL;
  size_t len;

  if (argc == 2) {
    len = strlen(argv[1])+1;
    if (len > MAX_ALLOCATION) {
      /* Handle Error */
    }
    str = malloc(len);
    if (str == NULL) {
      /* Handle Allocation Error */
    }
    strcpy(str,argv[1]);
  }
  else {
    str = "usage: $>a.exe [string]";
    printf("%s\n", str);
  }
  /* ... */
  free(str);
  return 0;
}

Compliant Solution

In the compliant solution, the program has been changed to eliminate the possibility of str referencing non-dynamic memory when it is supplied to free().

#define MAX_ALLOCATION 1000

int main(int argc, char *argv[]) {
  char *str = NULL;
  size_t len;

  if (argc == 2) {
    len = strlen(argv[1])+1;
    if (len > MAX_ALLOCATION) {
      /* Handle Error */
    }
    str = malloc(len);
    if (str == NULL) {
      /* Handle Allocation Error */
    }
    strcpy(str, argv[1]);
  }
  else {
    printf("%s\n", "usage: $>a.exe [string]");
    return -1;
  }
  /* ... */
  free(str);
  return 0;
}

Risk Assessment

Freeing or reallocating memory that was not dynamically allocated could lead to abnormal termination and denial-of-service attacks.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MEM34-C

1 (high)

3 (likely)

2 (high)

P6

L1

Examples of vulnerabilities resulting from the violation of this rule can be found on the CERTwebsite.

References

[[ISO/IEC 9899-1999]] Section 7.20.3, "Memory management functions"
[[Seacord 05]] Chapter 4, "Dynamic Memory Management"

  • No labels