]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
features: Fix channel datastore access. 24/3124/1
authorRichard Mudgett <rmudgett@digium.com>
Thu, 30 Jun 2016 20:17:02 +0000 (15:17 -0500)
committerRichard Mudgett <rmudgett@digium.com>
Thu, 30 Jun 2016 20:31:20 +0000 (15:31 -0500)
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
main/features.c

index 543988dde0a6af9d2f3fc154b2f07570cf388053..2fafdf9903275bf130afb32044fb9e21a215cef1 100644 (file)
@@ -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)) {
index b96cbd68cc20ecbee9d4c2e125573120e45498a6..00010514c53e00bb227afcd74e541fb31598c0c5 100644 (file)
@@ -767,8 +767,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);
@@ -783,8 +783,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);
@@ -1098,7 +1098,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);