From: Phil Carmody Date: Wed, 31 Aug 2016 17:14:41 +0000 (+0300) Subject: Fix control flow and T_BEGIN/T_END hygiene X-Git-Tag: 2.3.0.rc1~3093 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=14cac26dcb71108abfdc95ea524e74be1f95774c;p=thirdparty%2Fdovecot%2Fcore.git Fix control flow and T_BEGIN/T_END hygiene You mustn't goto, break, continue, or return from out of a T_BEGIN {...} T_END block, as that will lose a t_pop(). This has been seen in the wild: Panic: Leaked t_pop() call Signed-off-by: Phil Carmody --- diff --git a/src/director/login-connection.c b/src/director/login-connection.c index f6b7459d21..5db690aa87 100644 --- a/src/director/login-connection.c +++ b/src/director/login-connection.c @@ -73,21 +73,27 @@ static void login_connection_input(struct login_connection *conn) static void login_connection_authreply_input(struct login_connection *conn) { + bool bail = FALSE; const char *line; - while ((line = i_stream_read_next_line(conn->input)) != NULL) T_BEGIN { + while (!bail && (line = i_stream_read_next_line(conn->input)) != NULL) T_BEGIN { if (!conn->handshaked) { if (!version_string_verify(line, "director-authreply-client", AUTHREPLY_PROTOCOL_MAJOR_VERSION)) { i_error("authreply client sent invalid handshake: %s", line); login_connection_deinit(&conn); - return; + bail = TRUE; /* don't return from within a T_BEGIN {...} T_END */ + } else { + conn->handshaked = TRUE; } - conn->handshaked = TRUE; } else { auth_input_line(line, conn); } } T_END; + + if (bail) + return; + if (conn->input->eof) { if (conn->input->stream_errno != 0 && conn->input->stream_errno != ECONNRESET) { diff --git a/src/lib/file-lock.c b/src/lib/file-lock.c index 05515b5023..fd2a430660 100644 --- a/src/lib/file-lock.c +++ b/src/lib/file-lock.c @@ -114,9 +114,9 @@ file_lock_find_proc_locks(int lock_fd ATTR_UNUSED) /* number: FLOCK/POSIX ADVISORY READ/WRITE pid major:minor:inode region-start region-end */ - if (str_array_length(args) < 8) - continue; - if (strcmp(args[5], node_buf) == 0) { + if (str_array_length(args) < 8) { + ; /* don't continue from within a T_BEGIN {...} T_END */ + } else if (strcmp(args[5], node_buf) == 0) { lock_type = strcmp(args[3], "READ") == 0 ? "READ" : "WRITE"; if (str_to_pid(args[4], &pid) < 0)