Blame SOURCES/dovecot-2.3.13-CVE_2020_24386-part4.patch

b62b43
From 1a27cfa8e337b7e3298ba230059e766cdbc1123d Mon Sep 17 00:00:00 2001
b62b43
From: Timo Sirainen <timo.sirainen@open-xchange.com>
b62b43
Date: Mon, 24 Aug 2020 19:10:43 +0300
b62b43
Subject: [PATCH] imap: imap_client_hibernate() - Return reason string on
b62b43
 failure
b62b43
b62b43
This helps writing a unit test for it.
b62b43
---
b62b43
 src/imap/cmd-idle.c              |  3 ++-
b62b43
 src/imap/imap-client-hibernate.c | 10 +++++++++-
b62b43
 src/imap/imap-client.h           |  5 +++--
b62b43
 3 files changed, 14 insertions(+), 4 deletions(-)
b62b43
b62b43
diff --git a/src/imap/cmd-idle.c b/src/imap/cmd-idle.c
b62b43
index 8a05582d03..2b31dc714e 100644
b62b43
--- a/src/imap/cmd-idle.c
b62b43
+++ b/src/imap/cmd-idle.c
b62b43
@@ -175,11 +175,12 @@ static void idle_add_keepalive_timeout(struct cmd_idle_context *ctx)
b62b43
 static void idle_hibernate_timeout(struct cmd_idle_context *ctx)
b62b43
 {
b62b43
 	struct client *client = ctx->client;
b62b43
+	const char *reason;
b62b43
 
b62b43
 	i_assert(ctx->sync_ctx == NULL);
b62b43
 	i_assert(!ctx->sync_pending);
b62b43
 
b62b43
-	if (imap_client_hibernate(&client)) {
b62b43
+	if (imap_client_hibernate(&client, &reason)) {
b62b43
 		/* client may be destroyed now */
b62b43
 	} else {
b62b43
 		/* failed - don't bother retrying */
b62b43
diff --git a/src/imap/imap-client-hibernate.c b/src/imap/imap-client-hibernate.c
b62b43
index d3451b1bf6..0709e4a244 100644
b62b43
--- a/src/imap/imap-client-hibernate.c
b62b43
+++ b/src/imap/imap-client-hibernate.c
b62b43
@@ -203,19 +203,23 @@ imap_hibernate_process_send(struct client *client, const buffer_t *state,
b62b43
 	return 0;
b62b43
 }
b62b43
 
b62b43
-bool imap_client_hibernate(struct client **_client)
b62b43
+bool imap_client_hibernate(struct client **_client, const char **reason_r)
b62b43
 {
b62b43
 	struct client *client = *_client;
b62b43
 	buffer_t *state;
b62b43
 	const char *error;
b62b43
 	int ret, fd_notify = -1, fd_hibernate = -1;
b62b43
 
b62b43
+	*reason_r = NULL;
b62b43
+
b62b43
 	if (client->fd_in != client->fd_out) {
b62b43
 		/* we won't try to hibernate stdio clients */
b62b43
+		*reason_r = "stdio clients can't be hibernated";
b62b43
 		return FALSE;
b62b43
 	}
b62b43
 	if (o_stream_get_buffer_used_size(client->output) > 0) {
b62b43
 		/* wait until we've sent the pending output to client */
b62b43
+		*reason_r = "output pending to client";
b62b43
 		return FALSE;
b62b43
 	}
b62b43
 
b62b43
@@ -233,11 +237,13 @@ bool imap_client_hibernate(struct client **_client)
b62b43
 			"Couldn't export state: %s (mailbox=%s)", error,
b62b43
 			client->mailbox == NULL ? "" :
b62b43
 			mailbox_get_vname(client->mailbox));
b62b43
+		*reason_r = error;
b62b43
 	} else if (ret == 0) {
b62b43
 		e_debug(client->event, "Couldn't hibernate imap client: "
b62b43
 			"Couldn't export state: %s (mailbox=%s)", error,
b62b43
 			client->mailbox == NULL ? "" :
b62b43
 			mailbox_get_vname(client->mailbox));
b62b43
+		*reason_r = error;
b62b43
 	}
b62b43
 	if (ret > 0 && client->mailbox != NULL) {
b62b43
 		fd_notify = mailbox_watch_extract_notify_fd(client->mailbox,
b62b43
@@ -248,6 +254,7 @@ bool imap_client_hibernate(struct client **_client)
b62b43
 			e_debug(client->event, "Couldn't hibernate imap client: "
b62b43
 				"Couldn't extract notifications fd: %s",
b62b43
 				error);
b62b43
+			*reason_r = error;
b62b43
 			ret = -1;
b62b43
 		}
b62b43
 	}
b62b43
@@ -257,5 +264,6 @@ bool imap_client_hibernate(struct client **_client)
b62b43
 			e_error(client->event,
b62b43
 				"Couldn't hibernate imap client: %s", error);
b62b43
+			*reason_r = error;
b62b43
 			ret = -1;
b62b43
 		}
b62b43
 	}
b62b43
diff --git a/src/imap/imap-client.h b/src/imap/imap-client.h
b62b43
index f2ffe0d7c9..4e591d5c7c 100644
b62b43
--- a/src/imap/imap-client.h
b62b43
+++ b/src/imap/imap-client.h
b62b43
@@ -323,8 +323,9 @@ enum mailbox_feature client_enabled_mailbox_features(struct client *client);
b62b43
 const char *const *client_enabled_features(struct client *client);
b62b43
 
b62b43
 /* Send client processing to imap-idle process. If successful, returns TRUE
b62b43
-   and destroys the client. */
b62b43
-bool imap_client_hibernate(struct client **client);
b62b43
+   and destroys the client. If hibernation failed, the exact reason is
b62b43
+   returned (mainly for unit tests). */
b62b43
+bool imap_client_hibernate(struct client **client, const char **reason_r);
b62b43
 
b62b43
 struct imap_search_update *
b62b43
 client_search_update_lookup(struct client *client, const char *tag,