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 2013b2013]. 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. This rule is a C++-specific instance of STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator. C-style strings require a null character to indicate the end of the string, while the C++ std::basic_string template requires no such character.

Noncompliant Code Example

Since Because the input is unbounded, the following code could lead to a buffer overflow:.

Code Block
bgColor#FFcccc
langcpp
#include <iostream>
 
void f() {
  char buf[12];
  std::cin >> buf;
}

...

To solve this problem, it may be tempting to use the std::ios_base::width() method, but there still is a trap, as shown in this noncompliant code example. In .

Code Block
bgColor#ffcccc
langcpp
#include <iostream>
 
void f() {
  char bufOne[12];
  char bufTwo[12];
  std::cin.width(12);
  std::cin >> bufOne;
  std::cin >> bufTwo;
}

In this example, the first read won't will not overflow, but could fill bufOne with a truncated string. Furthermore, the second read still could overflow bufTwo. The C++ Standard, [istream.extractors], paragraphs 7-9 describe 7–9  [ISO/IEC 14882-2014], describes the behavior of of operator>>(basic_istream &, charT *) and, and states in part [ISO/IEC 14882-2014], states the following:

operator>> then stores a null byte (charT()) in the next position, which may be the first position if no characters were extracted. operator>> then calls  then calls width(0).

ThusConsequently, it is necessary to call call width() prior to each each operator>> call  call passing a bounded array.

Code Block
bgColor#ffcccc
langcpp
#include <iostream>
 
void f() {
  char buf_one[12];
  char buf_two[12];
  std::cin.width(12);
  std::cin >> buf_one;
  std::cin >> buf_two;
}

Noncompliant Code Example

The following noncompliant code example calls std::ios_base_width() prior to each call to operator>>(). However, it still . However, this does not account for the input being truncated. Only the first 11 characters are read from the standard input stream, and a null terminator is then appended. The input could therefore be truncated, leading , which may lead to information loss or a possible vulnerability.

...

...

#include <iostream>
 
void f() {
  char buf_one[12];
  char buf_two[12];
  std::cin.width(12);
  std::cin >> buf_one;
  std::cin.width(12);
  std::cin >> buf_two;
}

Compliant Solution

The best solution for ensuring that data is not truncated , and for guarding against buffer overflows are guarded against, is to use std::string instead of a bounded array, as in this compliant solution:.

Code Block
bgColor#ccccff
langcpp
#include <iostream>
#include <string>
 
void f() {
  std::string input;
  std::string string_onestringOne, string_twostringTwo;
  std::cin >> string_onestringOne >> string_twostringTwo;
}

Noncompliant Code Example

In this noncompliant example, the unformatted input function std::basic_istream<T>::read() is used to read an unformatted character array of 32 characters from the given file. However, the read() function does not guarantee that the string will be null terminated, so the subsequent call of of the std::string constructor results in undefined behavior if the character array does not contain a null terminator.

Code Block
bgColor#ffcccc
langcpp
#include <fstream>
#include <string>
 
void f(std::istream &in) {
  char buffer[32];
  try {
    in.read(buffer, 32sizeof(buffer));
  } catch (std::ios_base::failure &Ee) {
    // Handle error
  }
 
  std::string str(buffer);
  // ...
}

Compliant Solution

This compliant solution continues to assume assumes that the input from the file is exactly at most 32 characters and instead . Instead of inserting a null terminator, it constructs the std::string object based on the sizethe number of characters read from the input stream. If the size of the input is uncertain, it is better to use std::basic_istream<T>::readsome() or a formatted input function, depending on need.

Code Block
bgColor#ccccff
langcpp
#include <fstream>
#include <string>

void f(std::istream &in) {
  char buffer[32];
  try {
    in.read(buffer, 32sizeof(buffer));
  } catch (std::ios_base::failure &Ee) {
    // Handle error
  }
  std::string str(buffer, 32in.gcount());
  // ...
}

Risk Assessment

Copying string data to a buffer that is too small to hold that data results in a buffer overflow. Attackers can exploit this condition to execute arbitrary code with the permissions of the vulnerable process.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

STR35

STR50-CPP

High

Likely

Medium

P18

L1

Automated Detection

Tool

Version

Checker

Description

   

Astrée

Include Page
Astrée_V
Astrée_V

stream-input-char-array
Partially checked + soundly supported
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

MISC.MEM.NTERM

LANG.MEM.BO
LANG.MEM.TO

No space for null terminator

Buffer overrun
Type overrun

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

 C++5216

DF2835, DF2836, DF2839,


Klocwork
Include Page
Klocwork_V
Klocwork_V
NNTS.MIGHT
NNTS.TAINTED
NNTS.MUST
SV.UNBOUND_STRING_INPUT.CIN

LDRA tool suite
Include Page
LDRA_V
LDRA_V

489 S, 66 X, 70 X, 71 X

Partially implemented

Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_CPP-STR50-b
CERT_CPP-STR50-c
CERT_CPP-STR50-e
CERT_CPP-STR50-f
CERT_CPP-STR50-g

Avoid overflow due to reading a not zero terminated string
Avoid overflow when writing to a buffer
Prevent buffer overflows from tainted data
Avoid buffer write overflow from tainted data
Do not use the 'char' buffer to store input from 'std::cin'

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C++: STR50-CPP

Checks for:

  • Use of dangerous standard function
  • Missing null in string array
  • Buffer overflow from incorrect string format specifier
  • Destination buffer overflow in string manipulation
  • Insufficient destination buffer size

Rule partially covered.

RuleChecker
Include Page
RuleChecker_V
RuleChecker_V
stream-input-char-array
Partially checked
SonarQube C/C++ Plugin
Include Page
SonarQube C/C++ Plugin_V
SonarQube C/C++ Plugin_V
S3519
 

Related Vulnerabilities

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

Related Guidelines

Bibliography

[ISO/IEC 14882-2014]

Subclause 27.7.2.2.3, "basic_istream::operator>>"
Subclause 27.7.2.3, "Unformatted Input Functions" 

[Seacord
2013b
2013]Chapter 2, "Strings"

...


...

Image Modified Image Modified Image Modified