CERT.CONC.WAKE_IN_LOOP_C

Wrap functions that can spuriously wake up in a loop

This checker reports calls to 'cnd_wait', cnd_timedwait', 'wait', 'wait_for' and 'wait_until' that are not invoked in a loop.

Vulnerability and risk

Failure to enclose calls to the cnd_wait() or cnd_timedwait() functions inside a while loop can lead to indefinite blocking and denial of service (DoS).

Mitigation and prevention

Call the cnd_wait() function from within a while loop to check the condition both before and after the call to cnd_wait():

Vulnerable code example

struct node_t {
    void *node;
    struct node_t *next;
};

struct node_t list;
static mtx_t lock;
static cnd_t condition;

void consume_list_element(void) {
    if (thrd_success != mtx_lock(&lock)) {
        /* Handle error */
    }

    if (list.next == NULL) {
        if (thrd_success != cnd_wait(&condition, &lock)) {
            /* Handle error */
        }
    }

    /* Proceed when condition holds */

    if (thrd_success != mtx_unlock(&lock)) {
        /* Handle error */
    }
}

This noncompliant code example nests the cnd_wait() function inside an if block and consequently fails to check the condition predicate after the notification is received. If the notification was spurious or malicious, the thread would wake up prematurely.