diff options
author | Richard Mudgett <rmudgett@digium.com> | 2012-01-24 17:04:20 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2012-01-24 17:04:20 +0000 |
commit | 2144ba5df2813609024964c4c2d9060b30d5cd43 (patch) | |
tree | 4a9b5856e9f988a9fbdc5bdde610c146aaf5a841 /funcs | |
parent | 84aea92ba7b71ff17aa9c1d3ed05345d3fb570c0 (diff) |
Fix locking issues with channel datastores in func_odbc.c.
* Fixed a potential memory leak when an existing datastore is manually
destroyed by inline code instead of calling ast_datastore_free().
(closes issue ASTERISK-17948)
Reported by: Archie Cobbs
Review: https://reviewboard.asterisk.org/r/1687/
........
Merged revisions 352291 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 352292 from http://svn.asterisk.org/svn/asterisk/branches/10
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@352293 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'funcs')
-rw-r--r-- | funcs/func_odbc.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/funcs/func_odbc.c b/funcs/func_odbc.c index eeb7d3be1..edb69f093 100644 --- a/funcs/func_odbc.c +++ b/funcs/func_odbc.c @@ -727,8 +727,7 @@ end_acf_read: ast_channel_lock(chan); if ((odbc_store = ast_channel_datastore_find(chan, &odbc_info, buf))) { ast_channel_datastore_remove(chan, odbc_store); - odbc_datastore_free(odbc_store->data); - ast_free(odbc_store); + ast_datastore_free(odbc_store); } ast_channel_unlock(chan); } @@ -745,7 +744,9 @@ end_acf_read: return -1; } odbc_store->data = resultset; + ast_channel_lock(chan); ast_channel_datastore_add(chan, odbc_store); + ast_channel_unlock(chan); } } SQLCloseCursor(stmt); @@ -791,8 +792,11 @@ static int acf_fetch(struct ast_channel *chan, const char *cmd, char *data, char struct ast_datastore *store; struct odbc_datastore *resultset; struct odbc_datastore_row *row; + + ast_channel_lock(chan); store = ast_channel_datastore_find(chan, &odbc_info, data); if (!store) { + ast_channel_unlock(chan); pbx_builtin_setvar_helper(chan, "ODBC_FETCH_STATUS", "FAILURE"); return -1; } @@ -804,10 +808,12 @@ static int acf_fetch(struct ast_channel *chan, const char *cmd, char *data, char /* Cleanup datastore */ ast_channel_datastore_remove(chan, store); ast_datastore_free(store); + ast_channel_unlock(chan); pbx_builtin_setvar_helper(chan, "ODBC_FETCH_STATUS", "FAILURE"); return -1; } pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", resultset->names); + ast_channel_unlock(chan); ast_copy_string(buf, row->data, len); ast_free(row); pbx_builtin_setvar_helper(chan, "ODBC_FETCH_STATUS", "SUCCESS"); @@ -824,11 +830,15 @@ static char *app_odbcfinish = "ODBCFinish"; static int exec_odbcfinish(struct ast_channel *chan, const char *data) { - struct ast_datastore *store = ast_channel_datastore_find(chan, &odbc_info, data); - if (!store) /* Already freed; no big deal. */ - return 0; - ast_channel_datastore_remove(chan, store); - ast_datastore_free(store); + struct ast_datastore *store; + + ast_channel_lock(chan); + store = ast_channel_datastore_find(chan, &odbc_info, data); + if (store) { + ast_channel_datastore_remove(chan, store); + ast_datastore_free(store); + } + ast_channel_unlock(chan); return 0; } |