...
Passing an array type still produces undefined behavior in C++ because an array type as a function parameter requires use of a reference, which is prohibited.
Noncompliant Code Example
In this noncompliant code example, a reference type is passed as the second argument to va_start()
:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <cstdarg> #include <iostream> void f(int &a, ...) { va_list list; va_start(list, a); if (a) { std::cout << a << ", " << va_arg(list, int); a = 100; // Assign something to a for the caller } va_end(list); } |
Compliant Solution
Instead of passing a reference type to f()
, this compliant solution passes a pointer type:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <cstdarg> #include <iostream> void f(int *a, ...) { va_list list; va_start(list, a); if (a && *a) { std::cout << a << ", " << va_arg(list, int); *a = 100; // Assign something to *a for the caller } va_end(list); } |
Noncompliant Code Example
In this noncompliant code example, a nontrivially-copyable type is passed as the second argument to va_start()
, which is conditionally supported depending on the implementation:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <cstdarg> #include <iostream> #include <string> void f(std::string s, ...) { va_list list; va_start(list, s); std::cout << s << ", " << va_arg(list, int); va_end(list); } |
Compliant Solution
This compliant solution passes a const char *
instead of a std::string
, which has well-defined behavior on all implementations:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <cstdarg> #include <iostream> void f(const char *s, ...) { va_list list; va_start(list, a); std::cout << (s ? s : "") << ", " << va_arg(list, int); va_end(list); } |
Risk Assessment
Passing a reference type, or nontrivially-copyable type as the second argument to va_start()
can result in undefined behavior that might be exploited to cause data integrity violations.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
EXP40-CPP | Medium | Unlikely | Medium | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Clang |
| -Wvarargs | Does not catch all instances of this rule, such as the second NCCE. |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Bibliography
[ISO/IEC 9899:2011] | 7.16.1.4, "The va_start macro" |
[ISO/IEC 14882-2014] | 18.10, "Other Runtime Support" |
...