dovecot-2.2: lib-http: server: Fixed segfault occurring in conne...

dovecot at dovecot.org dovecot at dovecot.org
Wed Sep 10 10:44:03 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/7ccf5dd98be8
changeset: 17767:7ccf5dd98be8
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Wed Sep 10 13:39:37 2014 +0300
description:
lib-http: server: Fixed segfault occurring in connection input handler.
Request handlers could close and destroy the connection early.
Fixed by holding a reference in the input handler.

diffstat:

 src/lib-http/http-server-connection.c |  19 ++++++++++++++++---
 1 files changed, 16 insertions(+), 3 deletions(-)

diffs (70 lines):

diff -r 992f17769cca -r 7ccf5dd98be8 src/lib-http/http-server-connection.c
--- a/src/lib-http/http-server-connection.c	Wed Sep 10 13:39:36 2014 +0300
+++ b/src/lib-http/http-server-connection.c	Wed Sep 10 13:39:37 2014 +0300
@@ -426,12 +426,15 @@
 	/* parse requests */
 	ret = 1;
 	while (!conn->close_indicated && ret != 0) {
+		http_server_connection_ref(conn);
 		while ((ret = http_request_parse_next	(conn->http_parser,
 			req->pool, &req->req, &error_code, &error)) > 0) {
 
 			if (pending_request != NULL) {
 				/* previous request is now fully read and ready to respond */
 				http_server_request_ready_to_respond(pending_request);
+				if (conn->closed)
+					break;
 			}
 
 			http_server_connection_debug(conn,
@@ -452,6 +455,7 @@
 					http_server_request_destroy(&req);
 				else
 					http_server_request_unref(&req);
+				http_server_connection_unref(&conn);
 				return;
 			}
 			if (req->req.connection_close)
@@ -460,15 +464,16 @@
 				http_server_request_destroy(&req);
 			else
 				http_server_request_unref(&req);
-		
+
 			/* client indicated it will close after this request; stop trying
-			   to read more. */			   
-			if (conn->close_indicated)	
+			   to read more. */
+			if (conn->close_indicated)
 				break;
 
 			if (conn->request_queue_count >=
 				conn->server->set.max_pipelined_requests) {
 				http_server_connection_input_halt(conn);
+				http_server_connection_unref(&conn);
 				return;
 			}
 
@@ -476,6 +481,10 @@
 			req = http_server_request_new(conn);
 		}
 
+		http_server_connection_unref(&conn);
+		if (conn == NULL || conn->closed)
+			return;
+
 		if (ret <= 0 &&
 	    (conn->conn.input->eof || conn->conn.input->stream_errno != 0)) {
 			int stream_errno = conn->conn.input->stream_errno;
@@ -545,7 +554,11 @@
 		if (ret == 0 && pending_request != NULL &&
 			!http_request_parser_pending_payload(conn->http_parser)) {
 			/* previous request is now fully read and ready to respond */
+			http_server_connection_ref(conn);
 			http_server_request_ready_to_respond(pending_request);
+			http_server_connection_unref(&conn);
+			if (conn == NULL || conn->closed)
+				return;
 		}
 	}
 }


More information about the dovecot-cvs mailing list