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 を返します。

関連チェッカー