Content-Type: text/plain Content-Disposition: inline Content-Transfer-Encoding: binary MIME-Version: 1.0 X-Mailer: MIME-tools 5.411 (Entity 5.404) Subject: Race condition in lib/krb5/ccache/cc_memory.c X-RT-Original-Encoding: iso-8859-1 Content-Length: 1606 Using the MEMORY credentials cache from multiple threads is not thread-safe and crashes. The crash was found and can be illustrated on function krb5_verify_init_creds() that creates and destroys a temporary credentials cache: ... krb5_cc_resolve(context, "MEMORY:rd_req", &ccache) ... krb5_cc_destroy(context, ccache); ... The krb5_ccache structure contains pointer to a krb5_mcc_data structure that is shared among ccaches with the same residual ("rd_req"). The active krb5_mcc_data pointers are stored in a global linked list mcc_head. This list is protected by a mutex (improvement in version 1.4 - there used to be no mutex before), but this mutex is not enough to prevent a race condition. Here is how the program can crash: 1. There are two threads that both call krb5_verify_init_creds at the same time. 2. Thread 1 creates the "MEMORY:rd_req" cache. It is not yet present in the mcc_head list, so it allocates new krb5_mcc_data structure and stores the pointer to mcc_head list. 3. Thread 2 creates the "MEMORY:rd_req" cache. Item with residual "rd_req" is already present in the mcc_head list, so the pointer is reused. Now both threads' krb5_ccache structures share pointer to one krb5_mcc_data structure. 4. Thread 1 calls krb5_cc_destroy. The pointer to krb5_mcc_data is removed from the mcc_head list and freed. 5. But Thread 2 still uses the pointer that was just freed! Our program crashes inside krb5_mcc_free when trying to free the already freed memory. To be really thread-safe, the krb5_mcc_data structure must be reference counted and freed only when the refcount drops to zero.