Skip to content

Commit ba412c9

Browse files
committed
Avoid ecpglib core dump with out-of-order operations.
If an application executed operations like EXEC SQL PREPARE without having first established a database connection, it could get a core dump instead of the expected clean failure. This occurred because we did "pthread_getspecific(actual_connection_key)" without ever having initialized the TSD key actual_connection_key. The results of that are probably platform-specific, but at least on Linux it often leads to a crash. To fix, add calls to ecpg_pthreads_init() in the code paths that might use actual_connection_key uninitialized. It's harmless (and hopefully inexpensive) to do that more than once. Per bug #17514 from Okano Naoki. The problem's ancient, so back-patch to all supported branches. Discussion: https://postgr.es/m/17514-edd4fad547c5692c@postgresql.org
1 parent d26ac35 commit ba412c9

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

src/interfaces/ecpg/ecpglib/connect.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,16 @@ ecpg_get_connection_nr(const char *connection_name)
4040
if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
4141
{
4242
#ifdef ENABLE_THREAD_SAFETY
43+
ecpg_pthreads_init(); /* ensure actual_connection_key is valid */
44+
4345
ret = pthread_getspecific(actual_connection_key);
4446

4547
/*
4648
* if no connection in TSD for this thread, get the global default
4749
* connection and hope the user knows what they're doing (i.e. using
4850
* their own mutex to protect that connection from concurrent accesses
4951
*/
50-
/* if !ret then we got the connection from TSD */
51-
if (NULL == ret)
52+
if (ret == NULL)
5253
/* no TSD connection, going for global */
5354
ret = actual_connection;
5455
#else
@@ -78,15 +79,16 @@ ecpg_get_connection(const char *connection_name)
7879
if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
7980
{
8081
#ifdef ENABLE_THREAD_SAFETY
82+
ecpg_pthreads_init(); /* ensure actual_connection_key is valid */
83+
8184
ret = pthread_getspecific(actual_connection_key);
8285

8386
/*
8487
* if no connection in TSD for this thread, get the global default
8588
* connection and hope the user knows what they're doing (i.e. using
8689
* their own mutex to protect that connection from concurrent accesses
8790
*/
88-
/* if !ret then we got the connection from TSD */
89-
if (NULL == ret)
91+
if (ret == NULL)
9092
/* no TSD connection here either, using global */
9193
ret = actual_connection;
9294
#else

0 commit comments

Comments
 (0)