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

b62b43
diff -up dovecot-2.3.8/src/imap/imap-client-hibernate.c.CVE_2020_24386-prereq1 dovecot-2.3.8/src/imap/imap-client-hibernate.c
b62b43
--- dovecot-2.3.8/src/imap/imap-client-hibernate.c.CVE_2020_24386-prereq1	2019-10-08 10:46:18.000000000 +0200
b62b43
+++ dovecot-2.3.8/src/imap/imap-client-hibernate.c	2021-01-08 17:14:40.051174282 +0100
b62b43
@@ -19,24 +19,26 @@
b62b43
 #define IMAP_HIBERNATE_SEND_TIMEOUT_SECS 10
b62b43
 #define IMAP_HIBERNATE_HANDSHAKE "VERSION\timap-hibernate\t1\t0\n"
b62b43
 
b62b43
-static int imap_hibernate_handshake(int fd, const char *path)
b62b43
+static int
b62b43
+imap_hibernate_handshake(int fd, const char *path, const char **error_r)
b62b43
 {
b62b43
 	char buf[1024];
b62b43
 	ssize_t ret;
b62b43
 
b62b43
 	if (write_full(fd, IMAP_HIBERNATE_HANDSHAKE,
b62b43
 		       strlen(IMAP_HIBERNATE_HANDSHAKE)) < 0) {
b62b43
-		i_error("write(%s) failed: %m", path);
b62b43
+		*error_r = t_strdup_printf("write(%s) failed: %m", path);
b62b43
 		return -1;
b62b43
 	} else if ((ret = read(fd, buf, sizeof(buf)-1)) < 0) {
b62b43
-		i_error("read(%s) failed: %m", path);
b62b43
+		*error_r = t_strdup_printf("read(%s) failed: %m", path);
b62b43
 		return -1;
b62b43
 	} else if (ret > 0 && buf[ret-1] == '\n') {
b62b43
 		buf[ret-1] = '\0';
b62b43
 		if (version_string_verify(buf, "imap-hibernate", 1))
b62b43
 			return 0;
b62b43
 	}
b62b43
-	i_error("%s sent invalid VERSION handshake: %s", path, buf);
b62b43
+	*error_r = t_strdup_printf("%s sent invalid VERSION handshake: %s",
b62b43
+				   path, buf);
b62b43
 	return -1;
b62b43
 }
b62b43
 
b62b43
@@ -105,40 +107,42 @@ static void imap_hibernate_write_cmd(str
b62b43
 
b62b43
 static int
b62b43
 imap_hibernate_process_send_cmd(int fd_socket, const char *path,
b62b43
-				const string_t *cmd, int fd_client)
b62b43
+				const string_t *cmd, int fd_client,
b62b43
+				const char **error_r)
b62b43
 {
b62b43
 	ssize_t ret;
b62b43
 
b62b43
 	i_assert(fd_socket != -1);
b62b43
 	i_assert(str_len(cmd) > 1);
b62b43
 
b62b43
-	if (imap_hibernate_handshake(fd_socket, path) < 0)
b62b43
+	if (imap_hibernate_handshake(fd_socket, path, error_r) < 0)
b62b43
 		return -1;
b62b43
 	if ((ret = fd_send(fd_socket, fd_client, str_data(cmd), 1)) < 0) {
b62b43
-		i_error("fd_send(%s) failed: %m", path);
b62b43
+		*error_r = t_strdup_printf("fd_send(%s) failed: %m", path);
b62b43
 		return -1;
b62b43
 	}
b62b43
 	if ((ret = write_full(fd_socket, str_data(cmd)+1, str_len(cmd)-1)) < 0) {
b62b43
-		i_error("write(%s) failed: %m", path);
b62b43
+		*error_r = t_strdup_printf("write(%s) failed: %m", path);
b62b43
 		return -1;
b62b43
 	}
b62b43
 	return 0;
b62b43
 }
