Mercurial > dovecot > original-hg > dovecot-2.2
changeset 17767:7ccf5dd98be8
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.
author | Stephan Bosch <stephan@rename-it.nl> |
---|---|
date | Wed, 10 Sep 2014 13:39:37 +0300 |
parents | 992f17769cca |
children | 4e339d81e1d2 |
files | src/lib-http/http-server-connection.c |
diffstat | 1 files changed, 16 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- 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; } } }