From: Timo Sirainen Date: Thu, 5 Jul 2018 11:53:02 +0000 (+0300) Subject: director: Fix crash when user kill times out before IPC finishes X-Git-Tag: 2.3.4~159 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=96efffe56468f4a3944a1fc2a783c50a00b9cf8f;p=thirdparty%2Fdovecot%2Fcore.git director: Fix crash when user kill times out before IPC finishes Abort the IPC kick command when freeing kill context so the IPC callback won't be called. --- diff --git a/src/director/director.c b/src/director/director.c index 2038ce8998..618316092b 100644 --- a/src/director/director.c +++ b/src/director/director.c @@ -922,6 +922,8 @@ static void director_user_move_free(struct user *user) dir_debug("User %u move finished at state=%s", user->username_hash, user_kill_state_names[kill_ctx->kill_state]); + if (kill_ctx->ipc_cmd != NULL) + ipc_client_cmd_abort(dir->ipc_proxy, &kill_ctx->ipc_cmd); timeout_remove(&kill_ctx->to_move); i_free(kill_ctx->socket_path); i_free(kill_ctx); @@ -999,6 +1001,9 @@ static void director_kill_user_callback(enum ipc_client_cmd_state state, struct director_kill_context *ctx = context; struct user *user; + /* don't try to abort the IPC command anymore */ + ctx->ipc_cmd = NULL; + /* this is an asynchronous notification about user being killed. there are no guarantees about what might have happened to the user in the mean time. */ @@ -1103,8 +1108,8 @@ void director_kill_user(struct director *dir, struct director_host *src, user->username_hash); ctx->callback_pending = TRUE; dir->users_kicking_count++; - ipc_client_cmd(dir->ipc_proxy, cmd, - director_kill_user_callback, ctx); + ctx->ipc_cmd = ipc_client_cmd(dir->ipc_proxy, cmd, + director_kill_user_callback, ctx); } else { /* a) we didn't even know about the user before now. don't bother performing a local kick, since it wouldn't diff --git a/src/director/director.h b/src/director/director.h index 5503f2b861..ef51381536 100644 --- a/src/director/director.h +++ b/src/director/director.h @@ -90,6 +90,8 @@ struct director_kill_context { /* Move timeout to make sure user's connections won't silently hang indefinitely if there is some trouble moving it. */ struct timeout *to_move; + /* IPC command to kick the user */ + struct ipc_client_cmd *ipc_cmd; /* these are set only for director_flush_socket handling: */ struct ip_addr host_ip;