Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb589d21

Browse files
committed
Fix error handling with threads on OOM in ECPG connection logic
An out-of-memory failure happening when allocating the structures tostore the connection parameter keywords and values would mess up withthe set of connections saved, as on failure the pthread mutex wouldstill be hold with the new connection object listed but free()'d.Rather than just unlocking the mutex, which would leave the static listof connections into an inconsistent state, move the allocation for thestructures of the connection parameters before beginning the testmanipulation. This ensures that the list of connections and theconnection mutex remain consistent all the time in this code path.This error is unlikely going to happen, but this could mess up badlywith ECPG clients in surprising ways, so backpatch all the way down.Reported-by: ryancaicseDiscussion:https://postgr.es/m/17186-b4cfd8f0eb4d1dee@postgresql.orgBackpatch-through: 9.6
1 parent7e42007 commitb589d21

File tree

1 file changed

+39
-32
lines changed

1 file changed

+39
-32
lines changed

‎src/interfaces/ecpg/ecpglib/connect.c

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -484,37 +484,10 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
484484
else
485485
realname=NULL;
486486

487-
/* add connection to our list */
488-
#ifdefENABLE_THREAD_SAFETY
489-
pthread_mutex_lock(&connections_mutex);
490-
#endif
491-
if (connection_name!=NULL)
492-
this->name=ecpg_strdup(connection_name,lineno);
493-
else
494-
this->name=ecpg_strdup(realname,lineno);
495-
496-
this->cache_head=NULL;
497-
this->prep_stmts=NULL;
498-
499-
if (all_connections==NULL)
500-
this->next=NULL;
501-
else
502-
this->next=all_connections;
503-
504-
all_connections=this;
505-
#ifdefENABLE_THREAD_SAFETY
506-
pthread_setspecific(actual_connection_key,all_connections);
507-
#endif
508-
actual_connection=all_connections;
509-
510-
ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
511-
realname ?realname :"<DEFAULT>",
512-
host ?host :"<DEFAULT>",
513-
port ? (ecpg_internal_regression_mode ?"<REGRESSION_PORT>" :port) :"<DEFAULT>",
514-
options ?"with options " :"",options ?options :"",
515-
(user&&strlen(user)>0) ?"for user " :"",user ?user :"");
516-
517-
/* count options (this may produce an overestimate, it's ok) */
487+
/*
488+
* Count options for the allocation done below (this may produce an
489+
* overestimate, it's ok).
490+
*/
518491
if (options)
519492
for (i=0;options[i];i++)
520493
if (options[i]=='=')
@@ -525,7 +498,11 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
525498
if (passwd&&strlen(passwd)>0)
526499
connect_params++;
527500

528-
/* allocate enough space for all connection parameters */
501+
/*
502+
* Allocate enough space for all connection parameters. These allocations
503+
* are done before manipulating the list of connections to ease the error
504+
* handling on failure.
505+
*/
529506
conn_keywords= (constchar**)ecpg_alloc((connect_params+1)*sizeof(char*),lineno);
530507
conn_values= (constchar**)ecpg_alloc(connect_params*sizeof(char*),lineno);
531508
if (conn_keywords==NULL||conn_values==NULL)
@@ -548,6 +525,36 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
548525
return false;
549526
}
550527

528+
/* add connection to our list */
529+
#ifdefENABLE_THREAD_SAFETY
530+
pthread_mutex_lock(&connections_mutex);
531+
#endif
532+
if (connection_name!=NULL)
533+
this->name=ecpg_strdup(connection_name,lineno);
534+
else
535+
this->name=ecpg_strdup(realname,lineno);
536+
537+
this->cache_head=NULL;
538+
this->prep_stmts=NULL;
539+
540+
if (all_connections==NULL)
541+
this->next=NULL;
542+
else
543+
this->next=all_connections;
544+
545+
all_connections=this;
546+
#ifdefENABLE_THREAD_SAFETY
547+
pthread_setspecific(actual_connection_key,all_connections);
548+
#endif
549+
actual_connection=all_connections;
550+
551+
ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
552+
realname ?realname :"<DEFAULT>",
553+
host ?host :"<DEFAULT>",
554+
port ? (ecpg_internal_regression_mode ?"<REGRESSION_PORT>" :port) :"<DEFAULT>",
555+
options ?"with options " :"",options ?options :"",
556+
(user&&strlen(user)>0) ?"for user " :"",user ?user :"");
557+
551558
i=0;
552559
if (realname)
553560
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp