From: Stephan Bosch Date: Wed, 31 Oct 2018 23:39:21 +0000 (+0100) Subject: lib-smtp: server: command: Hold a reference to the command while calling a non-destro... X-Git-Tag: 2.3.9~1109 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=24a22bd8daa4d5666f50b686adc9db51c58cb643;p=thirdparty%2Fdovecot%2Fcore.git lib-smtp: server: command: Hold a reference to the command while calling a non-destroy hook. Prevents memory problems when the hook inadvertently gets the command destroyed. --- diff --git a/src/lib-smtp/smtp-server-command.c b/src/lib-smtp/smtp-server-command.c index c673ebc245..c4ff96ff04 100644 --- a/src/lib-smtp/smtp-server-command.c +++ b/src/lib-smtp/smtp-server-command.c @@ -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) diff --git a/src/lib-smtp/smtp-server-private.h b/src/lib-smtp/smtp-server-private.h index 9d9365880b..9b574ebb8d 100644 --- a/src/lib-smtp/smtp-server-private.h +++ b/src/lib-smtp/smtp-server-private.h @@ -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);