From 224149ab58fb0db7eff47c535e90b6c0f5cf2060 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Mon, 11 Feb 2013 21:43:41 +0800 Subject: [PATCH] fix ssl reject path for freeing header allocation If the SSL connection failed before the headers came, we were not dealing with deallocating the header malloc. This takes care of it. Using CyaSSL, we are then valgrind-clean for ssl client and server. With OpenSSL, there is 88 bytes lost at init that never changes or gets recovered. AFAIK there's nothing to do about that. OpenSSL also blows these during operation ==1059== Conditional jump or move depends on uninitialised value(s) ==1059== at 0x4A0B131: bcmp (mc_replace_strmem.c:935) ==1059== by 0x3014CDDBA8: ??? (in /usr/lib64/libcrypto.so.1.0.1c) ==1059== by 0x3015430852: tls1_enc (in /usr/lib64/libssl.so.1.0.1c) ==1059== by 0x3015428CEC: ssl3_read_bytes (in /usr/lib64/libssl.so.1.0.1c) ==1059== by 0x30154264C5: ??? (in /usr/lib64/libssl.so.1.0.1c) ==1059== by 0x4C3C596: lws_server_socket_service (server.c:153) ==1059== by 0x4C32C1E: libwebsocket_service_fd (libwebsockets.c:927) ==1059== by 0x4C33270: libwebsocket_service (libwebsockets.c:1225) ==1059== by 0x401C84: main (in /usr/bin/libwebsockets-test-server) However googling around https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/60021 http://www.openssl.org/support/faq.html#PROG13 (also the next FAQ down) it seems OpenSSL have a relaxed attitude to this and it's expected. It's interesting CyaSSL works fine but doesn't have that problem... Signed-off-by: Andy Green --- lib/client-handshake.c | 5 ++--- lib/parsers.c | 1 + lib/private-libwebsockets.h | 2 ++ lib/server.c | 6 +++++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/client-handshake.c b/lib/client-handshake.c index 76d4ce75..e8e497e2 100644 --- a/lib/client-handshake.c +++ b/lib/client-handshake.c @@ -89,7 +89,7 @@ struct libwebsocket *__libwebsocket_client_connect_2( if (n < 0) { compatible_close(wsi->sock); lwsl_debug("ERROR writing to proxy socket\n"); - goto bail1; + goto oom4; } libwebsocket_set_timeout(wsi, @@ -130,7 +130,6 @@ struct libwebsocket *__libwebsocket_client_connect_2( oom4: free(wsi->u.hdr.ah); -bail1: free(wsi); return NULL; @@ -183,7 +182,7 @@ libwebsocket_client_connect(struct libwebsocket_context *context, wsi = (struct libwebsocket *) malloc(sizeof(struct libwebsocket)); if (wsi == NULL) - goto bail1; + goto bail; memset(wsi, 0, sizeof(*wsi)); diff --git a/lib/parsers.c b/lib/parsers.c index 2d6aa3ca..4202d3a3 100644 --- a/lib/parsers.c +++ b/lib/parsers.c @@ -598,6 +598,7 @@ set_parsing_complete: lwsl_parser("v%02d hdrs completed\n", wsi->ietf_spec_revision); } wsi->u.hdr.parser_state = WSI_PARSING_COMPLETE; + wsi->hdr_parsing_completed = 1; return 0; } diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index d1699089..d93621db 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -372,6 +372,8 @@ struct libwebsocket { char lws_rx_parse_state; /* enum lws_rx_parse_state */ char rx_frame_type; /* enum libwebsocket_write_protocol */ + unsigned int hdr_parsing_completed:1; + char pending_timeout; /* enum pending_timeout */ unsigned long pending_timeout_limit; diff --git a/lib/server.c b/lib/server.c index e0f46c39..1b10a86a 100644 --- a/lib/server.c +++ b/lib/server.c @@ -102,6 +102,7 @@ libwebsocket_create_new_server_wsi(struct libwebsocket_context *context) new_wsi->state = WSI_STATE_HTTP; new_wsi->u.hdr.name_buffer_pos = 0; new_wsi->mode = LWS_CONNMODE_HTTP_SERVING; + new_wsi->hdr_parsing_completed = 0; if (lws_allocate_header_table(new_wsi)) { free(new_wsi); @@ -167,7 +168,10 @@ int lws_server_socket_service(struct libwebsocket_context *context, return 0; } if (!len) { - lwsl_info("lws_server_sktt_srv: read 0 len\n"); + lwsl_info("lws_server_skt_srv: read 0 len\n"); + /* lwsl_info(" state=%d\n", wsi->state); */ + if (!wsi->hdr_parsing_completed) + free(wsi->u.hdr.ah); libwebsocket_close_and_free_session( context, wsi, LWS_CLOSE_STATUS_NOSTATUS); return 0;