From 6cdd4e697eb86982e3dfd2ceab009ead5da0efcb Mon Sep 17 00:00:00 2001 From: Rene Cannao Date: Sun, 3 May 2026 03:31:19 +0000 Subject: [PATCH] fix: correct lock unlock order in Authentication classes Fix lock order reversal in MySQL_Authentication, ClickHouse_Authentication, and PgSQL_Authentication. In memory_usage() and dump_all_users(), locks were acquired in order (frontends, backends) but released in the same order instead of the reverse. This creates a potential deadlock if another thread attempts to acquire the same locks in opposite order. Swap unlock calls to release backends before frontends, matching the reverse of the acquisition order. --- lib/ClickHouse_Authentication.cpp | 4 ++-- lib/MySQL_Authentication.cpp | 8 ++++---- lib/PgSQL_Authentication.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/ClickHouse_Authentication.cpp b/lib/ClickHouse_Authentication.cpp index e21485e6f..052d23d74 100644 --- a/lib/ClickHouse_Authentication.cpp +++ b/lib/ClickHouse_Authentication.cpp @@ -210,11 +210,11 @@ int ClickHouse_Authentication::dump_all_users(ch_account_details_t ***ads, bool *ads=_ads; __exit_dump_all_users: #ifdef PROXYSQL_AUTH_PTHREAD_MUTEX - pthread_rwlock_unlock(&creds_frontends.lock); pthread_rwlock_unlock(&creds_backends.lock); + pthread_rwlock_unlock(&creds_frontends.lock); #else - spin_rdunlock(&creds_frontends.lock); spin_rdunlock(&creds_backends.lock); + spin_rdunlock(&creds_frontends.lock); #endif return total_size; } diff --git a/lib/MySQL_Authentication.cpp b/lib/MySQL_Authentication.cpp index cb571623d..789ef133b 100644 --- a/lib/MySQL_Authentication.cpp +++ b/lib/MySQL_Authentication.cpp @@ -306,11 +306,11 @@ unsigned int MySQL_Authentication::memory_usage() { ret += sizeof(PtrArray); ret += (creds_backends.cred_array->size * sizeof(void *)); #ifdef PROXYSQL_AUTH_PTHREAD_MUTEX - pthread_rwlock_unlock(&creds_frontends.lock); pthread_rwlock_unlock(&creds_backends.lock); + pthread_rwlock_unlock(&creds_frontends.lock); #else - spin_rdunlock(&creds_frontends.lock); spin_rdunlock(&creds_backends.lock); + spin_rdunlock(&creds_frontends.lock); #endif return ret; } @@ -392,11 +392,11 @@ int MySQL_Authentication::dump_all_users(account_details_t ***ads, bool _complet *ads=_ads; __exit_dump_all_users: #ifdef PROXYSQL_AUTH_PTHREAD_MUTEX - pthread_rwlock_unlock(&creds_frontends.lock); pthread_rwlock_unlock(&creds_backends.lock); + pthread_rwlock_unlock(&creds_frontends.lock); #else - spin_rdunlock(&creds_frontends.lock); spin_rdunlock(&creds_backends.lock); + spin_rdunlock(&creds_frontends.lock); #endif return total_size; } diff --git a/lib/PgSQL_Authentication.cpp b/lib/PgSQL_Authentication.cpp index 0abdae0e3..f0fbd5517 100644 --- a/lib/PgSQL_Authentication.cpp +++ b/lib/PgSQL_Authentication.cpp @@ -250,11 +250,11 @@ unsigned int PgSQL_Authentication::memory_usage() { ret += sizeof(PtrArray); ret += (creds_backends.cred_array->size * sizeof(void *)); #ifdef PROXYSQL_AUTH_PTHREAD_MUTEX - pthread_rwlock_unlock(&creds_frontends.lock); pthread_rwlock_unlock(&creds_backends.lock); + pthread_rwlock_unlock(&creds_frontends.lock); #else - spin_rdunlock(&creds_frontends.lock); spin_rdunlock(&creds_backends.lock); + spin_rdunlock(&creds_frontends.lock); #endif return ret; } @@ -327,11 +327,11 @@ int PgSQL_Authentication::dump_all_users(pgsql_account_details_t***ads, bool _co *ads=_ads; __exit_dump_all_users: #ifdef PROXYSQL_AUTH_PTHREAD_MUTEX - pthread_rwlock_unlock(&creds_frontends.lock); pthread_rwlock_unlock(&creds_backends.lock); + pthread_rwlock_unlock(&creds_frontends.lock); #else - spin_rdunlock(&creds_frontends.lock); spin_rdunlock(&creds_backends.lock); + spin_rdunlock(&creds_frontends.lock); #endif return total_size; }