diff options
author | Noah Misch <noah@leadboat.com> | 2015-05-18 10:02:31 -0400 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2015-05-18 10:02:31 -0400 |
commit | b0ce385032d72d6acf1e330f733013553fe6affe (patch) | |
tree | eeb158b7e34bc5cda085464767eee2274b0a5407 /src/backend/libpq/pqcomm.c | |
parent | 8cc7a4c5fdbe43b9b16b4cf3e07c8115107a8d4e (diff) | |
download | postgresql-b0ce385032d72d6acf1e330f733013553fe6affe.tar.gz postgresql-b0ce385032d72d6acf1e330f733013553fe6affe.zip |
Prevent a double free by not reentering be_tls_close().
Reentering this function with the right timing caused a double free,
typically crashing the backend. By synchronizing a disconnection with
the authentication timeout, an unauthenticated attacker could achieve
this somewhat consistently. Call be_tls_close() solely from within
proc_exit_prepare(). Back-patch to 9.0 (all supported versions).
Benkocs Norbert Attila
Security: CVE-2015-3165
Diffstat (limited to 'src/backend/libpq/pqcomm.c')
-rw-r--r-- | src/backend/libpq/pqcomm.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index fcdbfcea07b..6667cf94c64 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -220,32 +220,45 @@ socket_comm_reset(void) /* -------------------------------- * socket_close - shutdown libpq at backend exit * - * Note: in a standalone backend MyProcPort will be null, - * don't crash during exit... + * This is the one pg_on_exit_callback in place during BackendInitialize(). + * That function's unusual signal handling constrains that this callback be + * safe to run at any instant. * -------------------------------- */ static void socket_close(int code, Datum arg) { + /* Nothing to do in a standalone backend, where MyProcPort is NULL. */ if (MyProcPort != NULL) { #if defined(ENABLE_GSS) || defined(ENABLE_SSPI) #ifdef ENABLE_GSS OM_uint32 min_s; - /* Shutdown GSSAPI layer */ + /* + * Shutdown GSSAPI layer. This section does nothing when interrupting + * BackendInitialize(), because pg_GSS_recvauth() makes first use of + * "ctx" and "cred". + */ if (MyProcPort->gss->ctx != GSS_C_NO_CONTEXT) gss_delete_sec_context(&min_s, &MyProcPort->gss->ctx, NULL); if (MyProcPort->gss->cred != GSS_C_NO_CREDENTIAL) gss_release_cred(&min_s, &MyProcPort->gss->cred); #endif /* ENABLE_GSS */ - /* GSS and SSPI share the port->gss struct */ + /* + * GSS and SSPI share the port->gss struct. Since nowhere else does a + * postmaster child free this, doing so is safe when interrupting + * BackendInitialize(). + */ free(MyProcPort->gss); #endif /* ENABLE_GSS || ENABLE_SSPI */ - /* Cleanly shut down SSL layer */ + /* + * Cleanly shut down SSL layer. Nowhere else does a postmaster child + * call this, so this is safe when interrupting BackendInitialize(). + */ secure_close(MyProcPort); /* |