# Pastebin RflwWYj1 commit 93d2f3137006df570a322d1881ad6cbb5da84ecc Author: Evgenios_Greek Date: Tue Apr 13 10:57:21 2021 +0300 Core/Stasis: Fix "FRACK!, Failed assertion bad magic number" happens when unsubscribe an application from an event source Several changes have been made to fix bugs related to applications subscriptions either by technology or by specific resources of the Endpoint's subscriptions * Fixed a typo in get_subscription when calling ao2_find (needs to pass the Endpoint's Id and not the whole object) * Fixed return a wrong subscription's object in get_subscription when check fails at search by Endpoint's technology block of code * In messaging_app_subscribe_endpoint added lines to up the subscription's reference counter in case more than 1 application is subscribed to * In messaging_app_unsubscribe_endpoint added line to up the subscription's reference counter, at search by Endpoint's resource block of code, cause the below ao2_unlink decreases the subscription's reference counter by 1 and cause follow lines of code decreases it 2 times more, one by calling ao2_ref, and one by auto-calling ao2_cleanup for the subscription's object when the function goes out of scope (through RAII_VAR macro) ASTERISK-28237 #close Reported by: Lucas Tardioli Silveira Change-Id: Ia91b15f8e5ea68f850c66889a6325d9575901729 diff --git a/res/stasis/messaging.c b/res/stasis/messaging.c index 2caa8ed228..16687ed2d4 100644 --- a/res/stasis/messaging.c +++ b/res/stasis/messaging.c @@ -396,7 +396,7 @@ static struct message_subscription *get_subscription(struct ast_endpoint *endpoi struct message_subscription *sub = NULL; if (endpoint && !ast_strlen_zero(ast_endpoint_get_resource(endpoint))) { - sub = ao2_find(endpoint_subscriptions, endpoint, OBJ_SEARCH_KEY); + sub = ao2_find(endpoint_subscriptions, ast_endpoint_get_id(endpoint), OBJ_SEARCH_KEY); } else { int i; @@ -408,6 +408,9 @@ static struct message_subscription *get_subscription(struct ast_endpoint *endpoi ao2_bump(sub); break; } + + /* Need to reset the pointer at this line to prevent from wrong using since the above check fails */ + sub = NULL; } ast_rwlock_unlock(&tech_subscriptions_lock); } @@ -441,10 +444,10 @@ void messaging_app_unsubscribe_endpoint(const char *app_name, const char *endpoi AST_VECTOR_REMOVE_CMP_UNORDERED(&tech_subscriptions, endpoint ? ast_endpoint_get_id(endpoint) : TECH_WILDCARD, messaging_subscription_cmp, AST_VECTOR_ELEM_CLEANUP_NOOP); ast_rwlock_unlock(&tech_subscriptions_lock); + ao2_ref(sub, -1); /* Release the reference held by tech_subscriptions */ } } ao2_unlock(sub); - ao2_ref(sub, -1); ast_debug(3, "App '%s' unsubscribed to messages from endpoint '%s'\n", app_name, endpoint ? ast_endpoint_get_id(endpoint) : "-- ALL --"); ast_test_suite_event_notify("StasisMessagingSubscription", "SubState: Unsubscribed\r\nAppName: %s\r\nToken: %s\r\n", @@ -464,6 +467,10 @@ static struct message_subscription *get_or_create_subscription(struct ast_endpoi return NULL; } + /* Either endpoint_subscriptions or tech_subscriptions will hold a reference to + * the subscription. This reference is released when there are no longer any + * applications receiving events from the subscription. + */ if (endpoint && !ast_strlen_zero(ast_endpoint_get_resource(endpoint))) { ao2_link(endpoint_subscriptions, sub); } else {