From: Timo Sirainen Date: Thu, 6 Oct 2016 10:09:46 +0000 (+0300) Subject: imapc: Added imapc_max_line_length to limit maximum memory usage. X-Git-Tag: 2.3.0.rc1~2945 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c23ebb9b0e0b760ca8da16fde34ff33f5ece5e07;p=thirdparty%2Fdovecot%2Fcore.git imapc: Added imapc_max_line_length to limit maximum memory usage. The default is still unlimited, but this should be set to something smaller for untrusted servers. --- diff --git a/src/lib-imap-client/imapc-client.c b/src/lib-imap-client/imapc-client.c index 58d1cac30f..46bc38d196 100644 --- a/src/lib-imap-client/imapc-client.c +++ b/src/lib-imap-client/imapc-client.c @@ -69,6 +69,8 @@ imapc_client_init(const struct imapc_client_settings *set) IMAPC_DEFAULT_CONNECT_TIMEOUT_MSECS; client->set.cmd_timeout_msecs = set->cmd_timeout_msecs != 0 ? set->cmd_timeout_msecs : IMAPC_DEFAULT_COMMAND_TIMEOUT_MSECS; + client->set.max_line_length = set->max_line_length != 0 ? + set->max_line_length : IMAPC_DEFAULT_MAX_LINE_LENGTH; client->set.throttle_set = set->throttle_set; if (client->set.throttle_set.init_msecs == 0) diff --git a/src/lib-imap-client/imapc-client.h b/src/lib-imap-client/imapc-client.h index 1b3010cba5..69583302ef 100644 --- a/src/lib-imap-client/imapc-client.h +++ b/src/lib-imap-client/imapc-client.h @@ -56,6 +56,7 @@ enum imapc_client_ssl_mode { #define IMAPC_DEFAULT_CONNECT_TIMEOUT_MSECS (1000*30) #define IMAPC_DEFAULT_COMMAND_TIMEOUT_MSECS (1000*60*5) +#define IMAPC_DEFAULT_MAX_LINE_LENGTH ((size_t)-1) struct imapc_throttling_settings { unsigned int init_msecs; @@ -93,6 +94,10 @@ struct imapc_client_settings { sent or received. 0 = default. */ unsigned int cmd_timeout_msecs; + /* Maximum allowed line length (not including literals read as + streams). 0 = unlimited. */ + size_t max_line_length; + struct imapc_throttling_settings throttle_set; }; diff --git a/src/lib-imap-client/imapc-connection.c b/src/lib-imap-client/imapc-connection.c index 105ce3a85a..4a4f364a95 100644 --- a/src/lib-imap-client/imapc-connection.c +++ b/src/lib-imap-client/imapc-connection.c @@ -1437,11 +1437,15 @@ static void imapc_connection_input(struct imapc_connection *conn) imapc_connection_input_pending(conn); if (ret < 0) { - /* disconnected */ + /* disconnected or buffer full */ str = t_str_new(128); if (conn->disconnect_reason != NULL) { str_printfa(str, "Server disconnected with message: %s", conn->disconnect_reason); + } else if (ret == -2) { + str_printfa(str, "Server sent too large input " + "(buffer full at %"PRIuSIZE_T")", + i_stream_get_data_size(conn->input)); } else if (conn->ssl_iostream == NULL) { errstr = conn->input->stream_errno == 0 ? "EOF" : i_stream_get_error(conn->input); @@ -1640,7 +1644,8 @@ static void imapc_connection_connect_next_ip(struct imapc_connection *conn) } } conn->fd = fd; - conn->input = conn->raw_input = i_stream_create_fd(fd, (size_t)-1); + conn->input = conn->raw_input = + i_stream_create_fd(fd, conn->client->set.max_line_length); conn->output = conn->raw_output = o_stream_create_fd(fd, (size_t)-1); o_stream_set_no_error_handling(conn->output, TRUE); @@ -1653,7 +1658,8 @@ static void imapc_connection_connect_next_ip(struct imapc_connection *conn) o_stream_set_flush_callback(conn->output, imapc_connection_output, conn); conn->io = io_add(fd, IO_WRITE, imapc_connection_connected, conn); - conn->parser = imap_parser_create(conn->input, NULL, (size_t)-1); + conn->parser = imap_parser_create(conn->input, NULL, + conn->client->set.max_line_length); conn->to = timeout_add(conn->client->set.connect_timeout_msecs, imapc_connection_timeout, conn); conn->to_output = timeout_add(conn->client->set.max_idle_time*1000, diff --git a/src/lib-storage/index/imapc/imapc-settings.c b/src/lib-storage/index/imapc/imapc-settings.c index 2bbf274fc7..58d015768a 100644 --- a/src/lib-storage/index/imapc/imapc-settings.c +++ b/src/lib-storage/index/imapc/imapc-settings.c @@ -30,6 +30,7 @@ static const struct setting_define imapc_setting_defines[] = { DEF(SET_STR, imapc_list_prefix), DEF(SET_TIME, imapc_cmd_timeout), DEF(SET_TIME, imapc_max_idle_time), + DEF(SET_SIZE, imapc_max_line_length), DEF(SET_STR, pop3_deleted_flag), @@ -53,6 +54,7 @@ static const struct imapc_settings imapc_default_settings = { .imapc_list_prefix = "", .imapc_cmd_timeout = 5*60, .imapc_max_idle_time = 60*29, + .imapc_max_line_length = 0, .pop3_deleted_flag = "" }; diff --git a/src/lib-storage/index/imapc/imapc-settings.h b/src/lib-storage/index/imapc/imapc-settings.h index fa8be08492..afbdf34f76 100644 --- a/src/lib-storage/index/imapc/imapc-settings.h +++ b/src/lib-storage/index/imapc/imapc-settings.h @@ -36,6 +36,7 @@ struct imapc_settings { const char *imapc_list_prefix; unsigned int imapc_cmd_timeout; unsigned int imapc_max_idle_time; + uoff_t imapc_max_line_length; const char *pop3_deleted_flag; diff --git a/src/lib-storage/index/imapc/imapc-storage.c b/src/lib-storage/index/imapc/imapc-storage.c index 4c7e1a3eae..eee8dfe817 100644 --- a/src/lib-storage/index/imapc/imapc-storage.c +++ b/src/lib-storage/index/imapc/imapc-storage.c @@ -281,6 +281,7 @@ int imapc_storage_client_create(struct mail_namespace *ns, set.use_proxyauth = (imapc_set->parsed_features & IMAPC_FEATURE_PROXYAUTH) != 0; set.cmd_timeout_msecs = imapc_set->imapc_cmd_timeout * 1000; set.max_idle_time = imapc_set->imapc_max_idle_time; + set.max_line_length = imapc_set->imapc_max_line_length; set.dns_client_socket_path = *ns->user->set->base_dir == '\0' ? "" : t_strconcat(ns->user->set->base_dir, "/", DNS_CLIENT_SOCKET_NAME, NULL);