CERT.MEM.SMART_PTR.OWNED.THIS
基礎となるリソースが無関係なスマートポインターによって既に所有されている可能性がある
CERT.MEM.SMART_PTR.OWNED.THIS チェッカーは、既に所有されているポインター値が無関係なスマートポインターに格納される可能性がある場合に欠陥を検出します。
脆弱性とリスク
基礎となるリソースが 2 つの無関係なスマートポインターによって所有されると、二重解放の脆弱性が発生する可能性があります。
軽減と防止
適合のためのソリューションは、std::enable_shared_from_this::shared_from_this()
を使用して、既存の std::shared_ptr object
に関連付けられている共有ポインターを取得することです。
脆弱コード例
コピー
#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 で 6 行目について CERT.MEM.SMART_PTR.OWNED.THIS が報告されます。これは、13 行目の s1->g() 呼び出しで、新しいスマートポインターが作成され、既にスマートポインター s1 によって所有されている s2 に格納されるためです。ここでは、s1 と s2 の両方が、基礎となるラップオブジェクトを削除しようとし、二重解放の脆弱性が発生します。
修正コード例
コピー
#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;
}
shared_from_this() 関数呼び出しでは新しい無関係なスマートポインターが作成されないので、ここでは二重解放の脆弱性が発生する可能性はありません。9 行目の実行終了時に、use_count() が s1 と s2 の両方に対して 2 を返します。