From 4f7b85972669500d7f52598811935ebedfdee545 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Thu, 30 Jun 2016 15:17:02 -0500 Subject: [PATCH] features: Fix channel datastore access. Found as a result of the testsuite tests/callparking test crashing. Several calls to ast_get_chan_featuremap_config() and ast_get_chan_features_xfer_config() did not lock the channel before calling so the channel's datastore list was accessed without the lock's protection. Apparently another thread deleted a datastore on the channel's list while the crashing thread was walking the list. Crash at 0xdeaddead due to MALLOC_DEBUG's memory filler value as a result. * Add missing channel locks to calls that were not already protected as the doxygen for those calls indicates. Change-Id: Id273b3d305cc616406c353cbc841b2b7655efaa1 --- main/bridge_channel.c | 9 +++++++-- main/features.c | 6 ++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/main/bridge_channel.c b/main/bridge_channel.c index 3ba61aa334..18f7195061 100644 --- a/main/bridge_channel.c +++ b/main/bridge_channel.c @@ -1543,8 +1543,13 @@ static void testsuite_notify_feature_success(struct ast_channel *chan, const cha { #ifdef TEST_FRAMEWORK char *feature = "unknown"; - struct ast_featuremap_config *featuremap = ast_get_chan_featuremap_config(chan); - struct ast_features_xfer_config *xfer = ast_get_chan_features_xfer_config(chan); + struct ast_featuremap_config *featuremap; + struct ast_features_xfer_config *xfer; + + ast_channel_lock(chan); + featuremap = ast_get_chan_featuremap_config(chan); + xfer = ast_get_chan_features_xfer_config(chan); + ast_channel_unlock(chan); if (featuremap) { if (!strcmp(dtmf, featuremap->blindxfer)) { diff --git a/main/features.c b/main/features.c index 6806fe749f..b6e9630b52 100644 --- a/main/features.c +++ b/main/features.c @@ -766,8 +766,8 @@ static int action_bridge(struct mansession *s, const struct message *m) astman_send_error(s, m, buf); return 0; } - xfer_cfg_a = ast_get_chan_features_xfer_config(chana); ast_channel_lock(chana); + xfer_cfg_a = ast_get_chan_features_xfer_config(chana); chana_exten = ast_strdupa(ast_channel_exten(chana)); chana_context = ast_strdupa(ast_channel_context(chana)); chana_priority = ast_channel_priority(chana); @@ -782,8 +782,8 @@ static int action_bridge(struct mansession *s, const struct message *m) astman_send_error(s, m, buf); return 0; } - xfer_cfg_b = ast_get_chan_features_xfer_config(chanb); ast_channel_lock(chanb); + xfer_cfg_b = ast_get_chan_features_xfer_config(chanb); chanb_exten = ast_strdupa(ast_channel_exten(chanb)); chanb_context = ast_strdupa(ast_channel_context(chanb)); chanb_priority = ast_channel_priority(chanb); @@ -1097,7 +1097,9 @@ static int bridge_exec(struct ast_channel *chan, const char *data) goto done; } + ast_channel_lock(current_dest_chan); xfer_cfg = ast_get_chan_features_xfer_config(current_dest_chan); + ast_channel_unlock(current_dest_chan); bridge_add_failed = ast_bridge_add_channel(bridge, current_dest_chan, peer_features, ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE), xfer_cfg ? xfer_cfg->xfersound : NULL);