CERT.CONC.ATOMIC_COMP_FAIL_IN_LOOP

疑似的にループで失敗する可能性のある関数はラップしてください。

脆弱性とリスク

atomic_compare_exchange_weak() 関数と atomic_compare_exchange_weak_explicit() 関数をループでラップしないと、値や制御フローが不正確になる可能性があります。

脆弱コード例

struct data {
    struct data *next;
    /* ...*/
};

extern void cleanup_data_structure(struct data *head);

int reorganize_data_structure(void *thread_arg) {
    struct data *_Atomic *ptr_to_head = thread_arg;
    struct data *old_head = atomic_load(ptr_to_head);
    struct data *new_head;
    bool success;

    /* ...データ構造を再編成します ...*/

    success = atomic_compare_exchange_weak(ptr_to_head,
    &old_head, new_head);
    if (!success) {
        cleanup_data_structure(new_head);
    }
    return success; /* スレッドを終了します */
}

この非準拠コード例では、reorganize_data_structure() が thrd_create() の引数として使用されます。この関数は、再編成の後、新しいバージョンを指すためにヘッドポインターを置き換えようとします。最初にロードされて以来、他のスレッドによってヘッドポインターが変更されていなければ、reorganize_data_structure() はスレッドを抜け、成功を示す true を返します。そうでない場合は、新しい再編成試行を破棄し、スレッドを抜け、false を返します。しかし、atomic_compare_exchange_weak() は、ヘッドポインターが変更されていなくても失敗することがあります。このため、reorganize_data_structure() は再編成作業を行った後、この作業を不必要に破棄する可能性があります。