mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-13 16:21:01 +00:00
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
This commit is contained in:
@@ -2161,8 +2161,10 @@ int conf_set_menu_to_user(const char *menu_name, struct confbridge_user *user)
|
||||
ao2_ref(menu, +1);
|
||||
pvt->menu = menu;
|
||||
|
||||
ast_bridge_dtmf_hook(&user->features, pvt->menu_entry.dtmf, menu_hook_callback,
|
||||
pvt, menu_hook_destroy, 0);
|
||||
if (ast_bridge_dtmf_hook(&user->features, pvt->menu_entry.dtmf,
|
||||
menu_hook_callback, pvt, menu_hook_destroy, 0)) {
|
||||
menu_hook_destroy(pvt);
|
||||
}
|
||||
}
|
||||
|
||||
ao2_unlock(menu);
|
||||
|
@@ -390,7 +390,7 @@ int ast_bridge_interval_unregister(enum ast_bridge_builtin_interval interval);
|
||||
* \param remove_flags Dictates what situations the hook should be removed.
|
||||
*
|
||||
* \retval 0 on success
|
||||
* \retval -1 on failure
|
||||
* \retval -1 on failure (The caller must cleanup any hook_pvt resources.)
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
@@ -420,7 +420,7 @@ int ast_bridge_join_hook(struct ast_bridge_features *features,
|
||||
* \param remove_flags Dictates what situations the hook should be removed.
|
||||
*
|
||||
* \retval 0 on success
|
||||
* \retval -1 on failure
|
||||
* \retval -1 on failure (The caller must cleanup any hook_pvt resources.)
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
@@ -450,7 +450,7 @@ int ast_bridge_leave_hook(struct ast_bridge_features *features,
|
||||
* \param remove_flags Dictates what situations the hook should be removed.
|
||||
*
|
||||
* \retval 0 on success
|
||||
* \retval -1 on failure
|
||||
* \retval -1 on failure (The caller must cleanup any hook_pvt resources.)
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
@@ -481,7 +481,7 @@ int ast_bridge_hangup_hook(struct ast_bridge_features *features,
|
||||
* \param remove_flags Dictates what situations the hook should be removed.
|
||||
*
|
||||
* \retval 0 on success
|
||||
* \retval -1 on failure
|
||||
* \retval -1 on failure (The caller must cleanup any hook_pvt resources.)
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
@@ -503,7 +503,7 @@ int ast_bridge_dtmf_hook(struct ast_bridge_features *features,
|
||||
enum ast_bridge_hook_remove_flags remove_flags);
|
||||
|
||||
/*!
|
||||
* \brief attach an interval hook to a bridge features structure
|
||||
* \brief Attach an interval hook to a bridge features structure
|
||||
*
|
||||
* \param features Bridge features structure
|
||||
* \param interval The interval that the hook should execute at in milliseconds
|
||||
@@ -513,7 +513,7 @@ int ast_bridge_dtmf_hook(struct ast_bridge_features *features,
|
||||
* \param remove_flags Dictates what situations the hook should be removed.
|
||||
*
|
||||
* \retval 0 on success
|
||||
* \retval -1 on failure
|
||||
* \retval -1 on failure (The caller must cleanup any hook_pvt resources.)
|
||||
*
|
||||
* \code
|
||||
* struct ast_bridge_features features;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -542,6 +542,7 @@ void parking_set_duration(struct ast_bridge_features *features, struct parked_us
|
||||
if (ast_bridge_interval_hook(features, time_limit,
|
||||
parking_duration_callback, user, parking_duration_cb_destroyer, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) {
|
||||
ast_log(LOG_ERROR, "Failed to apply duration limits to the parking call.\n");
|
||||
ao2_ref(user, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user