From 697b4f75fccbb5eda530211f3ef58c2b226c5461 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 10 Mar 2016 20:59:30 -0500 Subject: [PATCH] Clear OpenSSL error queue before OpenSSL calls OpenSSL requires that the error queue be cleared before certain OpenSSL API calls, so that you can be sure that the error you are checking afterwards actually come from you and was not left over from other activity. We had never done that, which appears to have worked as long as we are the only users of OpenSSL in the process. But if a process using libpq or a backend plugin uses OpenSSL as well, this can lead to confusion and crashes. see bug #12799 and https://bugs.php.net/bug.php?id=68276 based on patches by Dave Vitek and Peter Geoghegan --- src/backend/libpq/be-secure-openssl.c | 3 +++ src/interfaces/libpq/fe-secure-openssl.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 1e3dfb6..be337f5 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -353,6 +353,7 @@ be_tls_open_server(Port *port) port->ssl_in_use = true; aloop: + ERR_clear_error(); r = SSL_accept(port->ssl); if (r <= 0) { @@ -501,6 +502,7 @@ be_tls_read(Port *port, void *ptr, size_t len, int *waitfor) int err; errno = 0; + ERR_clear_error(); n = SSL_read(port->ssl, ptr, len); err = SSL_get_error(port->ssl, n); switch (err) @@ -558,6 +560,7 @@ be_tls_write(Port *port, void *ptr, size_t len, int *waitfor) int err; errno = 0; + ERR_clear_error(); n = SSL_write(port->ssl, ptr, len); err = SSL_get_error(port->ssl, n); switch (err) diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 133546b..0535338 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -212,6 +212,7 @@ pgtls_read(PGconn *conn, void *ptr, size_t len) rloop: SOCK_ERRNO_SET(0); + ERR_clear_error(); n = SSL_read(conn->ssl, ptr, len); err = SSL_get_error(conn->ssl, n); switch (err) @@ -320,6 +321,7 @@ pgtls_write(PGconn *conn, const void *ptr, size_t len) int err; SOCK_ERRNO_SET(0); + ERR_clear_error(); n = SSL_write(conn->ssl, ptr, len); err = SSL_get_error(conn->ssl, n); switch (err) @@ -1327,6 +1329,7 @@ open_client_SSL(PGconn *conn) { int r; + ERR_clear_error(); r = SSL_connect(conn->ssl); if (r <= 0) { -- 2.7.2