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