dovecot-2.0: imap: Fixed infinite loop / memory eating with SEAR...

dovecot at dovecot.org dovecot at dovecot.org
Tue Feb 22 12:00:16 EET 2011


details:   http://hg.dovecot.org/dovecot-2.0/rev/3053befe6a64
changeset: 12616:3053befe6a64
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Feb 22 11:59:57 2011 +0200
description:
imap: Fixed infinite loop / memory eating with SEARCHRES + pipelining $.
If SEARCH RETURN (SAVE) command was running long enough so that Dovecot
started executing the next command, and if that command used $ in
messageset, Dovecot went into infinite function recursion.

diffstat:

 src/imap/imap-client.c |  20 ++++++++++++++++----
 src/imap/imap-client.h |   1 +
 2 files changed, 17 insertions(+), 4 deletions(-)

diffs (72 lines):

diff -r 324f9ca60539 -r 3053befe6a64 src/imap/imap-client.c
--- a/src/imap/imap-client.c	Tue Feb 22 11:14:31 2011 +0200
+++ b/src/imap/imap-client.c	Tue Feb 22 11:59:57 2011 +0200
@@ -432,7 +432,7 @@
 	return NULL;
 }
 
-static bool client_command_check_ambiguity(struct client_command_context *cmd)
+static bool client_command_is_ambiguous(struct client_command_context *cmd)
 {
 	enum command_flags flags;
 	enum client_command_state max_state =
@@ -443,6 +443,17 @@
 	    !imap_sync_is_allowed(cmd->client))
 		return TRUE;
 
+	if (cmd->search_save_result_used) {
+		/* if there are pending commands that update the search
+		   save result, wait */
+		struct client_command_context *old_cmd = cmd->next;
+
+		for (; old_cmd != NULL; old_cmd = old_cmd->next) {
+			if (old_cmd->search_save_result)
+				return TRUE;
+		}
+	}
+
 	if ((cmd->cmd_flags & COMMAND_FLAG_BREAKS_MAILBOX) ==
 	    COMMAND_FLAG_BREAKS_MAILBOX) {
 		/* there must be no other command running that uses the
@@ -578,11 +589,11 @@
 
 		/* the command is waiting for existing ambiguity causing
 		   commands to finish. */
-		if (client_command_check_ambiguity(cmd)) {
+		if (client_command_is_ambiguous(cmd)) {
 			/* we could be waiting for existing sync to finish */
 			if (!cmd_sync_delayed(client))
 				return;
-			if (client_command_check_ambiguity(cmd))
+			if (client_command_is_ambiguous(cmd))
 				return;
 		}
 		cmd->state = CLIENT_COMMAND_STATE_WAIT_INPUT;
@@ -690,7 +701,7 @@
 	} else if ((command = command_find(cmd->name)) != NULL) {
 		cmd->func = command->func;
 		cmd->cmd_flags = command->flags;
-		if (client_command_check_ambiguity(cmd)) {
+		if (client_command_is_ambiguous(cmd)) {
 			/* do nothing until existing commands are finished */
 			i_assert(cmd->state == CLIENT_COMMAND_STATE_WAIT_INPUT);
 			cmd->state = CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY;
@@ -907,6 +918,7 @@
 	i_assert(cmd->state == CLIENT_COMMAND_STATE_WAIT_INPUT);
 	cmd->client->input_lock = cmd;
 	cmd->state = CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY;
+	cmd->search_save_result_used = TRUE;
 	io_remove(&cmd->client->io);
 	return TRUE;
 }
diff -r 324f9ca60539 -r 3053befe6a64 src/imap/imap-client.h
--- a/src/imap/imap-client.h	Tue Feb 22 11:14:31 2011 +0200
+++ b/src/imap/imap-client.h	Tue Feb 22 11:59:57 2011 +0200
@@ -82,6 +82,7 @@
 	unsigned int cancel:1; /* command is wanted to be cancelled */
 	unsigned int param_error:1;
 	unsigned int search_save_result:1; /* search result is being updated */
+	unsigned int search_save_result_used:1; /* command uses search save */
 	unsigned int temp_executed:1; /* temporary execution state tracking */
 };
 


More information about the dovecot-cvs mailing list