nss: fix crash when closing HTTPS conn over HTTPS proxy

Truncated valgrind output capturing the crash follows:

Invalid read of size 8
   at 0x628B4A0: PR_Close (priometh.c:104)
   by 0x43C088: nss_close (nss.c:1356)
   by 0x43C17F: Curl_nss_close (nss.c:1377)
   by 0x438F42: Curl_ssl_close (vtls.c:618)
   by 0x45460B: Curl_disconnect (url.c:3000)
   by 0x42EACA: close_all_connections (multi.c:1887)
   by 0x42EB37: curl_multi_cleanup (multi.c:1907)
   by 0x44B4CA: Curl_close (url.c:427)
   by 0x4282C2: curl_easy_cleanup (easy.c:859)
   by 0x41341C: main_free (tool_main.c:206)
   by 0x4134F4: main (tool_main.c:260)
 Address 0x99afa10 is 0 bytes inside a block of size 48 free'd
   at 0x4C29D6A: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x62A2C33: pt_Close (ptio.c:1277)
   by 0x43BACD: nspr_io_close (nss.c:1141)
   by 0x54D6E25: ssl_DefClose (ssldef.c:203)
   by 0x43BACD: nspr_io_close (nss.c:1141)
   by 0x54D6E25: ssl_DefClose (ssldef.c:203)
   by 0x43C088: nss_close (nss.c:1356)
   by 0x43C173: Curl_nss_close (nss.c:1376)
   by 0x438F42: Curl_ssl_close (vtls.c:618)
   by 0x45460B: Curl_disconnect (url.c:3000)
   by 0x42EACA: close_all_connections (multi.c:1887)
   by 0x42EB37: curl_multi_cleanup (multi.c:1907)
 Block was alloc'd at
   at 0x4C28C50: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x6289F71: _PR_Getfd (prfdcach.c:103)
   by 0x62A4816: pt_SetMethods.isra.13 (ptio.c:3303)
   by 0x62A56E5: PR_ImportTCPSocket (ptio.c:4577)
   by 0x43D4D0: nss_setup_connect (nss.c:1733)
   by 0x43DDCA: nss_connect_common (nss.c:1929)
   by 0x43DF1E: Curl_nss_connect_nonblocking (nss.c:1985)
   by 0x4386CE: Curl_ssl_connect_nonblocking (vtls.c:364)
   by 0x47F02C: https_proxy_connect (http_proxy.c:58)
   by 0x47F086: Curl_proxy_connect (http_proxy.c:74)
   by 0x445891: Curl_http_connect (http.c:1348)
   by 0x42D613: multi_runsingle (multi.c:1233)
This commit is contained in:
Kamil Dudka
2015-12-16 00:28:02 +01:00
parent e21bd4ecb5
commit 3e7a1ff9a6

View File

@@ -1338,21 +1338,26 @@ Curl_nss_check_cxn(struct connectdata *conn)
static void nss_close(struct ssl_connect_data *connssl)
{
/* before the cleanup, check whether we are using a client certificate */
const bool client_cert = (connssl->client_nickname != NULL)
|| (connssl->obj_clicert != NULL);
free(connssl->client_nickname);
connssl->client_nickname = NULL;
/* destroy all NSS objects in order to avoid failure of NSS shutdown */
Curl_llist_destroy(connssl->obj_list, NULL);
connssl->obj_list = NULL;
connssl->obj_clicert = NULL;
if(connssl->handle) {
if((connssl->client_nickname != NULL) || (connssl->obj_clicert != NULL))
if(client_cert)
/* A server might require different authentication based on the
* particular path being requested by the client. To support this
* scenario, we must ensure that a connection will never reuse the
* authentication data from a previous connection. */
SSL_InvalidateSession(connssl->handle);
free(connssl->client_nickname);
connssl->client_nickname = NULL;
/* destroy all NSS objects in order to avoid failure of NSS shutdown */
Curl_llist_destroy(connssl->obj_list, NULL);
connssl->obj_list = NULL;
connssl->obj_clicert = NULL;
PR_Close(connssl->handle);
connssl->handle = NULL;
}
@@ -1373,6 +1378,11 @@ void Curl_nss_close(struct connectdata *conn, int sockindex)
conn->sock[sockindex] = CURL_SOCKET_BAD;
}
if(connssl->handle)
/* nss_close(connssl) will transitively close also connssl_proxy->handle
if both are used. Clear it to avoid a double close leading to crash. */
connssl_proxy->handle = NULL;
nss_close(connssl);
nss_close(connssl_proxy);
}