
Co-authored-by: Marco Borgeaud <89914223+marco-antognini-sonarsource@users.noreply.github.com>
73 lines
2.6 KiB
Plaintext
73 lines
2.6 KiB
Plaintext
The function ``++size_t strlen(const char *s)++`` measures the length of the string `s` (excluding the final null character). +
|
|
The function ``++size_t wcslen(const wchar_t *s)++`` does the same for wide characters, and should be used with the same guidelines.
|
|
|
|
Similarly to many other functions in the standard C libraries,
|
|
`strlen` and `wcslen` assume that their argument is not a null pointer.
|
|
|
|
Additionally, they expect the strings to be null-terminated.
|
|
For example, the 5-letter string "abcde" must be stored in memory as "abcde\0" (i.e. using 6 characters) to be processed correctly.
|
|
When a string is missing the null character at the end, these functions will iterate past the end of the buffer, which is undefined behavior.
|
|
|
|
Therefore, string parameters must end with a proper null character.
|
|
The absence of this particular character can lead to security vulnerabilities that allow, for example, access to sensitive data or the execution of arbitrary code.
|
|
|
|
== Ask Yourself Whether
|
|
|
|
* There is a possibility that the pointer is null.
|
|
* There is a possibility that the string is not correctly null-terminated.
|
|
|
|
There is a risk if you answered yes to any of those questions.
|
|
|
|
|
|
== Recommended Secure Coding Practices
|
|
|
|
* Use safer functions. The C11 functions `strlen_s` and `wcslen_s` from annex K handle typical programming errors. +
|
|
Note, however, that they have a runtime overhead and require more code for error handling and therefore are not suited to every case.
|
|
* Even if your compiler does not exactly support annex K, you probably have access to similar functions.
|
|
* If you are writing {cpp} code, using ``++std::string++`` to manipulate strings is much simpler and less error-prone.
|
|
|
|
|
|
== Sensitive Code Example
|
|
|
|
[source,cpp]
|
|
----
|
|
size_t f(char *src) {
|
|
char dest[256];
|
|
strncpy(dest, src, sizeof dest); // Truncation may happen
|
|
return strlen(dest); // Sensitive: "dest" will not be null-terminated if truncation happened
|
|
}
|
|
----
|
|
|
|
|
|
== Compliant Solution
|
|
|
|
[source,cpp]
|
|
----
|
|
size_t f(char *src) {
|
|
char dest[256];
|
|
strncpy(dest, src, sizeof dest); // Truncation may happen
|
|
dest[sizeof dest - 1] = 0;
|
|
return strlen(dest); // Compliant: "dest" is guaranteed to be null-terminated
|
|
}
|
|
----
|
|
|
|
|
|
== See
|
|
|
|
* https://cwe.mitre.org/data/definitions/120[MITRE, CWE-120] - Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')
|
|
* https://wiki.sei.cmu.edu/confluence/x/HdcxBQ[CERT, STR07-C.] - Use the bounds-checking interfaces for string manipulation
|
|
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
Make sure use of "strlen" is safe here.
|
|
|
|
|
|
endif::env-github,rspecator-view[]
|