diff options
Diffstat (limited to 'src/interfaces/libpq')
-rw-r--r-- | src/interfaces/libpq/fe-connect.c | 16 | ||||
-rw-r--r-- | src/interfaces/libpq/fe-misc.c | 39 | ||||
-rw-r--r-- | src/interfaces/libpq/fe-secure-openssl.c | 45 | ||||
-rw-r--r-- | src/interfaces/libpq/po/ru.po | 80 | ||||
-rw-r--r-- | src/interfaces/libpq/pthread-win32.c | 26 |
5 files changed, 103 insertions, 103 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index a809013..47dcb37 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -7443,24 +7443,8 @@ static void default_threadlock(int acquire) { #ifdef ENABLE_THREAD_SAFETY -#ifndef WIN32 static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER; -#else - static pthread_mutex_t singlethread_lock = NULL; - static long mutex_initlock = 0; - if (singlethread_lock == NULL) - { - while (InterlockedExchange(&mutex_initlock, 1) == 1) - /* loop, another thread own the lock */ ; - if (singlethread_lock == NULL) - { - if (pthread_mutex_init(&singlethread_lock, NULL)) - Assert(false); - } - InterlockedExchange(&mutex_initlock, 0); - } -#endif if (acquire) { if (pthread_mutex_lock(&singlethread_lock)) diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index d76bb39..128f056 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -1233,13 +1233,14 @@ static void libpq_binddomain(void) { /* - * If multiple threads come through here at about the same time, it's okay - * for more than one of them to call bindtextdomain(). But it's not okay - * for any of them to return to caller before bindtextdomain() is - * complete, so don't set the flag till that's done. Use "volatile" just - * to be sure the compiler doesn't try to get cute. + * At least on Windows, there are gettext implementations that fail if + * multiple threads call bindtextdomain() concurrently. Use a mutex and + * flag variable to ensure that we call it just once per process. It is + * not known that similar bugs exist on non-Windows platforms, but we + * might as well do it the same way everywhere. */ static volatile bool already_bound = false; + static pthread_mutex_t binddomain_mutex = PTHREAD_MUTEX_INITIALIZER; if (!already_bound) { @@ -1249,14 +1250,26 @@ libpq_binddomain(void) #else int save_errno = errno; #endif - const char *ldir; - - /* No relocatable lookup here because the binary could be anywhere */ - ldir = getenv("PGLOCALEDIR"); - if (!ldir) - ldir = LOCALEDIR; - bindtextdomain(PG_TEXTDOMAIN("libpq"), ldir); - already_bound = true; + + (void) pthread_mutex_lock(&binddomain_mutex); + + if (!already_bound) + { + const char *ldir; + + /* + * No relocatable lookup here because the calling executable could + * be anywhere + */ + ldir = getenv("PGLOCALEDIR"); + if (!ldir) + ldir = LOCALEDIR; + bindtextdomain(PG_TEXTDOMAIN("libpq"), ldir); + already_bound = true; + } + + (void) pthread_mutex_unlock(&binddomain_mutex); + #ifdef WIN32 SetLastError(save_errno); #else diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 61f3767..47c8e0b 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -96,12 +96,7 @@ static bool ssl_lib_initialized = false; #ifdef ENABLE_THREAD_SAFETY static long crypto_open_connections = 0; -#ifndef WIN32 static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER; -#else -static pthread_mutex_t ssl_config_mutex = NULL; -static long win32_ssl_create_mutex = 0; -#endif #endif /* ENABLE_THREAD_SAFETY */ static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL; @@ -777,20 +772,6 @@ int pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto) { #ifdef ENABLE_THREAD_SAFETY -#ifdef WIN32 - /* Also see similar code in fe-connect.c, default_threadlock() */ - if (ssl_config_mutex == NULL) - { - while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1) - /* loop, another thread own the lock */ ; - if (ssl_config_mutex == NULL) - { - if (pthread_mutex_init(&ssl_config_mutex, NULL)) - return -1; - } - InterlockedExchange(&win32_ssl_create_mutex, 0); - } -#endif if (pthread_mutex_lock(&ssl_config_mutex)) return -1; @@ -881,7 +862,6 @@ static void destroy_ssl_system(void) { #if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK) - /* Mutex is created in pgtls_init() */ if (pthread_mutex_lock(&ssl_config_mutex)) return; @@ -929,7 +909,6 @@ initialize_SSL(PGconn *conn) bool have_homedir; bool have_cert; bool have_rootcert; - EVP_PKEY *pkey = NULL; /* * We'll need the home directory if any of the relevant parameters are @@ -1265,6 +1244,7 @@ initialize_SSL(PGconn *conn) /* Colon, but not in second character, treat as engine:key */ char *engine_str = strdup(conn->sslkey); char *engine_colon; + EVP_PKEY *pkey; if (engine_str == NULL) { @@ -1677,10 +1657,11 @@ pgtls_close(PGconn *conn) * Obtain reason string for passed SSL errcode * * ERR_get_error() is used by caller to get errcode to pass here. + * The result must be freed after use, using SSLerrfree. * - * Some caution is needed here since ERR_reason_error_string will - * return NULL if it doesn't recognize the error code. We don't - * want to return NULL ever. + * Some caution is needed here since ERR_reason_error_string will return NULL + * if it doesn't recognize the error code, or (in OpenSSL >= 3) if the code + * represents a system errno value. We don't want to return NULL ever. */ static char ssl_nomem[] = "out of memory allocating error description"; @@ -1706,6 +1687,22 @@ SSLerrmessage(unsigned long ecode) strlcpy(errbuf, errreason, SSL_ERR_LEN); return errbuf; } + + /* + * In OpenSSL 3.0.0 and later, ERR_reason_error_string randomly refuses to + * map system errno values. We can cover that shortcoming with this bit + * of code. Older OpenSSL versions don't have the ERR_SYSTEM_ERROR macro, + * but that's okay because they don't have the shortcoming either. + */ +#ifdef ERR_SYSTEM_ERROR + if (ERR_SYSTEM_ERROR(ecode)) + { + strlcpy(errbuf, strerror(ERR_GET_REASON(ecode)), SSL_ERR_LEN); + return errbuf; + } +#endif + + /* No choice but to report the numeric ecode */ snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), ecode); return errbuf; } diff --git a/src/interfaces/libpq/po/ru.po b/src/interfaces/libpq/po/ru.po index 78affba..50925d0 100644 --- a/src/interfaces/libpq/po/ru.po +++ b/src/interfaces/libpq/po/ru.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: libpq (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2024-02-02 18:11+0300\n" +"POT-Creation-Date: 2024-05-04 10:36+0300\n" "PO-Revision-Date: 2023-08-30 15:09+0300\n" "Last-Translator: Alexander Lakhin <exclusion@gmail.com>\n" "Language-Team: Russian <pgsql-ru-general@postgresql.org>\n" @@ -81,7 +81,7 @@ msgstr "не удалось сгенерировать разовый код\n" #: fe-exec.c:4139 fe-exec.c:4304 fe-gssapi-common.c:111 fe-lobj.c:884 #: fe-protocol3.c:968 fe-protocol3.c:983 fe-protocol3.c:1016 #: fe-protocol3.c:1724 fe-protocol3.c:2127 fe-secure-common.c:112 -#: fe-secure-gssapi.c:500 fe-secure-openssl.c:460 fe-secure-openssl.c:1272 +#: fe-secure-gssapi.c:500 fe-secure-openssl.c:455 fe-secure-openssl.c:1252 msgid "out of memory\n" msgstr "нехватка памяти\n" @@ -896,7 +896,7 @@ msgstr "функция pqPutInt не поддерживает integer разме msgid "connection not open\n" msgstr "соединение не открыто\n" -#: fe-misc.c:755 fe-secure-openssl.c:218 fe-secure-openssl.c:331 +#: fe-misc.c:755 fe-secure-openssl.c:213 fe-secure-openssl.c:326 #: fe-secure.c:262 fe-secure.c:430 #, c-format msgid "" @@ -1123,81 +1123,81 @@ msgstr "ошибка проверки размера в GSSAPI" msgid "GSSAPI context establishment error" msgstr "ошибка установления контекста в GSSAPI" -#: fe-secure-openssl.c:223 fe-secure-openssl.c:336 fe-secure-openssl.c:1512 +#: fe-secure-openssl.c:218 fe-secure-openssl.c:331 fe-secure-openssl.c:1492 #, c-format msgid "SSL SYSCALL error: %s\n" msgstr "ошибка SSL SYSCALL: %s\n" -#: fe-secure-openssl.c:230 fe-secure-openssl.c:343 fe-secure-openssl.c:1516 +#: fe-secure-openssl.c:225 fe-secure-openssl.c:338 fe-secure-openssl.c:1496 msgid "SSL SYSCALL error: EOF detected\n" msgstr "ошибка SSL SYSCALL: конец файла (EOF)\n" -#: fe-secure-openssl.c:241 fe-secure-openssl.c:354 fe-secure-openssl.c:1525 +#: fe-secure-openssl.c:236 fe-secure-openssl.c:349 fe-secure-openssl.c:1505 #, c-format msgid "SSL error: %s\n" msgstr "ошибка SSL: %s\n" -#: fe-secure-openssl.c:256 fe-secure-openssl.c:369 +#: fe-secure-openssl.c:251 fe-secure-openssl.c:364 msgid "SSL connection has been closed unexpectedly\n" msgstr "SSL-соединение было неожиданно закрыто\n" -#: fe-secure-openssl.c:262 fe-secure-openssl.c:375 fe-secure-openssl.c:1575 +#: fe-secure-openssl.c:257 fe-secure-openssl.c:370 fe-secure-openssl.c:1555 #, c-format msgid "unrecognized SSL error code: %d\n" msgstr "нераспознанный код ошибки SSL: %d\n" -#: fe-secure-openssl.c:420 +#: fe-secure-openssl.c:415 msgid "could not determine server certificate signature algorithm\n" msgstr "не удалось определить алгоритм подписи сертификата сервера\n" -#: fe-secure-openssl.c:441 +#: fe-secure-openssl.c:436 #, c-format msgid "could not find digest for NID %s\n" msgstr "не удалось найти алгоритм хеширования по NID %s\n" -#: fe-secure-openssl.c:451 +#: fe-secure-openssl.c:446 msgid "could not generate peer certificate hash\n" msgstr "не удалось сгенерировать хеш сертификата сервера\n" -#: fe-secure-openssl.c:508 +#: fe-secure-openssl.c:503 msgid "SSL certificate's name entry is missing\n" msgstr "в SSL-сертификате отсутствует запись имени\n" -#: fe-secure-openssl.c:543 +#: fe-secure-openssl.c:538 msgid "SSL certificate's address entry is missing\n" msgstr "в SSL-сертификате отсутствует запись адреса\n" -#: fe-secure-openssl.c:961 +#: fe-secure-openssl.c:940 #, c-format msgid "could not create SSL context: %s\n" msgstr "не удалось создать контекст SSL: %s\n" -#: fe-secure-openssl.c:1000 +#: fe-secure-openssl.c:979 #, c-format msgid "invalid value \"%s\" for minimum SSL protocol version\n" msgstr "неверное значение \"%s\" для минимальной версии протокола SSL\n" -#: fe-secure-openssl.c:1011 +#: fe-secure-openssl.c:990 #, c-format msgid "could not set minimum SSL protocol version: %s\n" msgstr "не удалось задать минимальную версию протокола SSL: %s\n" -#: fe-secure-openssl.c:1029 +#: fe-secure-openssl.c:1008 #, c-format msgid "invalid value \"%s\" for maximum SSL protocol version\n" msgstr "неверное значение \"%s\" для максимальной версии протокола SSL\n" -#: fe-secure-openssl.c:1040 +#: fe-secure-openssl.c:1019 #, c-format msgid "could not set maximum SSL protocol version: %s\n" msgstr "не удалось задать максимальную версию протокола SSL: %s\n" -#: fe-secure-openssl.c:1076 +#: fe-secure-openssl.c:1055 #, c-format msgid "could not read root certificate file \"%s\": %s\n" msgstr "не удалось прочитать файл корневых сертификатов \"%s\": %s\n" -#: fe-secure-openssl.c:1129 +#: fe-secure-openssl.c:1108 msgid "" "could not get home directory to locate root certificate file\n" "Either provide the file or change sslmode to disable server certificate " @@ -1207,7 +1207,7 @@ msgstr "" "Укажите полный путь к файлу или отключите проверку сертификата сервера, " "изменив sslmode.\n" -#: fe-secure-openssl.c:1133 +#: fe-secure-openssl.c:1112 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" @@ -1218,63 +1218,63 @@ msgstr "" "Укажите полный путь к файлу или отключите проверку сертификата сервера, " "изменив sslmode.\n" -#: fe-secure-openssl.c:1164 +#: fe-secure-openssl.c:1143 #, c-format msgid "could not open certificate file \"%s\": %s\n" msgstr "не удалось открыть файл сертификата \"%s\": %s\n" -#: fe-secure-openssl.c:1183 +#: fe-secure-openssl.c:1162 #, c-format msgid "could not read certificate file \"%s\": %s\n" msgstr "не удалось прочитать файл сертификата \"%s\": %s\n" -#: fe-secure-openssl.c:1208 +#: fe-secure-openssl.c:1187 #, c-format msgid "could not establish SSL connection: %s\n" msgstr "не удалось установить SSL-соединение: %s\n" -#: fe-secure-openssl.c:1242 +#: fe-secure-openssl.c:1221 #, c-format msgid "could not set SSL Server Name Indication (SNI): %s\n" msgstr "" "не удалось задать SNI (Server Name Indication) для SSL-подключения: %s\n" -#: fe-secure-openssl.c:1288 +#: fe-secure-openssl.c:1268 #, c-format msgid "could not load SSL engine \"%s\": %s\n" msgstr "не удалось загрузить модуль SSL ENGINE \"%s\": %s\n" -#: fe-secure-openssl.c:1300 +#: fe-secure-openssl.c:1280 #, c-format msgid "could not initialize SSL engine \"%s\": %s\n" msgstr "не удалось инициализировать модуль SSL ENGINE \"%s\": %s\n" -#: fe-secure-openssl.c:1316 +#: fe-secure-openssl.c:1296 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "не удалось прочитать закрытый ключ SSL \"%s\" из модуля \"%s\": %s\n" -#: fe-secure-openssl.c:1330 +#: fe-secure-openssl.c:1310 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "не удалось загрузить закрытый ключ SSL \"%s\" из модуля \"%s\": %s\n" -#: fe-secure-openssl.c:1368 +#: fe-secure-openssl.c:1348 #, c-format msgid "certificate present, but not private key file \"%s\"\n" msgstr "при наличии сертификата отсутствует файл закрытого ключа \"%s\"\n" -#: fe-secure-openssl.c:1372 +#: fe-secure-openssl.c:1352 #, c-format msgid "could not stat private key file \"%s\": %m\n" msgstr "не удалось получить информацию о файле закрытого ключа \"%s\": %m\n" -#: fe-secure-openssl.c:1381 +#: fe-secure-openssl.c:1361 #, c-format msgid "private key file \"%s\" is not a regular file\n" msgstr "файл закрытого ключа \"%s\" - не обычный файл\n" -#: fe-secure-openssl.c:1414 +#: fe-secure-openssl.c:1394 #, c-format msgid "" "private key file \"%s\" has group or world access; file must have " @@ -1286,17 +1286,17 @@ msgstr "" "текущему пользователю, либо u=rw,g=r (0640) или более строгие, если он " "принадлежит root\n" -#: fe-secure-openssl.c:1439 +#: fe-secure-openssl.c:1419 #, c-format msgid "could not load private key file \"%s\": %s\n" msgstr "не удалось загрузить файл закрытого ключа \"%s\": %s\n" -#: fe-secure-openssl.c:1456 +#: fe-secure-openssl.c:1436 #, c-format msgid "certificate does not match private key file \"%s\": %s\n" msgstr "сертификат не соответствует файлу закрытого ключа \"%s\": %s\n" -#: fe-secure-openssl.c:1558 +#: fe-secure-openssl.c:1538 #, c-format msgid "" "This may indicate that the server does not support any SSL protocol version " @@ -1305,22 +1305,22 @@ msgstr "" "Это может указывать на то, что сервер не поддерживает ни одну версию " "протокола SSL между %s и %s.\n" -#: fe-secure-openssl.c:1594 +#: fe-secure-openssl.c:1574 #, c-format msgid "certificate could not be obtained: %s\n" msgstr "не удалось получить сертификат: %s\n" -#: fe-secure-openssl.c:1700 +#: fe-secure-openssl.c:1681 #, c-format msgid "no SSL error reported" msgstr "нет сообщения об ошибке SSL" -#: fe-secure-openssl.c:1709 +#: fe-secure-openssl.c:1706 #, c-format msgid "SSL error code %lu" msgstr "код ошибки SSL: %lu" -#: fe-secure-openssl.c:1988 +#: fe-secure-openssl.c:1985 #, c-format msgid "WARNING: sslpassword truncated\n" msgstr "ПРЕДУПРЕЖДЕНИЕ: значение sslpassword усечено\n" diff --git a/src/interfaces/libpq/pthread-win32.c b/src/interfaces/libpq/pthread-win32.c index c0e056e..c9609c0 100644 --- a/src/interfaces/libpq/pthread-win32.c +++ b/src/interfaces/libpq/pthread-win32.c @@ -34,27 +34,33 @@ pthread_getspecific(pthread_key_t key) int pthread_mutex_init(pthread_mutex_t *mp, void *attr) { - *mp = (CRITICAL_SECTION *) malloc(sizeof(CRITICAL_SECTION)); - if (!*mp) - return 1; - InitializeCriticalSection(*mp); + mp->initstate = 0; return 0; } int pthread_mutex_lock(pthread_mutex_t *mp) { - if (!*mp) - return 1; - EnterCriticalSection(*mp); + /* Initialize the csection if not already done */ + if (mp->initstate != 1) + { + LONG istate; + + while ((istate = InterlockedExchange(&mp->initstate, 2)) == 2) + Sleep(0); /* wait, another thread is doing this */ + if (istate != 1) + InitializeCriticalSection(&mp->csection); + InterlockedExchange(&mp->initstate, 1); + } + EnterCriticalSection(&mp->csection); return 0; } int pthread_mutex_unlock(pthread_mutex_t *mp) { - if (!*mp) - return 1; - LeaveCriticalSection(*mp); + if (mp->initstate != 1) + return EINVAL; + LeaveCriticalSection(&mp->csection); return 0; } |