From 174b16a3d1285712f2f965f0572fd1b973f9ff41 Mon Sep 17 00:00:00 2001 From: "Ahron Greenberg (agree)" <37550360+greenbea@users.noreply.github.com> Date: Fri, 12 Jun 2026 10:53:40 -0400 Subject: [PATCH] [mod_amqp] prevent segfault on double connection close When a command response publish failed, `mod_amqp_command_response` closed the connection and cleared conn_active. The command thread teardown then called mod_amqp_connection_close(NULL), causing a segfault. Also fix amqp_error_string2() calls to pass status codes without erroneous negation. --- src/mod/event_handlers/mod_amqp/mod_amqp_command.c | 9 ++++++--- src/mod/event_handlers/mod_amqp/mod_amqp_connection.c | 11 +++++++++-- src/mod/event_handlers/mod_amqp/mod_amqp_logging.c | 3 ++- src/mod/event_handlers/mod_amqp/mod_amqp_producer.c | 3 ++- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/mod/event_handlers/mod_amqp/mod_amqp_command.c b/src/mod/event_handlers/mod_amqp/mod_amqp_command.c index 48cdf55ce4..ee879d2474 100644 --- a/src/mod/event_handlers/mod_amqp/mod_amqp_command.c +++ b/src/mod/event_handlers/mod_amqp/mod_amqp_command.c @@ -259,7 +259,8 @@ static void mod_amqp_command_response(mod_amqp_command_profile_t *profile, char switch_safe_free(json_output); if (amqp_status != AMQP_STATUS_OK) { - const char *errstr = amqp_error_string2(-amqp_status); + const char *errstr = amqp_error_string2(amqp_status); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] failed to send event on connection[%s]: %s\n", profile->name, profile->conn_active->name, errstr); @@ -498,8 +499,10 @@ void * SWITCH_THREAD_FUNC mod_amqp_command_thread(switch_thread_t *thread, void amqp_bytes_free(queueName); queueName.bytes = NULL; - mod_amqp_connection_close(profile->conn_active); - profile->conn_active = NULL; + if (profile->conn_active) { + mod_amqp_connection_close(profile->conn_active); + profile->conn_active = NULL; + } if (profile->running) { /* We'll reconnect, but sleep to avoid hammering resources */ diff --git a/src/mod/event_handlers/mod_amqp/mod_amqp_connection.c b/src/mod/event_handlers/mod_amqp/mod_amqp_connection.c index 758eac241e..d3b7efc767 100644 --- a/src/mod/event_handlers/mod_amqp/mod_amqp_connection.c +++ b/src/mod/event_handlers/mod_amqp/mod_amqp_connection.c @@ -40,9 +40,15 @@ void mod_amqp_connection_close(mod_amqp_connection_t *connection) { - amqp_connection_state_t old_state = connection->state; + amqp_connection_state_t old_state; int status = 0; + if (!connection) { + return; + } + + old_state = connection->state; + connection->state = NULL; if (old_state != NULL) { @@ -50,7 +56,8 @@ void mod_amqp_connection_close(mod_amqp_connection_t *connection) mod_amqp_log_if_amqp_error(amqp_connection_close(old_state, AMQP_REPLY_SUCCESS), "Closing connection"); if ((status = amqp_destroy_connection(old_state))) { - const char *errstr = amqp_error_string2(-status); + const char *errstr = amqp_error_string2(status); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error destroying amqp connection: %s\n", errstr); } } diff --git a/src/mod/event_handlers/mod_amqp/mod_amqp_logging.c b/src/mod/event_handlers/mod_amqp/mod_amqp_logging.c index 01d08960fa..eec17581a6 100644 --- a/src/mod/event_handlers/mod_amqp/mod_amqp_logging.c +++ b/src/mod/event_handlers/mod_amqp/mod_amqp_logging.c @@ -296,7 +296,8 @@ switch_status_t mod_amqp_logging_send(mod_amqp_logging_profile_t *profile, mod_a amqp_cstring_bytes(msg->pjson)); if (status < 0) { - const char *errstr = amqp_error_string2(-status); + const char *errstr = amqp_error_string2(status); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] failed to send event on connection[%s]: %s\n", profile->name, profile->conn_active->name, errstr); diff --git a/src/mod/event_handlers/mod_amqp/mod_amqp_producer.c b/src/mod/event_handlers/mod_amqp/mod_amqp_producer.c index 303927285e..259906c007 100644 --- a/src/mod/event_handlers/mod_amqp/mod_amqp_producer.c +++ b/src/mod/event_handlers/mod_amqp/mod_amqp_producer.c @@ -426,7 +426,8 @@ switch_status_t mod_amqp_producer_send(mod_amqp_producer_profile_t *profile, mod amqp_cstring_bytes(msg->pjson)); if (status < 0) { - const char *errstr = amqp_error_string2(-status); + const char *errstr = amqp_error_string2(status); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] failed to send event on connection[%s]: %s\n", profile->name, profile->conn_active->name, errstr);