From b3cc74fda954b330944397d5bbca4ff98698661f Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Wed, 13 Apr 2016 17:09:53 -0500 Subject: [PATCH] manager_channels.c: Fix allocation failure crash. An earlier allocation failure failed to create a channel snapshot for the AMI HangupRequest/SoftHangupRequest event which resulted in a crash in channel_hangup_request_cb(). Where the stasis message gets generated cannot tell if the NULL snapshot returned was because of an allocation failure or the channel was a dummy channel. * Made channel_hangup_request_cb() check if the channel blob has a snapshot and exit if it doesn't. * Eliminated the RAII_VAR usage in channel_hangup_request_cb(). Change-Id: I0b6a1c4e95cbb7d80b2a7054c6eadecc169dfd24 --- main/manager_channels.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/main/manager_channels.c b/main/manager_channels.c index da9bf476dc..c395708cc9 100644 --- a/main/manager_channels.c +++ b/main/manager_channels.c @@ -697,28 +697,33 @@ static void channel_hangup_request_cb(void *data, struct stasis_message *message) { struct ast_channel_blob *obj = stasis_message_data(message); - RAII_VAR(struct ast_str *, extra, NULL, ast_free); - RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free); + struct ast_str *extra; + struct ast_str *channel_event_string; struct ast_json *cause; int is_soft; char *manager_event = "HangupRequest"; + if (!obj->snapshot) { + /* No snapshot? Likely an earlier allocation failure creating it. */ + return; + } + extra = ast_str_create(20); if (!extra) { return; } channel_event_string = ast_manager_build_channel_state_string(obj->snapshot); - if (!channel_event_string) { + ast_free(extra); return; } cause = ast_json_object_get(obj->blob, "cause"); if (cause) { ast_str_append(&extra, 0, - "Cause: %jd\r\n", - ast_json_integer_get(cause)); + "Cause: %jd\r\n", + ast_json_integer_get(cause)); } is_soft = ast_json_is_true(ast_json_object_get(obj->blob, "soft")); @@ -727,9 +732,12 @@ static void channel_hangup_request_cb(void *data, } manager_event(EVENT_FLAG_CALL, manager_event, - "%s%s", - ast_str_buffer(channel_event_string), - ast_str_buffer(extra)); + "%s%s", + ast_str_buffer(channel_event_string), + ast_str_buffer(extra)); + + ast_free(channel_event_string); + ast_free(extra); } static void channel_chanspy_stop_cb(void *data, struct stasis_subscription *sub,