]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: server: command: Hold a reference to the command while calling a non-destro...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Wed, 31 Oct 2018 23:39:21 +0000 (00:39 +0100)
committerStephan Bosch <stephan.bosch@dovecot.fi>
Thu, 1 Nov 2018 21:22:43 +0000 (22:22 +0100)
Prevents memory problems when the hook inadvertently gets the command destroyed.

src/lib-smtp/smtp-server-command.c
src/lib-smtp/smtp-server-private.h

index c673ebc245e75a09a59e036881b8e8bf8eaf2d65..c4ff96ff043a1a1af350b09866b39fd87a2f31d9 100644 (file)
@@ -273,7 +273,9 @@ bool smtp_server_command_unref(struct smtp_server_command **_cmd)
        }
 
        /* execute hooks */
-       smtp_server_command_call_hooks(cmd, SMTP_SERVER_COMMAND_HOOK_DESTROY);
+       if (!smtp_server_command_call_hooks(
+               &cmd, SMTP_SERVER_COMMAND_HOOK_DESTROY))
+               i_unreached();
 
        smtp_server_reply_free(cmd);
        pool_unref(&cmd->context.pool);
@@ -348,11 +350,15 @@ void smtp_server_command_remove_hook(struct smtp_server_command *cmd,
        i_assert(found);
 }
 
-void smtp_server_command_call_hooks(struct smtp_server_command *cmd,
+bool smtp_server_command_call_hooks(struct smtp_server_command **_cmd,
                                    enum smtp_server_command_hook_type type)
 {
+       struct smtp_server_command *cmd = *_cmd;
        struct smtp_server_command_hook *hook;
 
+       if (type != SMTP_SERVER_COMMAND_HOOK_DESTROY)
+               smtp_server_command_ref(cmd);
+
        hook = cmd->hooks_head;
        while (hook != NULL) {
                struct smtp_server_command_hook *hook_next = hook->next;
@@ -365,6 +371,14 @@ void smtp_server_command_call_hooks(struct smtp_server_command *cmd,
 
                hook = hook_next;
        }
+
+       if (type != SMTP_SERVER_COMMAND_HOOK_DESTROY) {
+               if (!smtp_server_command_unref(&cmd)) {
+                       *_cmd = NULL;
+                       return FALSE;
+               }
+       }
+       return TRUE;
 }
 
 void smtp_server_command_remove_hooks(struct smtp_server_command *cmd,
@@ -411,7 +425,7 @@ void smtp_server_command_next_to_reply(struct smtp_server_command *cmd)
 {
        smtp_server_command_debug(&cmd->context, "Next to reply");
 
-       smtp_server_command_call_hooks(cmd, SMTP_SERVER_COMMAND_HOOK_NEXT);
+       smtp_server_command_call_hooks(&cmd, SMTP_SERVER_COMMAND_HOOK_NEXT);
 }
 
 static void
@@ -422,7 +436,7 @@ smtp_server_command_replied(struct smtp_server_command *cmd)
 
        smtp_server_command_debug(&cmd->context, "Replied");
 
-       smtp_server_command_call_hooks(cmd, SMTP_SERVER_COMMAND_HOOK_REPLIED);
+       smtp_server_command_call_hooks(&cmd, SMTP_SERVER_COMMAND_HOOK_REPLIED);
 }
 
 void smtp_server_command_completed(struct smtp_server_command *cmd)
@@ -432,7 +446,7 @@ void smtp_server_command_completed(struct smtp_server_command *cmd)
 
        smtp_server_command_debug(&cmd->context, "Completed");
 
-       smtp_server_command_call_hooks(cmd, SMTP_SERVER_COMMAND_HOOK_COMPLETED);
+       smtp_server_command_call_hooks(&cmd, SMTP_SERVER_COMMAND_HOOK_COMPLETED);
 }
 
 void smtp_server_command_submit_reply(struct smtp_server_command *cmd)
index 9d9365880b420a0bef50d569e9ad92b5c5d559c6..9b574ebb8df7d50f23afae9d22eb51a547228cf7 100644 (file)
@@ -255,7 +255,7 @@ void smtp_server_command_ref(struct smtp_server_command *cmd);
 bool smtp_server_command_unref(struct smtp_server_command **_cmd);
 void smtp_server_command_abort(struct smtp_server_command **_cmd);
 
-void smtp_server_command_call_hooks(struct smtp_server_command *cmd,
+bool smtp_server_command_call_hooks(struct smtp_server_command **_cmd,
                                    enum smtp_server_command_hook_type type);
 void smtp_server_command_remove_hooks(struct smtp_server_command *cmd,
                                      enum smtp_server_command_hook_type type);