...
As a result, objects of type T
with automatic or dynamic storage duration must be explicitly initialized prior to before having their value read as part of an expression , except if unless T
is a class type or an array thereof , or is an unsigned narrow character type. If T
is an unsigned narrow character type, it may be used to initialize an object of unsigned narrow character type, which results in both objects having an indeterminate value. This technique can be used to implement copy operations like such as std::memcpy()
without triggering undefined behavior.
Additionally, memory dynamically allocated with a new
expression is default-initialized when the new-initialized is omitted. Memory allocated by the standard library function std::calloc()
is zero-initialized. Memory allocated by the standard library function std::realloc()
assumes the values of the original pointer , but may not initialize the full range of memory. Memory allocated by any other means (std::malloc()
, allocator objects, operator new()
, etcand so on) is assumed to be default-initialized.
Objects of static or thread storage duration are zero-initialized before any other initialization takes place [ISO/IEC 14882-2014] , and need not be explicitly initialized prior to before having their value read.
Noncompliant Code Example
...
In this noncompliant code example, an int *
object is allocated by a new-expression, but the memory is it points to is not initialized. The object's pointer value , and the value it points to are printed to the standard output stream. Printing the pointer value is well-defined, but attempting to print the value pointed to yields an indeterminate value, resulting in undefined behavior.
...
When moving a value from an object of standard library type, the moved-from object's value is generally left in a valid , but unspecified , state. The notable exception to this rule is std::unique_ptr
, which is guaranteed to represent a null pointer value when it has been moved - from. In this noncompliant code example, the integer values 0
through 9
are expected to be printed to the standard output stream from a std::string
rvalue reference. However, since because the object is moved , and then reused under the assumption its internal state has been cleared, unexpected output may occur despite not triggering undefined behavior.
...
Some standard library implementations may implement the Short String Optimization short string optimization (SSO) when implementing std::string
. In such implementations, strings under a certain length are stored in a character buffer internal to the std::string
object (saving avoiding an expensive heap allocation operation). However, such an implementation might not alter the original buffer value when performing a move operation. When the noncompliant code example is compiled with Clang 3.7 using libc++, the following output is produced:
...
In this compliant solution, the std::string
object is initialized to the expected value on each iteration of the loop. This practice ensures that the object is in a valid, specified state prior to attempting to access it in g()
, resulting in the expected output:
...
Reading uninitialized variables is undefined behavior and can result in unexpected program behavior. In some cases, these security flaws may these security flaws may allow the execution of arbitrary code.
Reading uninitialized variables for creating entropy is problematic , because these memory accesses can be removed by compiler optimization. VU#925211 is an example of a vulnerability caused a vulnerability caused by this coding error.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
EXP53-CPP | High | Probable | Medium | P12 | L1 |
...
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
...