Buffer overflow from possible non null-terminated string

In C and C++, a C string, or a null-terminated string, is a character sequence terminated with a null character (\0). The length of a C string is found by searching for the null character.

The NNTS family of checkers looks for code that uses string manipulation functions with character arrays that are not or may not be null terminated. The NNTS.MIGHT checker looks for code using string manipulation functions in which required information can't be evaluated, such as an argument with an unknown character length.

Vulnerability and risk

The null termination has historically created security problems. For example:

  • a null character inserted into a string can truncate it unexpectedly
  • it's a common bug not to allocate enough space for the null character or to forget the null
  • many programs don't check the length before copying a string to a fixed-size buffer, causing a buffer overflow when it's too long
  • the inability to store a null character means that string and binary data needs to be handled by different functions, which can cause problems if the wrong function is used

Mitigation and prevention

To avoid the problem:

  • add special code to validate null termination of string buffers if performance constraints permit
  • switch to bounded-string manipulation functions like strncpy
  • inspect buffer lengths involved in the buffer overrun traceback

Vulnerable code example

1  int nnts_m_m_2(char * src)
2  { 
3      char buf[8];
4      char tgt[1024];
6      strncpy(buf, src, 3);
7      strcpy(tgt, buf);
8      return 0;
9  }

Klocwork produces a NNTS.MIGHT buffer overflow issue report at line 7 in this example. The character length of the parameter 'src' isn't known, and if the string length of 'src' is equal to or greater than three, the call to strncpy at line 6 will write only three characters to 'buf'. If the stack memory where 'buf' is allocated doesn't have a null termination in it, the call at line 7 will access arrays outside their bounds. If there is a null termination in 'buf', strcpy may still copy uninitialized data into the 'tgt' buffer. This code could possibly result in a buffer overflow, which can cause various significant security problems.

Klocwork would have produced an NNTS.MUST issue report if the character length of 'src' had been known to be equal to or greater than three.

Fixed code example

1  int nnts_m_m_2(char * src)
2  { 
3      char buf[8];
4      char tgt[1024];
6      strncpy(buf, src, 3);
7      // ensure null termination
8      buf[3] = '\0';
9      strcpy(tgt, buf);
10     return 0;
11 }

In the fixed example, a null terminating character is explicitly added to 'buf' on line 8. Since 'buf' could no longer be a non null-terminated string, the issue has been avoided on line 9.

Security training

Application security training materials provided by Secure Code Warrior.


This checker can be extended. See Tuning C/C++ analysis for more information.