CWE-690, Unchecked Return Value to NULL Pointer Dereference, is what happens when a program calls a function that can return NULL when it fails, does not check, and then uses the result. The crash that follows is a NULL pointer dereference.
MITRE's extended description notes that unchecked return values are not limited to NULL, but that functions often return NULL to signal an error, which makes this a common special case. Platforms listed are memory-unsafe languages such as C and C++, but the same shape appears in Java as a NullPointerException.
How it happens
MITRE gives a short Java example. The code calls getUserName() and dereferences the result without checking:
// Vulnerable: username may be null
String username = getUserName();
if (username.equals(ADMIN_USER)) {
// ...
}
Its C example takes a user supplied address, checks the form, and looks up the hostname:
// Vulnerable: gethostbyaddr can return NULL
validate_addr_form(user_supplied_addr);
addr = inet_addr(user_supplied_addr);
hp = gethostbyaddr(addr, sizeof(struct in_addr), AF_INET);
strcpy(hostname, hp->h_name);
If an attacker supplies an address that is well formed but does not resolve to a hostname, gethostbyaddr() returns NULL, and the strcpy dereferences it. MITRE adds that this code also has a buffer overflow, since strcpy copies into a 64 byte buffer with no limit.
Real examples from the record:
- CVE-2008-1052: a large Content-Length value leads to a NULL pointer dereference when malloc fails.
- CVE-2006-6227: a large message length field leads to a NULL pointer dereference when malloc fails.
- CVE-2006-2555: a parsing routine hits a NULL dereference when input is missing a colon separator.
- CVE-2003-1054: a URI parsing API sets an argument to NULL on parse failure, such as a Referer header missing a hostname, leading to a NULL dereference.
Notice how often the trigger is attacker controlled input, such as a header value or a length field.
What an attacker gains
Usually a crash. MITRE lists denial of service through crash, exit or restart. For a server that handles many users, one malformed request that kills the process is enough to take it down repeatedly.
MITRE also notes a rare case: where NULL is equivalent to address 0x0 and privileged code can access it, reading or writing memory becomes possible, which may lead to code execution. That is uncommon, but it is why this is not only a reliability issue.
How to find it
MITRE is candid about the difficulty. The bug sits in rarely triggered error conditions, which lowers the chance of detection by black box testing. White box analysis needs knowledge of which library functions can return NULL, so unfamiliar libraries are easy to miss. MITRE recommends automated dynamic analysis with tools integrated at compile time that insert runtime error checking for memory safety errors.
Practical checks:
- Grep for allocation and lookup calls whose results are used on the next line.
- Run your parsers against truncated, empty and oversized inputs.
- Use fault injection to make
mallocand lookups fail, then watch for crashes.
How to fix it
MITRE's record lists no formal mitigation text for this entry, but the cause makes the fix plain: check the return value before use, and decide what the failure path does.
// Fixed: check, bound the copy, fail cleanly
hp = gethostbyaddr(&addr, sizeof(struct in_addr), AF_INET);
if (hp == NULL) {
return -1;
}
snprintf(hostname, sizeof hostname, "%s", hp->h_name);
// Fixed: handle the null explicitly
String username = getUserName();
if (ADMIN_USER.equals(username)) {
// ...
}
Also validate lengths from the wire before allocating. A huge declared length that makes malloc fail should produce an error response, not a crash.
Try it yourself
Click through it at your own pace, or open it full screen.
Quick check
Why does black box testing often miss this?
Because the NULL return happens in rarely triggered error conditions that ordinary test inputs do not produce.
Is this always only a denial of service?
Usually, yes. MITRE notes that in rare cases, when NULL is the 0x0 address and privileged code can access it, memory reads and writes may be possible.