Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

...

The gets() function is inherently unsafe, and should never be used as it provides no way to control how much data is read into a buffer from stdin. These two lines of code assume that gets() will not read more than BUFSIZ - 1 characters from stdin. This is an invalid assumption and the resulting operation can cause a buffer overflow. Again note that BUFSIZ is a macro from <cstdio> and does not represent the maximum size of an input buffer.

Wiki MarkupAccording to Section 7.19.7.7 of C99 \ [[ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\], the {{gets()}} function reads characters from the {{stdin}} into a destination array until end-of-file is encountered or a new-line character is read. Any new-line character is discarded, and a null character is written immediately after the last character read into the array.

Code Block
bgColor#FFCCCC
langcpp
char buf[BUFSIZ];
if (gets(buf) == NULL) {
  /* Handle Error */
}

...

The gets_s() function reads at most one less than the number of characters specified from the stream pointed to by stdin into an array.

Wiki MarkupAccording to TR 24731 \ [[ISO/IEC TR 24731-2006|AA. Bibliography#ISO/IEC TR 24731-2006]\]: <blockquote><p>No

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.

...

...

Code Block
bgColor#ccccff
langcpp
char buf[BUFFERSIZE];

if (gets_s(buf, sizeof(buf)) == NULL) {
  /* handle error */
}

Noncompliant Code Example ( scanf() )

...

Code Block
bgColor#ffcccc
langcpp
char buf_one[12];
char buf_two[12];
cin.width(12);
cin >> buf_one;
cin >> buf_two;

...

In this example, the first read won't overflow, but the second still could, because as the C+\+ standard states : "operator>> extracts characters and stores them into successive locations of an array \ [...\] operator>> then calls width(0)." Which means that width should be called every time you use the >> operator with a bounded array.

Non-compliant solution 2 (operator<<())

...

Code Block
bgColor#ffcccc
langcpp
char buf_one[12];
char buf_two[12];
cin.width(12);
cin >> buf_one;
cin.width(12);
cin >> buf_two;

...

because, as the C+\+ standard states, "If width() is greater than zero, n is width() \ [...\] n-1 characters are stored \ [...\] Operator>> then stores a null byte (charT()) in the next position, which may be the first position if no characters were extracted." The input could therefore be truncated, leading to information lost, and to a possible vulnerability.
In this particular example, if the user enters a string longer than 11 (11 characters + the NULL terminating character automatically appended by the >> operator equals 12 characters), the 12th and all subsequent characters will be lost.

Compliant solution (operator<<())

...

This rule appears in the C Secure Coding Standard as STR35-C. Do not copy data from an unbounded source to a fixed-length array.

Bibliography

...

\[[Drepper 06|AA. Bibliography#Drepper 06]\] Section 2.1.1, "Respecting Memory Bounds" \[
[ISO/IEC 14882-2003|AA. Bibliography#ISO/IEC 14882-2003] \] Sections 3.6.1 Main function, and 18.7 Other runtime support \
[[ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\] Section 7.19, "Input/output <{{stdio.h}}>" \
[[ISO/IEC TR 24731-2006|AA. Bibliography#ISO/IEC TR 24731-2006] \] Section 6.5.4.1, "The {{gets_s}} function" \[
[Lai 06|AA. Bibliography#Lai 06]\] \[[MITRE 07|AA. Bibliography#MITRE 07]\] [CWE ID 120|http://cwe.mitre.org/data/definitions/120.html], "Unbounded Transfer ('Classic Buffer Overflow')" \[[NIST 06|AA. Bibliography#NIST 06]\] SAMATE Reference Dataset Test Case ID ]
[MITRE 07] CWE ID 120, "Unbounded Transfer ('Classic Buffer Overflow')"
[NIST 06] SAMATE Reference Dataset Test Case ID 000-000-088 \[
[Seacord 05a|AA. Bibliography#Seacord 05]\] Chapter 2, "Strings"

...

STR34-CPP. Cast characters to unsigned types before converting to larger integer sizes      07. Characters and Strings (STR)      STR36-CPP. Do not specify the bound of a character array initialized with a string literal