[Pkg-postgresql-public] Bug#718460: libpq5 not thread-safe
Nick Phillips
nwp at debian.org
Thu Aug 1 00:33:38 UTC 2013
Package: libpq5
Version: 9.1.9-1
Severity: normal
Tags: patch upstream
I've had crashes with glibc detecting double free/memory corruption through
mod_wsgi, Django, psycopg2, libpq, libssl.
Turns out that libpq is not thread-safe; it uses a global SSL_context and
does not protect its use of it appropriately, resulting in crashes in
libssl.
The point at which it had been affecting me was during the call to
SSL_CTX_use_certificate_chain_file in initialize_SSL in fe-secure.c
There are several further vulnerable uses of SSL_context later within that
function; the patch I'm attaching protects all of them using a single
call to pthread_mutex_lock -- I've not bothered to investigate whether
the subsequent uses of SSL_context are such that they require the context
not be modified by other threads in the interim, or whether it would be
safe to protect each use separately. I don't think the gain from doing
so would be significant anyway, as this section of code is only used once
during each connection setup.
While I am using postgres 9.1 from wheezy, I note that this issue is not
fixed in current postgres 9.3 beta2 upstream.
Cheers,
Nick
-- System Information:
Debian Release: 7.1
APT prefers stable
APT policy: (990, 'stable'), (500, 'stable-updates')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.32-5-xen-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_NZ.UTF-8, LC_CTYPE=en_NZ.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages libpq5 depends on:
ii libc6 2.13-38
ii libcomerr2 1.42.5-1.1
ii libgssapi-krb5-2 1.10.1+dfsg-5+deb7u1
ii libkrb5-3 1.10.1+dfsg-5+deb7u1
ii libldap-2.4-2 2.4.31-1+nmu2
ii libssl1.0.0 1.0.1e-2
libpq5 recommends no packages.
libpq5 suggests no packages.
-- no debconf information
===> patch follows
Description: libpq thread safety fix
Protect libpq use of global SSL_context with mutex.
Author: Nick Phillips <nwp at debian.org>
Forwarded: no
Last-Update: 2013-08-01
--- postgresql-9.1-9.1.9.orig/src/interfaces/libpq/fe-secure.c
+++ postgresql-9.1-9.1.9/src/interfaces/libpq/fe-secure.c
@@ -1089,6 +1089,10 @@ initialize_SSL(PGconn *conn)
* sslcert settings are used for different connections in the same
* process.
*/
+#ifdef ENABLE_THREAD_SAFETY
+ if (pthread_mutex_lock(&ssl_config_mutex))
+ return -1;
+#endif
if (SSL_CTX_use_certificate_chain_file(SSL_context, fnbuf) != 1)
{
char *err = SSLerrmessage();
@@ -1097,6 +1101,9 @@ initialize_SSL(PGconn *conn)
libpq_gettext("could not read certificate file \"%s\": %s\n"),
fnbuf, err);
SSLerrfree(err);
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
return -1;
}
if (SSL_use_certificate_file(conn->ssl, fnbuf, SSL_FILETYPE_PEM) != 1)
@@ -1107,6 +1114,9 @@ initialize_SSL(PGconn *conn)
libpq_gettext("could not read certificate file \"%s\": %s\n"),
fnbuf, err);
SSLerrfree(err);
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
return -1;
}
/* need to load the associated private key, too */
@@ -1145,6 +1155,9 @@ initialize_SSL(PGconn *conn)
engine_str, err);
SSLerrfree(err);
free(engine_str);
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
return -1;
}
@@ -1159,6 +1172,9 @@ initialize_SSL(PGconn *conn)
ENGINE_free(conn->engine);
conn->engine = NULL;
free(engine_str);
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
return -1;
}
@@ -1176,6 +1192,9 @@ initialize_SSL(PGconn *conn)
ENGINE_free(conn->engine);
conn->engine = NULL;
free(engine_str);
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
return -1;
}
if (SSL_use_PrivateKey(conn->ssl, pkey) != 1)
@@ -1190,6 +1209,9 @@ initialize_SSL(PGconn *conn)
ENGINE_free(conn->engine);
conn->engine = NULL;
free(engine_str);
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
return -1;
}
@@ -1242,6 +1264,9 @@ initialize_SSL(PGconn *conn)
libpq_gettext("could not load private key file \"%s\": %s\n"),
fnbuf, err);
SSLerrfree(err);
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
return -1;
}
}
@@ -1256,6 +1281,9 @@ initialize_SSL(PGconn *conn)
libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
fnbuf, err);
SSLerrfree(err);
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
return -1;
}
@@ -1284,6 +1312,9 @@ initialize_SSL(PGconn *conn)
libpq_gettext("could not read root certificate file \"%s\": %s\n"),
fnbuf, err);
SSLerrfree(err);
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
return -1;
}
@@ -1311,6 +1342,9 @@ initialize_SSL(PGconn *conn)
libpq_gettext("SSL library does not support CRL certificates (file \"%s\")\n"),
fnbuf);
SSLerrfree(err);
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
return -1;
#endif
}
@@ -1341,10 +1375,16 @@ initialize_SSL(PGconn *conn)
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("root certificate file \"%s\" does not exist\n"
"Either provide the file or change sslmode to disable server certificate verification.\n"), fnbuf);
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
return -1;
}
}
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
return 0;
}
More information about the Pkg-postgresql-public
mailing list