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

Compare with Current View Page History

« Previous Version 2 Next »

The return values for memory allocation routines indicate the failure or success of the allocation. According to C99, calloc(), malloc(), and realloc() return null pointers if the requested memory allocation fails [[ISO/IEC 9899:1999]]. Failure to detect and properly handle memory management errors can lead to unpredictable and unintended program behavior. As a result, it is necessary to check the final status of memory management routines and handle errors appropriately.

The following table shows the possible outcomes of the standard memory allocation functions.

Function

Successful Return

Error Return

malloc()

pointer to allocated space

null pointer

calloc()

pointer to allocated space

null pointer

realloc()

pointer to the new object

null pointer

Noncompliant Code Example

In this example, input_string is copied into dynamically allocated memory referenced by str. However, the result of malloc() is not checked before str is referenced. Consequently, if malloc() fails, the program abnormally terminates.

char *input_string;

/* initialize input_string */

size_t size = strlen(input_string) + 1;
char *str = (char *)malloc(size);
strcpy(str, input_string);
/* ... */
free(str);
str = NULL;

Compliant Solution

The malloc() function as well as the other memory allocation functions, returns either a null pointer or a pointer to the allocated space. Always test the returned pointer to ensure it is not NULL before referencing the pointer. Handle the error condition appropriately when the returned pointer is NULL.

char *input_string;

/* initialize input_string */

size_t size = strlen(input_string) + 1;
char *str = (char *)malloc(size);
if (str == NULL) {
  /* Handle allocation error */
}
else {
  strcpy(str, input_string);
  /* ... */
  free(str);
  str = NULL;

Noncompliant Code Example

This noncompliant code example calls realloc() to resize the memory referred to by p. However, if realloc() fails, it returns a null pointer. Consequently, the connection between the original block of memory and p is severed, resulting in a memory leak.

void *p;
size_t new_size;

/* initialize new_size */

p = realloc(p, new_size);
if (p == NULL)   {
 /* Handle error */
}

When using realloc(), it is important to account for zero-byte allocations (see MEM04-CPP. Do not perform zero length allocations).

Compliant Solution

In this compliant solution, the result of realloc() is assigned to the temporary pointer q and validated before assigning it to the original pointer p.

void *p;
void *q;
size_t new_size;

/* initialize new_size */

q = realloc(p, new_size);
if (q == NULL)   {
 /* Handle error */
}
else {
  p = q;
}

Risk Assessment

Failing to detect allocation failures can lead to abnormal program termination and denial-of-service attacks.

If the vulnerable program references memory offset from the return value, an attacker can exploit the program to read or write arbitrary memory. This has been used to execute arbitrary code [VU#159523].

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MEM32-CPP

high

likely

medium

P18

L1

Automated Detection

Fortify SCA Version 5.0 can detect violations of this rule.

Compass/ROSE can detect violations of this rule. In particular, it ensures that variables are compared to NULL before being used, as in EXP34-CPP. Ensure a null pointer is not dereferenced.

Related Vulnerabilities

The vulnerability in Adobe Flash [[VU#159523]] arises because Flash neglects to check the return value from calloc(). Even though calloc() returns NULL, Flash does not attempt to read or write to the return value, but rather attempts to write to an offset from the return value. Dereferencing NULL usually results in a program crash, but dereferencing an offset from NULL allows an exploit to succeed without crashing the program.

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

Other Languages

This rule appears in the C Secure Coding Standard as MEM32-C. Detect and handle memory allocation errors.

References

[[ISO/IEC 9899:1999]] Section 7.20.3, "Memory management functions"
[[MITRE 07]] CWE ID 476, "NULL Pointer Dereference," and CWE ID 252, "Unchecked Return Value"
[[Seacord 05]] Chapter 4, "Dynamic Memory Management"
[[VU#159523]]


MEM31-CPP. Free dynamically allocated memory exactly once      08. Memory Management (MEM)      MEM33-CPP. Use the correct syntax for flexible array members

  • No labels