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

Commitc3b7922

Browse files
committed
Fix race condition with BIO methods initialization in libpq with threads
The libpq code in charge of creating per-connection SSL objects wasprone to a race condition when loading the custom BIO methods needed bymy_SSL_set_fd(). As BIO methods are stored as a static variable, theinitialization of a connection could fail because it could be possibleto have one thread refer to my_bio_methods while it is being manipulatedby a second concurrent thread.This error has been introduced by8bb14cd, that has removedssl_config_mutex around the call of my_SSL_set_fd(), that itself setsthe custom BIO methods used in libpq. Like previously, the BIO methodinitialization is now protected by the existing ssl_config_mutex, itselfinitialized earlier for WIN32.While on it, document that my_bio_methods is protected byssl_config_mutex, as this can be easy to miss.Reported-by: Willi MannAuthor: Willi Mann, Michael PaquierDiscussion:https://postgr.es/m/e77abc4c-4d03-4058-a9d7-ef0035657e04@celonis.comBackpatch-through: 12
1 parent648fc6a commitc3b7922

File tree

1 file changed

+51
-22
lines changed

1 file changed

+51
-22
lines changed

‎src/interfaces/libpq/fe-secure-openssl.c

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,6 +1666,7 @@ PQsslAttribute(PGconn *conn, const char *attribute_name)
16661666
#defineBIO_set_data(bio,data) (bio->ptr = data)
16671667
#endif
16681668

1669+
/* protected by ssl_config_mutex */
16691670
staticBIO_METHOD*my_bio_methods;
16701671

16711672
staticint
@@ -1731,6 +1732,15 @@ my_sock_write(BIO *h, const char *buf, int size)
17311732
staticBIO_METHOD*
17321733
my_BIO_s_socket(void)
17331734
{
1735+
BIO_METHOD*res;
1736+
1737+
#ifdefENABLE_THREAD_SAFETY
1738+
if (pthread_mutex_lock(&ssl_config_mutex))
1739+
returnNULL;
1740+
#endif
1741+
1742+
res=my_bio_methods;
1743+
17341744
if (!my_bio_methods)
17351745
{
17361746
BIO_METHOD*biom= (BIO_METHOD*)BIO_s_socket();
@@ -1739,39 +1749,58 @@ my_BIO_s_socket(void)
17391749

17401750
my_bio_index=BIO_get_new_index();
17411751
if (my_bio_index==-1)
1742-
returnNULL;
1752+
gotoerr;
17431753
my_bio_index |= (BIO_TYPE_DESCRIPTOR |BIO_TYPE_SOURCE_SINK);
1744-
my_bio_methods=BIO_meth_new(my_bio_index,"libpq socket");
1745-
if (!my_bio_methods)
1746-
returnNULL;
1754+
res=BIO_meth_new(my_bio_index,"libpq socket");
1755+
if (!res)
1756+
gotoerr;
17471757

17481758
/*
17491759
* As of this writing, these functions never fail. But check anyway,
17501760
* like OpenSSL's own examples do.
17511761
*/
1752-
if (!BIO_meth_set_write(my_bio_methods,my_sock_write)||
1753-
!BIO_meth_set_read(my_bio_methods,my_sock_read)||
1754-
!BIO_meth_set_gets(my_bio_methods,BIO_meth_get_gets(biom))||
1755-
!BIO_meth_set_puts(my_bio_methods,BIO_meth_get_puts(biom))||
1756-
!BIO_meth_set_ctrl(my_bio_methods,BIO_meth_get_ctrl(biom))||
1757-
!BIO_meth_set_create(my_bio_methods,BIO_meth_get_create(biom))||
1758-
!BIO_meth_set_destroy(my_bio_methods,BIO_meth_get_destroy(biom))||
1759-
!BIO_meth_set_callback_ctrl(my_bio_methods,BIO_meth_get_callback_ctrl(biom)))
1762+
if (!BIO_meth_set_write(res,my_sock_write)||
1763+
!BIO_meth_set_read(res,my_sock_read)||
1764+
!BIO_meth_set_gets(res,BIO_meth_get_gets(biom))||
1765+
!BIO_meth_set_puts(res,BIO_meth_get_puts(biom))||
1766+
!BIO_meth_set_ctrl(res,BIO_meth_get_ctrl(biom))||
1767+
!BIO_meth_set_create(res,BIO_meth_get_create(biom))||
1768+
!BIO_meth_set_destroy(res,BIO_meth_get_destroy(biom))||
1769+
!BIO_meth_set_callback_ctrl(res,BIO_meth_get_callback_ctrl(biom)))
17601770
{
1761-
BIO_meth_free(my_bio_methods);
1762-
my_bio_methods=NULL;
1763-
returnNULL;
1771+
gotoerr;
17641772
}
17651773
#else
1766-
my_bio_methods=malloc(sizeof(BIO_METHOD));
1767-
if (!my_bio_methods)
1768-
returnNULL;
1769-
memcpy(my_bio_methods,biom,sizeof(BIO_METHOD));
1770-
my_bio_methods->bread=my_sock_read;
1771-
my_bio_methods->bwrite=my_sock_write;
1774+
res=malloc(sizeof(BIO_METHOD));
1775+
if (!res)
1776+
gotoerr;
1777+
memcpy(res,biom,sizeof(BIO_METHOD));
1778+
res->bread=my_sock_read;
1779+
res->bwrite=my_sock_write;
17721780
#endif
17731781
}
1774-
returnmy_bio_methods;
1782+
1783+
my_bio_methods=res;
1784+
1785+
#ifdefENABLE_THREAD_SAFETY
1786+
pthread_mutex_unlock(&ssl_config_mutex);
1787+
#endif
1788+
1789+
returnres;
1790+
1791+
err:
1792+
#ifdefHAVE_BIO_METH_NEW
1793+
if (res)
1794+
BIO_meth_free(res);
1795+
#else
1796+
if (res)
1797+
free(res);
1798+
#endif
1799+
1800+
#ifdefENABLE_THREAD_SAFETY
1801+
pthread_mutex_unlock(&ssl_config_mutex);
1802+
#endif
1803+
returnNULL;
17751804
}
17761805

17771806
/* This should exactly match OpenSSL's SSL_set_fd except for using my BIO */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp