rspec/rules/S5485/cfamily/rule.adoc
Egon Okerman d1417e82f8
Modify CWE and OWASP Top 10 links to follow standard link format (APPSEC-1134) (#3529)
* Fix all CWE references

* Fix all OWASP references

* Fix missing CWE prefixes
2024-01-15 17:15:56 +01:00

157 lines
4.4 KiB
Plaintext

Passing invalid arguments to standard C library functions for handling I/O streams results in undefined behavior.
== Why is this an issue?
The standard C library includes a number of functions for handling I/O streams.
These functions put certain constraints on the values of their parameters.
The constraints include the following:
* The value for the ``++FILE*++``-typed parameter may _not_ be ``++NULL++``
* The third argument of ``++fseek++`` must be either of ``++SEEK_SET++``, ``++SEEK_END++``, or ``++SEEK_CUR++``
Failing to pass correctly constrained parameters renders them invalid and will result in undefined behavior.
[source,cpp]
----
#include <stdio.h>
size_t get_file_size() {
FILE *f = fopen("example_file.txt", "r");
// `f` may be NULL if `fopen` fails.
fseek(f, 0L, SEEK_END); // Leads to undefined behavior, if `f` is NULL.
size_t size = ftell(f); // Leads to undefined behavior, if `f` is NULL.
fclose(f);
return size;
}
----
== What is the potential impact?
Using the standard C library's functions for handling I/O streams with invalid arguments leads to *undefined behavior*.
When a program comprises undefined behavior, the compiler no longer needs to adhere to the language standard, and the program has no meaning assigned to it.
Due to the resulting NULL pointer dereferences in the C library functions, the application might just crash, but in the worst case, the application may appear to execute correctly, while losing data or producing incorrect results.
Besides affecting the application's availability, NULL pointer dereferences may lead to code execution, in rare circumstances.
If NULL is equivalent to the 0x0 memory address that can be accessed by privileged code, writing and reading memory is possible, which compromises the integrity and confidentiality of the application.
== How to fix it
Ensure that the ``++FILE*++``-typed pointer parameters passed to the standard C library's I/O stream handling functions are non-``++NULL++`` and also any other parameters such as the third argument of ``++fseek++`` carry appropriate values, namely any of ``++SEEK_SET++``, ``++SEEK_END++``, or ``++SEEK_CUR++``.
=== Code examples
==== Noncompliant code example
[source,cpp,diff-id=1,diff-type=noncompliant]
----
#include <stdio.h>
#include <stdlib.h>
int process_file(const char *fname) {
FILE *f = fopen(fname, "r");
fseek(f, 0L, SEEK_END);
size_t size = ftell(f);
rewind(f);
char *buf = (char *)malloc(size);
// Read file into buffer ...
fclose(f);
// Process buffer ...
free(buf);
return 0;
}
----
==== Compliant solution
[source,cpp,diff-id=1,diff-type=compliant]
----
#include <stdio.h>
#include <stdlib.h>
int process_file(const char *fname) {
FILE *f = fopen(fname, "r");
if (!f) {
printf("Could not open file!\n");
return 1;
}
fseek(f, 0L, SEEK_END);
size_t size = ftell(f);
rewind(f);
char *buf = (char *)malloc(size);
// Read file into buffer ...
fclose(f);
// Process buffer ...
free(buf);
return 0;
}
----
==== Noncompliant code example
[source,cpp,diff-id=2,diff-type=noncompliant]
----
#include <stdio.h>
#include <stdlib.h>
void process_tmp_file() {
FILE *f = tmpfile();
size_t pos_indicator = ftell(f); // Noncompliant: `f` could be NULL.
fseek(f, 0L, 3); // Noncompliant: 3rd argument should either be SEEK_SET, SEEK_CUR or SEEK_END.
// Further file processing ...
fclose(f);
}
----
==== Compliant solution
[source,cpp,diff-id=2,diff-type=compliant]
----
#include <stdio.h>
#include <stdlib.h>
int process_tmp_file() {
FILE *f = tmpfile();
if (!f) {
printf("Could not create temporary file!\n");
return 1;
}
size_t pos_indicator = ftell(f); // Compliant: `f` cannot be NULL here.
fseek(f, 0L, SEEK_END); // Compliant: 3rd argument is now a valid value.
// Further file processing ...
fclose(f);
return 0;
}
----
== Resources
=== Standards
* CWE - https://cwe.mitre.org/data/definitions/476[CWE-476 NULL Pointer Dereference]
=== Related rules
* S3807 ensures that appropriate arguments are passed to C standard library functions
* S5488 ensures that appropriate arguments are passed to UNIX/POSIX functions
ifdef::env-github,rspecator-view[]
'''
== Comments And Links
(visible only on this page)
=== is related to: S2095
=== is related to: S3588
=== on 22 Oct 2019, 16:20:15 Loïc Joly wrote:
\[~amelie.renard] I heavily reworded this one, can you validate please?
endif::env-github,rspecator-view[]