...
Code Block |
---|
|
int main(int argc, const char *argv[]) {
std::unique_ptr<char[]> buff;
const char *s = "";
if (1 < argc) {
buff.reset(new char [BUFSIZ]);
// ...
s = strncpy(buff.get(), argv[1], BUFSIZ-1);
}
std::cout << s << '\n';
}
|
Noncompliant Code Example (std::string::c_str()
)
In this noncompliant code example, std::string::c_str()
is being called on a temporary std::string
object. The resulting pointer will point to released memory once the std::string
object is destroyed at the end of the assignment expression, resulting in undefined behavior when accessing elements of that pointer.
Code Block |
---|
|
std::string someStringReturningFunction();
/* ... */
const char *str = someStringReturningFunction().c_str();
displayString(str); /* Undefined behavior */
|
Compliant solution (std::string::c_str()
)
In this compliant solution, a copy of the string returned by someStringReturningFunction()
is made on the stack, which means the string str
will be valid when the call to displayString
is made:
Code Block |
---|
|
void displayString( const char* s );
std::string someStringReturningFunction();
/* ... */
std::string str = someStringReturningFunction();
const char *str = str.c_str();
displayString(str); /* ok */ |
Risk Assessment
Reading previously dynamically allocated memory after it has been deallocated can lead to abnormal program termination and denial-of-service attacks. Writing memory that has been deallocated can lead to the execution of arbitrary code with the permissions of the vulnerable process.
...