]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: server: Make sure command object is not used after it is destroyed in hook.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Wed, 31 Oct 2018 23:12:03 +0000 (00:12 +0100)
committerStephan Bosch <stephan.bosch@dovecot.fi>
Thu, 1 Nov 2018 21:22:43 +0000 (22:22 +0100)
src/lib-smtp/smtp-server-command.c
src/lib-smtp/smtp-server-connection.c
src/lib-smtp/smtp-server-private.h

index a2ad0e040f83590a6b5b4018520d4f204384da35..6b554685835a0394f86d8252c5127f4376bccaf2 100644 (file)
@@ -421,32 +421,41 @@ void smtp_server_command_ready_to_reply(struct smtp_server_command *cmd)
        smtp_server_connection_trigger_output(cmd->context.conn);
 }
 
-void smtp_server_command_next_to_reply(struct smtp_server_command *cmd)
+bool smtp_server_command_next_to_reply(struct smtp_server_command **_cmd)
 {
+       struct smtp_server_command *cmd = *_cmd;
+
        smtp_server_command_debug(&cmd->context, "Next to reply");
 
-       smtp_server_command_call_hooks(&cmd, SMTP_SERVER_COMMAND_HOOK_NEXT);
+       return smtp_server_command_call_hooks(
+               _cmd, SMTP_SERVER_COMMAND_HOOK_NEXT);
 }
 
-static void
-smtp_server_command_replied(struct smtp_server_command *cmd)
+static bool
+smtp_server_command_replied(struct smtp_server_command **_cmd)
 {
+       struct smtp_server_command *cmd = *_cmd;
+
        if (cmd->replies_submitted < cmd->replies_expected)
-               return;
+               return TRUE;
 
        smtp_server_command_debug(&cmd->context, "Replied");
 
-       smtp_server_command_call_hooks(&cmd, SMTP_SERVER_COMMAND_HOOK_REPLIED);
+       return smtp_server_command_call_hooks(
+               _cmd, SMTP_SERVER_COMMAND_HOOK_REPLIED);
 }
 
-void smtp_server_command_completed(struct smtp_server_command *cmd)
+bool smtp_server_command_completed(struct smtp_server_command **_cmd)
 {
+       struct smtp_server_command *cmd = *_cmd;
+
        if (cmd->replies_submitted < cmd->replies_expected)
-               return;
+               return TRUE;
 
        smtp_server_command_debug(&cmd->context, "Completed");
 
-       smtp_server_command_call_hooks(&cmd, SMTP_SERVER_COMMAND_HOOK_COMPLETED);
+       return smtp_server_command_call_hooks(
+               _cmd, SMTP_SERVER_COMMAND_HOOK_COMPLETED);
 }
 
 static bool
@@ -456,7 +465,8 @@ smtp_server_command_handle_reply(struct smtp_server_command *cmd)
 
        smtp_server_connection_ref(conn);
 
-       smtp_server_command_replied(cmd);
+       if (!smtp_server_command_replied(&cmd))
+               return smtp_server_connection_unref(&conn);
 
        /* submit reply */
        switch (cmd->state) {
index 7deafd7ed7c5d5510f35b0982215fa12b72be027..d26d0b0d4d4eaf4e382c65b70a1b167723ccbd6f 100644 (file)
@@ -333,7 +333,7 @@ smtp_server_connection_handle_command(struct smtp_server_connection *conn,
        }
 
        if (cmd != NULL && conn->command_queue_head == cmd)
-               smtp_server_command_next_to_reply(cmd);
+               (void)smtp_server_command_next_to_reply(&cmd);
 
        smtp_server_connection_timeout_update(conn);
        return (cmd == NULL || !cmd->input_locked);
@@ -668,14 +668,15 @@ smtp_server_connection_next_reply(struct smtp_server_connection *conn)
        }
 
        if (cmd->state < SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY) {
-               smtp_server_command_next_to_reply(cmd);
+               (void)smtp_server_command_next_to_reply(&cmd);
                return FALSE;
        }
 
        i_assert(cmd->state == SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY &&
                 array_is_created(&cmd->replies));
 
-       smtp_server_command_completed(cmd);
+       if (!smtp_server_command_completed(&cmd))
+               return TRUE;
 
        /* send command replies */
        // FIXME: handle LMTP DATA command with enormous number of recipients;
index 9b574ebb8df7d50f23afae9d22eb51a547228cf7..cc75320d4ecb9588cfdd58e63ae3875abc894740 100644 (file)
@@ -265,10 +265,11 @@ void smtp_server_command_submit_reply(struct smtp_server_command *cmd);
 int smtp_server_connection_flush(struct smtp_server_connection *conn);
 
 void smtp_server_command_ready_to_reply(struct smtp_server_command *cmd);
-void smtp_server_command_next_to_reply(struct smtp_server_command *cmd);
-void smtp_server_command_completed(struct smtp_server_command *cmd);
 void smtp_server_command_finished(struct smtp_server_command *cmd);
 
+bool smtp_server_command_next_to_reply(struct smtp_server_command **_cmd);
+bool smtp_server_command_completed(struct smtp_server_command **_cmd);
+
 static inline bool
 smtp_server_command_is_complete(struct smtp_server_command *cmd)
 {