Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Copying data to a buffer that is not large enough to hold that data results in a buffer overflow. Buffer overflows occur frequently when manipulating strings [Seacord 2013b]. To prevent such errors, either limit copies through truncation or, preferably, ensure that the destination is of sufficient size to hold the character data to be copied and the null-termination character. (see See STR03-C. Do not inadvertently truncate a string.).

When strings live on the heap, this rule is a specific instance of MEM35-C. Allocate sufficient memory for an object. Because strings are represented as arrays of characters, this rule is related to both ARR30-C. Do not form or use out-of-bounds pointers or array subscripts and ARR38-C. Guarantee that library functions do not form invalid pointers.

...

The C Standard, Annex K [ISO/IEC 9899:2011], states:

No additional characters are read after a new-line character (which is discarded) or after end-of-file. The discarded new-line character does not count towards number of characters read. A null character is written immediately after the last character read into the array.

...

The getline() function is similar to the fgets() function but can dynamically allocate memory for the input buffer. If passed a null pointer, getline() dynamically allocates a buffer of sufficient size to hold the input. If passed a pointer to dynamically allocated storage that is too small to hold the contents of the string, the getline() function resizes the buffer, using realloc(), rather than truncating the input. If successful, the getline() function returns the number of characters read, which can be used to determine if the input has any null characters before the newline. The getline() function works only with dynamically allocated buffers. Allocated memory must be explicitly deallocated by the caller to avoid memory leaks. (see See MEM31-C. Free dynamically allocated memory when no longer needed.).

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
void func(void) {
  int ch;
  size_t buffer_size = 32;
  char *buffer = malloc(buffer_size);
 
  if (!buffer) {
    /* Handle error */
    return;
  }

  if ((ssize_t size = getline(&buffer, &buffer_size, stdin))
        == -1) {
    /* Handle error */
  } else {
    char *p = strchr(buffer, '\n');
    if (p) {
      *p = '\0';
    } else {
      /* Newline not found; flush stdin to end of line */
      while ((ch = getchar()) != '\n' && ch != EOF)
	    ;
	  if (ch == EOF && !feof(stdin) && !ferror(stdin)) {
         /* Character resembles EOF; handle error */
      }
    }
  }
  free (buffer);
}

...

The strcpy_s() function provides additional safeguards, including accepting the size of the destination buffer as an additional argument. (see See STR07-C. Use the bounds-checking interfaces for string manipulation.).

Code Block
bgColor#ccccff
langc
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdlib.h>
#include <string.h>
 
int main(int argc, char *argv[]) {
  /* Ensure argv[0] is not null */
  const char *const name = (argc && argv[0]) ? argv[0] : "";
  char *prog_name;
  size_t prog_size;

  prog_size = strlen(name) + 1;
  prog_name = (char *)malloc(prog_size);

  if (prog_name != NULL) {
    if (strcpy_s(prog_name, prog_size, name)) {
      /* Handle  error */
    }
  } else {
    /* Handle error */
  }
  /* ... */
  free(prog_name);
  return 0;
}

...

According to the C Standard, 7.22.4.6 [ISO/IEC 9899:2011]:

The getenv function searches an environment list, provided by the host environment, for a string that matches the string pointed to by name. The set of environment names and the method for altering the environment list are implementation defined.

...

In this noncompliant code example, name refers to an external string; it could have originated from user input, from the file system, or from the network. The program constructs a file name from the string in preparation for opening the file.

...

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

STR31-C

High

Likely

Medium

P18

L1

Automated Detection

Array access out of bounds, Buffer overflow from incorrect string format specifier, Destination buffer overflow in string manipulation, Invalid use of standard library string routine, Missing null in string array, Pointer access out of bounds, Tainted NULL or non-null-terminated string, Use of dangerous standard function 

Tool

Version

Checker

Description

 
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

LANG.MEM.BO
LANG.MEM.TO
MISC.MEM.NTERM
BADFUNC.BO.*

Buffer overrun
Type overrun
No space for null terminator
A collection of warning classes that report uses of library functions prone to internal buffer overflows

 

Compass/ROSE

 

 

Can detect violations of the rule. However, it is unable to handle cases involving strcpy_s() or manual string copies such as the one in the first example

 
Coverity6.5

STRING_OVERFLOW
STRING_SIZE
SECURE_CODING

Fully implemented

 

Fortify SCA

5.0

 

 

 

Klocwork

Include Page
Klocwork_V
Klocwork_V

NNTS.TAINTED
SV.STRBO.GETS
SV.USAGERULES.UNBOUNDED_STRING_COPY

 

 

LDRA tool suite

Include Page
LDRA_V
LDRA_V

489 S, 109 D, 66 X, 70 X, 71 X

Partially implemented

 
Parasoft C/C++test9.5BD-PB-OVERFWR,SECURITY-12  
Polyspace Bug FinderR2016a Guarantee that storage for strings has sufficient space for character data and null terminator 

Splint

Include Page
Splint_V
Splint_V

 

 

 
PRQA QA-C
Include Page
PRQA QA-C_v
PRQA QA-C_v
warncall for 'gets'Partially implemented 

...