From: Timo Sirainen Date: Mon, 2 Feb 2026 22:39:31 +0000 (+0200) Subject: imap-hibernate: Fix potential crash after fd_send() failure X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7bb4310a9f1741b04a9104dcb0ce85c7a6e3d19;p=thirdparty%2Fdovecot%2Fcore.git imap-hibernate: Fix potential crash after fd_send() failure connection_input_parse_lines() accessed the already freed conn struct after input_line() destroyed the connection. --- diff --git a/src/imap-hibernate/imap-client.c b/src/imap-hibernate/imap-client.c index 99e06c7e9c..4c2fb4bc0a 100644 --- a/src/imap-hibernate/imap-client.c +++ b/src/imap-hibernate/imap-client.c @@ -148,7 +148,7 @@ imap_client_parse_userdb_fields(struct imap_client *client, } } -static void +static int imap_client_move_back_send_callback(void *context, struct ostream *output) { struct imap_client *client = context; @@ -239,7 +239,7 @@ imap_client_move_back_send_callback(void *context, struct ostream *output) const char *error = t_strdup_printf( "fd_send(%s) failed: %m", o_stream_get_name(output)); imap_client_unhibernate_failed(&client, error); - return; + return -1; } /* If unhibernation fails after this, shutdown() the fd to make sure the imap process won't later on finish unhibernation after all and @@ -247,6 +247,7 @@ imap_client_move_back_send_callback(void *context, struct ostream *output) client->shutdown_fd_on_destroy = TRUE; i_assert(ret > 0); o_stream_nsend(output, str_data(str) + 1, str_len(str) - 1); + return 0; } static void diff --git a/src/imap-hibernate/imap-master-connection.c b/src/imap-hibernate/imap-master-connection.c index 71fa4dd5cc..303dfd3eb9 100644 --- a/src/imap-hibernate/imap-master-connection.c +++ b/src/imap-hibernate/imap-master-connection.c @@ -104,8 +104,7 @@ imap_master_client_input_line(struct connection *_conn, const char *line) if (connection_input_line_default(_conn, line) < 0) return -1; - conn->send_callback(conn->context, _conn->output); - return 1; + return conn->send_callback(conn->context, _conn->output) < 0 ? -1 : 1; } else { imap_master_read_callback(&conn, line); /* we're finished now with this connection - disconnect it */ diff --git a/src/imap-hibernate/imap-master-connection.h b/src/imap-hibernate/imap-master-connection.h index 0ff2f3c611..a3553c07b9 100644 --- a/src/imap-hibernate/imap-master-connection.h +++ b/src/imap-hibernate/imap-master-connection.h @@ -3,7 +3,7 @@ struct imap_master_connection; -typedef void +typedef int imap_master_connection_send_callback_t(void *context, struct ostream *output); typedef void imap_master_connection_read_callback_t(void *context, const char *reply);