Security Vulnerability in pthread_cond_wait (GLIBC): Thread can release another thread's mutex lock

hit-yh hit-yh@foxmail.com
Wed Mar 4 07:05:12 GMT 2026


Hi, I am reporting a severe security vulnerability in the pthread_cond_wait() function of the GNU C Library (GLIBC). The vulnerability allows a thread to release a mutex lock that is held by another thread, violating the basic principle of mutex ownership.




VULNERABILITY SUMMARY
=====================


Function: pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex)


Problem: When using a mutex initialized with PTHREAD_MUTEX_NORMAL type (the default behavior), calling pthread_cond_wait() from a thread that does NOT hold the mutex can still release the mutex if it is held by another thread.


Severity: High - This breaks the fundamental security guarantee of mutexes that "only the thread that locked the mutex can unlock it".




TEST RESULTS
============


I have created comprehensive test programs that demonstrate the vulnerability:


Test: Default Mutex Type (Vulnerable)
--------------------------------------


Compile with: gcc -o test_vulnerable test_vulnerable.c -pthread
Run: ./test_vulnerable


===============================================================================
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>


pthread_mutex_t mutex;
pthread_cond_t cond;
pthread_barrier_t barrier;
int cond_flag = 0;


void* child_thread(void* arg) {
    printf("Child thread: started\n");


    // Wait for main thread to be ready
    pthread_barrier_wait(&barrier);


    printf("Child thread: calling pthread_cond_wait...\n");
    int result = pthread_cond_wait(&cond, &mutex);


    if (result == 0) {
        printf("Child thread: pthread_cond_wait returned (cond_flag=%d)\n", cond_flag);
    } else {
        printf("Child thread: pthread_cond_wait failed: %d - %s\n", result, strerror(result));
    }


    return NULL;
}


int main() {
    printf("Main thread: started\n");


    // Initialize barrier for 2 threads (main + child)
    pthread_barrier_init(&barrier, NULL, 2);


    // Initialize mutex and condition variable
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);


    // Main thread locks mutex
    printf("Main thread: locking mutex...\n");
    pthread_mutex_lock(&mutex);


    // Create child thread
    pthread_t tid;
    pthread_create(&tid, NULL, child_thread, NULL);


    // Wait for child thread to reach barrier
    pthread_barrier_wait(&barrier);


    printf("Main thread: child thread has called pthread_cond_wait\n");


    // Check if mutex was unintentionally released
    printf("\nMain thread: checking mutex status with trylock...\n");
    int trylock_result = pthread_mutex_trylock(&mutex);
    if (trylock_result == 0) {
        printf("ERROR: Main thread can trylock again - mutex is UNLOCKED!\n"); // ------------- HERE! -------------
        pthread_mutex_unlock(&mutex);
    } else if (trylock_result == EBUSY) {
        printf("OK: Main thread trylock failed - mutex is still LOCKED\n");
    } else {
        printf("ERROR: pthread_mutex_trylock failed with: %d - %s\n", trylock_result, strerror(trylock_result));
    }


    // Signal condition variable
    cond_flag = 1;
    printf("\nMain thread: signaling condition variable...\n");
    pthread_cond_signal(&cond);


    // Wait for child thread to finish
    pthread_join(tid, NULL);


    // Unlock mutex
    printf("\nMain thread: unlocking mutex...\n");
    pthread_mutex_unlock(&mutex);


    // Cleanup
    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);
    pthread_barrier_destroy(&barrier);


    printf("Main thread: exiting normally\n");
    return 0;
}



===============================================================================


Output:
-------
Main thread: started
Main thread: locking mutex...
Child thread: started
Child thread: calling pthread_cond_wait...
Main thread: child thread has called pthread_cond_wait


Main thread: checking mutex status with trylock...
ERROR: Main thread can trylock again - mutex is UNLOCKED!


Main thread: signaling condition variable...
Child thread: pthread_cond_wait returned (cond_flag=1)


Main thread: unlocking mutex...
Main thread: exiting normally




IMPACT
======


Vulnerable Applications:
- All multi-threaded applications using pthread_cond_wait with the default mutex type
- Applications that use mutexes to protect critical sections




SYSTEM INFORMATION
==================


- OS: Ubuntu 22.04 LTS
- Kernel: Linux 5.15.167.4-microsoft-standard-WSL2
- GLIBC Version: 2.35
- Architecture: x86_64
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20260304/c6833823/attachment-0001.htm>


More information about the Libc-alpha mailing list