From: Timo Sirainen Date: Mon, 8 Aug 2016 16:16:57 +0000 (+0300) Subject: doveadm-server: Fixed potential hang when reading replies to multiple commands X-Git-Tag: 2.3.0.rc1~3211 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=be25bbb904b96f4c44602b2f96cf2d30f037fc93;p=thirdparty%2Fdovecot%2Fcore.git doveadm-server: Fixed potential hang when reading replies to multiple commands --- diff --git a/src/doveadm/server-connection.c b/src/doveadm/server-connection.c index f0c728ab24..9e20b6d4f5 100644 --- a/src/doveadm/server-connection.c +++ b/src/doveadm/server-connection.c @@ -59,6 +59,7 @@ struct server_connection { static struct server_connection *printing_conn = NULL; static void server_connection_input(struct server_connection *conn); +static bool server_connection_input_one(struct server_connection *conn); static void print_connection_released(void) { @@ -276,10 +277,7 @@ static void server_log_disconnect_error(struct server_connection *conn) static void server_connection_input(struct server_connection *conn) { - const unsigned char *data; - size_t size; const char *line; - int exit_code; if (!conn->handshaked) { if ((line = i_stream_read_next_line(conn->input)) == NULL) { @@ -326,24 +324,34 @@ static void server_connection_input(struct server_connection *conn) } } + while (server_connection_input_one(conn)) ; +} + +static bool server_connection_input_one(struct server_connection *conn) +{ + const unsigned char *data; + size_t size; + const char *line; + int exit_code; + data = i_stream_get_data(conn->input, &size); if (size == 0) - return; + return FALSE; switch (conn->state) { case SERVER_REPLY_STATE_DONE: i_error("doveadm server sent unexpected input"); server_connection_destroy(&conn); - return; + return FALSE; case SERVER_REPLY_STATE_PRINT: server_handle_input(conn, data, size); if (conn->state != SERVER_REPLY_STATE_RET) - break; + return FALSE; /* fall through */ case SERVER_REPLY_STATE_RET: line = i_stream_next_line(conn->input); if (line == NULL) - return; + return FALSE; if (line[0] == '+') server_connection_callback(conn, 0, ""); else if (line[0] == '-') { @@ -359,14 +367,16 @@ static void server_connection_input(struct server_connection *conn) i_error("doveadm server sent broken input " "(expected cmd reply): %s", line); server_connection_destroy(&conn); - break; + return FALSE; } if (conn->callback == NULL) { /* we're finished, close the connection */ server_connection_destroy(&conn); + return FALSE; } - break; + return TRUE; } + i_unreached(); } static int server_connection_read_settings(struct server_connection *conn)