CERT.CONC.UNSAFE_COND_VAR
条件変数の使用時にはスレッドセーフと活性を維持してください。
wait() 関数は、条件述語が当てはまるかをチェックするループから呼び出す必要があります。条件述語は関数の変数から構成された式です。スレッドを継続的に実行させるには、条件述語が真でなければなりません。
脆弱性とリスク
条件述語ループでネストして wait() を呼び出さないと、通知を受け取った後、チェッカーは条件述語のチェックを行いません。通知が偽物であったり、悪意のあるものであった場合、スレッドが早々に起動する可能性があります。
軽減と防止
wait() 関数は、条件述語が当てはまるかをチェックするループから呼び出す必要があります。
例
1 #include <condition_variable> 2 #include <mutex> 3 4 struct Node { 5 void *node; 6 struct Node *next; 7 }; 8 9 static Node list; 10 static std::mutex m; 11 static std::condition_variable condition; 12 13 void consume_list_element1(std::condition_variable &condition) { 14 std::unique_lock<std::mutex> lk(m); 15 16 if (list.next == nullptr) { 17 condition.wait(lk); // Uncompliant code. 18 } 19 20 // Proceed when condition holds. 21 } 22 23 void consume_list_element2() { 24 std::unique_lock<std::mutex> lk(m); 25 26 while (list.next == nullptr) { 27 condition.wait(lk); // Compliant code 28 } 29 30 // Proceed when condition holds. 31 } 32 33 void consume_list_element3() { 34 std::unique_lock<std::mutex> lk(m); 35 36 condition.wait(lk, []{ return list.next; }); //Compliant code. 37 // Proceed when condition holds. 38 }