Errors can occur when assumptions are made about the type of data being read. These assumptions may be violated, for example, when binary data has been read from a file instead of text from a user's terminal.
Non-Compliant Code Example
This non-compliant code example attempts to remove the trailing newline (\n
) from an input line. The fgets()
function is typically used to read a newline-terminated line of input from a stream. It takes a size parameter for the destination buffer and copies, at most, size-1
characters from a stream to a string.
char buf[BUFSIZ + 1]; if (fgets(buf, sizeof(buf), fp) == NULL) { /* handle error */ } buf[strlen(buf) - 1] = '\0';
The strlen()
function computes the length of a string by determining the number of characters that precede the terminating null character. A problem occurs if the first character read from the input by fgets()
is a null character. This may occur, for example, if a binary data file is read by the fgets()
call [[Lai 06]]. If the first character in buf
is a null character, strlen(buf)
will return 0 and a write-outside-array-bounds error will occur.
Compliant Solution
This compliant solution uses strchr()
to replace the newline character in the string, if it exists (see FIO36-C. Do not assume a newline character is read when using fgets()).
char buf[BUFSIZ + 1]; char *p; if (fgets(buf, sizeof(buf), fp)) { p = strchr(buf, '\n'); if (p) { *p = '\0'; } } else { /* handle error condition */ }
Risk Assessment
Assuming character data has been read can result in out-of-bounds memory writes.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
FIO37-C |
high |
unlikely |
medium |
P6 |
L2 |
Automated Detection
Fortify SCA Version 5.0 is able to detect violations of this rule.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[ISO/IEC 9899:1999]] Section 7.19.7.2, "The fgets function"
[[Lai 06]]
[[Seacord 05]] Chapter 2, "Strings"
FIO36-C. Do not assume a newline character is read when using fgets() 09. Input Output (FIO) FIO38-C. Do not use a copy of a FILE object for input and output