CWE
Home > CWE List > CWE-170 Individual Dictionary Definition (Draft 9)   View the CWE List

CWE-170 Individual Dictionary Definition (Draft 9)

Improper Null Termination
Weakness ID
Status: Incomplete

170 (Weakness Base)

Description

Summary

The software does not properly terminate a string or array with a null character or equivalent terminator. Null termination errors frequently occur in two different ways. An off-by-one error could cause a null to be written out of bounds, leading to an overflow. Or, a program could use a strncpy() function call incorrectly, which prevents a null terminator from being added at all. Other scenarios are possible.

Likelihood of Exploit

High

Potential Mitigations

If performance constraints permit, special code can be added that validates null-termination of string buffers, this is a rather naïve and error-prone solution.

Switch to bounded string manipulation functions. Inspect buffer lengths involved in the buffer overrun trace reported with the defect.

Add code that fills buffers with nulls (however, the length of buffers still needs to be inspected, to ensure that the non null-terminated string is not written at the physical end of the buffer).

Demonstrative
Examples

Example 1: The following code reads from cfgfile and copies the input into inputbuf using strcpy(). The code mistakenly assumes that inputbuf will always contain a NULL terminator.

#define MAXLEN 1024
...
char *pathbuf[MAXLEN];
...
read(cfgfile,inputbuf,MAXLEN); //does not null terminate
strcpy(pathbuf,input_buf); //requires null terminated input
...

The code in Example 1 will behave correctly if the data read from cfgfile is null terminated on disk as expected. But if an attacker is able to modify this input so that it does not contain the expected NULL character, the call to strcpy() will continue copying from memory until it encounters an arbitrary NULL character. This will likely overflow the destination buffer and, if the attacker can control the contents of memory immediately following inputbuf, can leave the application susceptible to a buffer overflow attack.


Example 2: In the following code, readlink() expands the name of a symbolic link stored in the buffer path so that the buffer filename contains the absolute path of the file referenced by the symbolic link. The length of the resulting value is then calculated using strlen().

...
char buf[MAXPATH];
...
readlink(path, buf, MAXPATH);
int length = strlen(filename);
...

The code in Example 2 will not behave correctly because the value read into buf by readlink() will not be null terminated. In testing, vulnerabilities like this one might not be caught because the unused contents of buf and the memory immediately following it may be NULL, thereby causing strlen() to appear as if it is behaving correctly. However, in the wild strlen() will continue traversing memory until it encounters an arbitrary NULL character on the stack, which results in a value of length that is much larger than the size of buf and may cause a buffer overflow in subsequent uses of this value. Buffer overflows aside, whenever a single call to readlink() returns the same value that has been passed to its third argument, it is impossible to know whether the name is precisely that many bytes long, or whether readlink() has truncated the name to avoid overrunning the buffer. Traditionally, strings are represented as a region of memory containing data terminated with a NULL character. Older string-handling methods frequently rely on this NULL character to determine the length of the string. If a buffer that does not contain a NULL terminator is passed to one of these functions, the function will read past the end of the buffer. Malicious users typically exploit this type of vulnerability by injecting data with unexpected size or content into the application. They may provide the malicious input either directly as input to the program or indirectly by modifying application resources, such as configuration files. In the event that an attacker causes the application to read beyond the bounds of a buffer, the attacker may be able use a resulting buffer overflow to inject and execute arbitrary code on the system.

Observed Examples
ReferenceDescription
CVE-2000-0312Attacker does not null-terminate argv[] when invoking another program.
CVE-2003-0777Interrupted step causes resultant lack of null termination.
CVE-2004-1072Fault causes resultant lack of null termination, leading to buffer expansion.
CVE-2001-1389Multiple vulnerabilities related to improper null termination.
CVE-2003-0143Product does not null terminate a message buffer after snprintf-like call, leading to overflow.
Context Notes

Conceptually, this does not just apply to the C language; any language or representation that involves a terminator could have this sort of problem.

Factors: this is usually resultant from other weaknesses such as off-by-one errors, but it can be primary to boundary condition violations such as buffer overflows. In buffer overflows, it can act as an expander for assumed-immutable data.

Overlaps missing input terminator.

Relationships
NatureTypeIDName
ChildOfCategoryCategory169Technology-Specific Special Elements
CanPrecedeCompound Element: CompositeCompound Element: Composite120Unbounded Transfer ('Classic Buffer Overflow')
CanAlsoBeWeakness VariantWeakness VariantWeakness Variant147Failure to Sanitize Input Terminators
ChildOfViewView630
CanFollowWeakness BaseWeakness BaseWeakness Base193Off-by-one Error
Source Taxonomies

PLOVER - Improper Null Termination

7 Pernicious Kingdoms - String Termination Error

Applicable Platforms

C

C++

White Box Definition


A weakness where the code path has:
1.        end statement that passes a data item to a null-terminated string function
2.        start statement that removes the null-terminator from the data item

Where “removes” is defined through the following scenarios:
1.        data item never ended with null-terminator
2.        null-terminator is re-written
3.        null-terminator was purposely removed from data item

Page Last Updated: April 21, 2008