-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C++: Promote cpp/iterator-to-expired-container
out of experimental
#16355
C++: Promote cpp/iterator-to-expired-container
out of experimental
#16355
Conversation
QHelp previews: cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.qhelpIterator to expired containerUsing an iterator owned by a container after the lifetime of the container has expired can lead to undefined behavior. This is because the iterator may be invalidated when the container is destroyed, and dereferencing an invalidated iterator is undefined behavior. These problems can be hard to spot due to C++'s complex rules for temporary object lifetimes and their extensions. RecommendationNever create an iterator to a temporary container when the iterator is expected to be used after the container's lifetime has expired. ExampleThe rules for lifetime extension ensures that the code in #include <vector>
std::vector<int> get_vector();
void use(int);
void lifetime_of_temp_extended() {
for(auto x : get_vector()) {
use(x); // GOOD: The lifetime of the vector returned by `get_vector()` is extended until the end of the loop.
}
}
// Writes the the values of `v` to an external log and returns it unchanged.
const std::vector<int>& log_and_return_argument(const std::vector<int>& v);
void lifetime_of_temp_not_extended() {
for(auto x : log_and_return_argument(get_vector())) {
use(x); // BAD: The lifetime of the vector returned by `get_vector()` is not extended, and the behavior is undefined.
}
}
References
|
…xpired-container'.
cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql
Dismissed
Show dismissed
Hide dismissed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
This PR moves the
cpp/iterator-to-expired-container
out of experimental and into Security-Extended as amedium
precision query. There are a couple of simple follow-ups to be done before we can move it to high precision, but moving it to medium precision should not be controversial at this point.It was mentioned in the past that we should rewrite the query alert message since the alert message currently says that the container is destroyed before the call to begin, but in reality what's going on is that the container is destroyed after the call to begin (but before it can be dereferenced without causing UB). Any ideas for how we should rephrase it? Some ideas:
call to begin
returns."This isn't ideal because most objects are destroyed after
begin
returns. The problem is that the object is destroyed before any meaningful things can be done with the return value.call to begin
returns."This isn't ideal since this is false in many cases. The object is destroyed at the end of the full expression, and that isn't necessary the call to begin.
This is the most correct, but I think it would make sense to include the
call to begin
somewhere in the message?