CERT.MEM.SMART_PTR.OWNED.THIS
The underlying resource might be already owned by a non-related smart pointer
The CERT.MEM.SMART_PTR.OWNED.THIS checker finds defects when an already-owned pointer value may get stored in an unrelated smart pointer.
Vulnerability and risk
If the underlying resource is owned by two unrelated smart pointers, then it can cause the double free vulnerability.
Mitigation and prevention
The compliant solution is to use std::enable_shared_from_this::shared_from_this()
to get a shared pointer, that is related to an existing std::shared_ptr object
.
Vulnerable code example
#include <memory>
struct S {
std::shared_ptr<S> g()
{
return std::shared_ptr<S>(this);
}
};
int main() {
std::shared_ptr<S> s1 = std::make_shared<S>();
// ...
std::shared_ptr<S> s2 = s1->g();
return 0;
}
Klocwork reports CERT.MEM.SMART_PTR.OWNED.THIS at line 6, because in line 13, s1->g() call, a new smart pointer is getting created and being stored in s2, which is already owned by smart pointer s1. Here s1 and s2 both will try to delete the underlying wrapped object and cause double free vulnerability.
Fixed code example
#include <memory>
struct S : std::enable_shared_from_this<S> {
std::shared_ptr<S> g() { return shared_from_this(); }
};
int main() {
std::shared_ptr<S> s1 = std::make_shared<S>();
std::shared_ptr<S> s2 = s1->g();
return 0;
}
There is no possibility of double free vulnerability here as the shared_from_this() function call does not create a new unrelated smart pointer. At the end of execution of line 9, the use_count() returns 2 for both s1 and s2.