From 59d15c4c2a35988c6f39cf8adbfede81763706ae Mon Sep 17 00:00:00 2001 From: Evgenios_Greek Date: Tue, 13 Apr 2021 10:57:21 +0300 Subject: [PATCH] stasis: Fix "FRACK!, Failed assertion bad magic number" when unsubscribing When unsubscribing from an endpoint technology a FRACK would occur due to incorrect reference counting. This fixes that issue, along with some other issues. Fixed a typo in get_subscription when calling ao2_find as it needed to pass the endpoint ID and not the entire object. Fixed scenario where a subscription would get returned when it shouldn't have been when searching based on endpoint technology. A doulbe unreference has also been resolved by only explicitly releasing the reference held by tech_subscriptions. ASTERISK-28237 #close Reported by: Lucas Tardioli Silveira Change-Id: Ia91b15f8e5ea68f850c66889a6325d9575901729 --- res/stasis/messaging.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/res/stasis/messaging.c b/res/stasis/messaging.c index 2caa8ed228..e1d54c4a79 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,11 @@ 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 using the wrong subscription due to + * the token check failing. + */ + sub = NULL; } ast_rwlock_unlock(&tech_subscriptions_lock); } @@ -441,10 +446,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 +469,11 @@ 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 to allow the subscription to + * eventually destruct 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 {