summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2013-06-20 17:21:40 +0000
committerRichard Mudgett <rmudgett@digium.com>2013-06-20 17:21:40 +0000
commitcd40e179a9bb01f10175ac3cecc633d631f69286 (patch)
treef8ff825633e0ee901f3f042544f98743cbdd682b /main
parent33eb15a242694e47707b70065c86fad19035d5c8 (diff)
Fix potential bridge hook resource leak if the hook install fails.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@392335 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/bridging.c46
-rw-r--r--main/features.c7
2 files changed, 50 insertions, 3 deletions
diff --git a/main/bridging.c b/main/bridging.c
index ad730f945..510123753 100644
--- a/main/bridging.c
+++ b/main/bridging.c
@@ -4893,6 +4893,15 @@ int ast_bridge_dtmf_hook(struct ast_bridge_features *features,
/* Once done we put it in the container. */
res = ao2_link(features->dtmf_hooks, hook) ? 0 : -1;
+ if (res) {
+ /*
+ * Could not link the hook into the container.
+ *
+ * Remove the hook_pvt destructor call from the hook since we
+ * are returning failure to install the hook.
+ */
+ hook->destructor = NULL;
+ }
ao2_ref(hook, -1);
return res;
@@ -4916,6 +4925,15 @@ int ast_bridge_hangup_hook(struct ast_bridge_features *features,
/* Once done we put it in the container. */
res = ao2_link(features->hangup_hooks, hook) ? 0 : -1;
+ if (res) {
+ /*
+ * Could not link the hook into the container.
+ *
+ * Remove the hook_pvt destructor call from the hook since we
+ * are returning failure to install the hook.
+ */
+ hook->destructor = NULL;
+ }
ao2_ref(hook, -1);
return res;
@@ -4939,6 +4957,15 @@ int ast_bridge_join_hook(struct ast_bridge_features *features,
/* Once done we put it in the container. */
res = ao2_link(features->join_hooks, hook) ? 0 : -1;
+ if (res) {
+ /*
+ * Could not link the hook into the container.
+ *
+ * Remove the hook_pvt destructor call from the hook since we
+ * are returning failure to install the hook.
+ */
+ hook->destructor = NULL;
+ }
ao2_ref(hook, -1);
return res;
@@ -4962,6 +4989,15 @@ int ast_bridge_leave_hook(struct ast_bridge_features *features,
/* Once done we put it in the container. */
res = ao2_link(features->leave_hooks, hook) ? 0 : -1;
+ if (res) {
+ /*
+ * Could not link the hook into the container.
+ *
+ * Remove the hook_pvt destructor call from the hook since we
+ * are returning failure to install the hook.
+ */
+ hook->destructor = NULL;
+ }
ao2_ref(hook, -1);
return res;
@@ -5013,11 +5049,17 @@ int ast_bridge_interval_hook(struct ast_bridge_features *features,
hook, hook->parms.timer.interval, features);
ast_heap_wrlock(features->interval_hooks);
res = ast_heap_push(features->interval_hooks, hook);
+ ast_heap_unlock(features->interval_hooks);
if (res) {
- /* Could not push the hook onto the heap. */
+ /*
+ * Could not push the hook into the heap
+ *
+ * Remove the hook_pvt destructor call from the hook since we
+ * are returning failure to install the hook.
+ */
+ hook->destructor = NULL;
ao2_ref(hook, -1);
}
- ast_heap_unlock(features->interval_hooks);
return res ? -1 : 0;
}
diff --git a/main/features.c b/main/features.c
index c44520c53..ff68b06e5 100644
--- a/main/features.c
+++ b/main/features.c
@@ -3415,6 +3415,7 @@ static int dynamic_dtmf_hook_add(struct ast_bridge_features *features, unsigned
size_t len_moh = ast_strlen_zero(moh_class) ? 0 : strlen(moh_class) + 1;
size_t len_feature = strlen(feature_name) + 1;
size_t len_data = sizeof(*hook_data) + len_name + len_args + len_moh + len_feature;
+ int res;
/* Fill in application run hook data. */
hook_data = ast_malloc(len_data);
@@ -3434,8 +3435,12 @@ static int dynamic_dtmf_hook_add(struct ast_bridge_features *features, unsigned
}
strcpy(&hook_data->app_name[hook_data->feature_offset], feature_name);/* Safe */
- return ast_bridge_dtmf_hook(features, dtmf, dynamic_dtmf_hook_trip, hook_data,
+ res = ast_bridge_dtmf_hook(features, dtmf, dynamic_dtmf_hook_trip, hook_data,
ast_free_ptr, AST_BRIDGE_HOOK_REMOVE_ON_PULL);
+ if (res) {
+ ast_free(hook_data);
+ }
+ return res;
}
static int setup_dynamic_feature(void *obj, void *arg, void *data, int flags)