b62b43
 
b62b43
-static int imap_hibernate_process_read(int fd, const char *path)
b62b43
+static int
b62b43
+imap_hibernate_process_read(int fd, const char *path, const char **error_r)
b62b43
 {
b62b43
 	char buf[1024];
b62b43
 	ssize_t ret;
b62b43
 
b62b43
 	if ((ret = read(fd, buf, sizeof(buf)-1)) < 0) {
b62b43
-		i_error("read(%s) failed: %m", path);
b62b43
+		*error_r = t_strdup_printf("read(%s) failed: %m", path);
b62b43
 		return -1;
b62b43
 	} else if (ret == 0) {
b62b43
-		i_error("%s disconnected", path);
b62b43
+		*error_r = t_strdup_printf("%s disconnected", path);
b62b43
 		return -1;
b62b43
 	} else if (buf[0] != '+') {
b62b43
 		buf[ret] = '\0';
b62b43
-		i_error("%s returned failure: %s", path,
b62b43
+		*error_r = t_strdup_printf("%s returned failure: %s", path,
b62b43
 			ret > 0 && buf[0] == '-' ? buf+1 : buf);
b62b43
 		return -1;
b62b43
 	} else {
b62b43
@@ -147,8 +151,8 @@ static int imap_hibernate_process_read(i
b62b43
 }
b62b43
 
b62b43
 static int
b62b43
-imap_hibernate_process_send(struct client *client,
b62b43
-			    const buffer_t *state, int fd_notify, int *fd_r)
b62b43
+imap_hibernate_process_send(struct client *client, const buffer_t *state,
b62b43
+			    int fd_notify, int *fd_r, const char **error_r)
b62b43
 {
b62b43
 	string_t *cmd = t_str_new(512);
b62b43
 	const char *path;
b62b43
@@ -171,14 +175,14 @@ imap_hibernate_process_send(struct clien
b62b43
 	imap_hibernate_write_cmd(client, cmd, state, fd_notify);
b62b43
 
b62b43
 	alarm(IMAP_HIBERNATE_SEND_TIMEOUT_SECS);
b62b43
-	if (imap_hibernate_process_send_cmd(fd, path, cmd, client->fd_in) < 0 ||
b62b43
-	    imap_hibernate_process_read(fd, path) < 0)
b62b43
+	if (imap_hibernate_process_send_cmd(fd, path, cmd, client->fd_in, error_r) < 0 ||
b62b43
+	    imap_hibernate_process_read(fd, path, error_r) < 0)
b62b43
 		ret = -1;
b62b43
 	else if (fd_notify != -1) {
b62b43
 		if ((ret = fd_send(fd, fd_notify, "\n", 1)) < 0)
b62b43
-			i_error("fd_send(%s) failed: %m", path);
b62b43
+			*error_r = t_strdup_printf("fd_send(%s) failed: %m", path);
b62b43
 		else
b62b43
-			ret = imap_hibernate_process_read(fd, path);
b62b43
+			ret = imap_hibernate_process_read(fd, path, error_r);
b62b43
 	}
b62b43
 	alarm(0);
b62b43
 	if (ret < 0) {
b62b43
@@ -229,8 +233,12 @@ bool imap_client_hibernate(struct client
b62b43
 		}
b62b43
 	}
b62b43
 	if (ret > 0) {
b62b43
-		if (imap_hibernate_process_send(client, state, fd_notify, &fd_hibernate) < 0)
b62b43
+		if (imap_hibernate_process_send(client, state, fd_notify,
b62b43
+						&fd_hibernate, &error) < 0) {
b62b43
+			e_error(client->event,
b62b43
+				"Couldn't hibernate imap client: %s", error);
b62b43
 			ret = -1;
b62b43
+		}
b62b43
 	}
b62b43
 	i_close_fd(&fd_notify);
b62b43
 	if (ret > 0) {