CERT.CONC.UNSAFE_COND_VAR
条件変数の使用時にはスレッドセーフと活性を維持してください。
wait() 関数は、条件述語が当てはまるかをチェックするループから呼び出す必要があります。条件述語は関数の変数から構成された式です。スレッドを継続的に実行させるには、条件述語が真でなければなりません。
脆弱性とリスク
条件述語ループでネストして wait() を呼び出さないと、通知を受け取った後、チェッカーは条件述語のチェックを行いません。通知が偽物であったり、悪意のあるものであった場合、スレッドが早々に起動する可能性があります。
軽減と防止
wait() 関数は、条件述語が当てはまるかをチェックするループから呼び出す必要があります。
例
コピー
#include <condition_variable>
#include <mutex>
struct Node {
void *node;
struct Node *next;
};
static Node list;
static std::mutex m;
static std::condition_variable condition;
void consume_list_element1(std::condition_variable &condition) {
std::unique_lock<std::mutex> lk(m);
if (list.next == nullptr) {
condition.wait(lk); // Uncompliant code.
}
// Proceed when condition holds.
}
void consume_list_element2() {
std::unique_lock<std::mutex> lk(m);
while (list.next == nullptr) {
condition.wait(lk); // Compliant code
}
// Proceed when condition holds.
}
void consume_list_element3() {
std::unique_lock<std::mutex> lk(m);
condition.wait(lk, []{ return list.next; }); //Compliant code.
// Proceed when condition holds.
}