]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Added imapc_max_line_length to limit maximum memory usage.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 6 Oct 2016 10:09:46 +0000 (13:09 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 6 Oct 2016 11:08:58 +0000 (14:08 +0300)
The default is still unlimited, but this should be set to something smaller
for untrusted servers.

src/lib-imap-client/imapc-client.c
src/lib-imap-client/imapc-client.h
src/lib-imap-client/imapc-connection.c
src/lib-storage/index/imapc/imapc-settings.c
src/lib-storage/index/imapc/imapc-settings.h
src/lib-storage/index/imapc/imapc-storage.c

index 58d1cac30f991d01630338e3a401a92316873f09..46bc38d19692abde37fca52f7c5e86647b79776c 100644 (file)
@@ -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)
index 1b3010cba55d7e9cee034faac70224280659308b..69583302ef94782fb44c7bca9d900f147ccf458a 100644 (file)
@@ -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;
 };
 
index 105ce3a85a06d401cadb71bde26b69a3407019af..4a4f364a950aed9ce96c2005c4f5ebf5f669005a 100644 (file)
@@ -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,
index 2bbf274fc740af8a416bf23d6a431afcca986e99..58d015768a6d882f0d1df348a97ce73fbc34de77 100644 (file)
@@ -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 = ""
 };
index fa8be08492fa0283ff86875d11b86863a63e5961..afbdf34f760d0f46afab03c9bdb8e35a7a6a3b5a 100644 (file)
@@ -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;
 
index 4c7e1a3eae297f1086a178bbc6e0ec3f505bfd6d..eee8dfe817cc49a9eb69f7f4156b51b6872c193b 100644 (file)
@@ -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);