diff options
author | Matthew Jordan <mjordan@digium.com> | 2012-05-18 14:43:44 +0000 |
---|---|---|
committer | Matthew Jordan <mjordan@digium.com> | 2012-05-18 14:43:44 +0000 |
commit | 7b51320642349100921af1308cb277c21d4fe18c (patch) | |
tree | 07841f22e8cb74ee5a457599b297ab58a3052e80 | |
parent | 6fc8e9928dbb0775bf5affdde5ccc0597fa105e1 (diff) |
Fix a variety of memory leaks
This patch addresses a number of memory leaks in a variety of modules that were
found by a static analysis tool. A brief summary of the changes:
* app_minivm: free ast_str objects on off nominal paths
* app_page: free the ast_dial object if the requested channel technology
cannot be appended to the dialing structure
* app_queue: if a penalty rule failed to match any existing rule list
names, the created rule would not be inserted and its memory
would be leaked
* app_read: dispose of the created silence detector in the presence of
off nominal circumstances
* app_voicemail: dispose of an allocated unique ID field for MWI event
un-subscribe requests in off nominal paths; dispose of
configuration objects when using the secret.conf option
* chan_dahdi: dispose of the allocated frame produced by ast_dsp_process
* chan_iax2: properly unref peer in CLI command "iax2 unregister"
* chan_sip: dispose of the allocated frame produced by sip_rtp_read's
call of ast_dsp_process; free memory in parse unit tests
* func_dialgroup: properly deref ao2 object grhead in nominal path of
dialgroup_read
* func_odbc: free resultset in off nominal paths of odbc_read
* cli: free match_list in off nominal paths of CLI match completion
* config: free comment_buffer/list_buffer when configuration file load
is unchanged; free the same buffers any time they were
created and config files were processed
* data: free XML nodes in various places
* enum: free context buffer in off nominal paths
* features: free ast_call_feature in off nominal paths of applicationmap
config processing
* netsock2: users of ast_sockaddr_resolve pass in an ast_sockaddr struct
that is allocated by the method. Failures in
ast_sockaddr_resolve could result in the users of the method
not knowing whether or not the buffer was allocated. The
method will now not allocate the ast_sockaddr struct if it
will return failure.
* pbx: cleanup hash table traversals in off nominal paths; free
ignore pattern buffer if it already exists for the specified
context
* xmldoc: cleanup various nodes when we no longer need them
* main/editline: various cleanup of pointers not being freed before being
assigned to other memory, cleanup along off nominal paths
* menuselect/mxml: cleanup of value buffer for an attribute when that attribute
did not specify a value
* res_calendar*: responses are allocated via the various *_request method
returns and should not be allocated in the various
write_event methods; ensure attendee buffer is freed if no
data exists in the parsed node; ensure that calendar objects
are de-ref'd appropriately
* res_jabber: free buffer in off nominal path
* res_musiconhold: close the DIR* object in off nominal paths
* res_rtp_asterisk: if we run out of ports, close the rtp socket object and free
the rtp object
* res_srtp: if we fail to create the session in libsrtp, destroy the
temporary ast_srtp object
(issue ASTERISK-19665)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/1922
........
Merged revisions 366880 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 366881 from http://svn.asterisk.org/svn/asterisk/branches/10
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@366917 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r-- | apps/app_minivm.c | 6 | ||||
-rw-r--r-- | apps/app_page.c | 1 | ||||
-rw-r--r-- | apps/app_queue.c | 9 | ||||
-rw-r--r-- | apps/app_record.c | 8 | ||||
-rw-r--r-- | apps/app_voicemail.c | 47 | ||||
-rw-r--r-- | channels/chan_dahdi.c | 5 | ||||
-rw-r--r-- | channels/chan_iax2.c | 2 | ||||
-rw-r--r-- | channels/chan_sip.c | 2 | ||||
-rw-r--r-- | channels/sip/config_parser.c | 6 | ||||
-rw-r--r-- | funcs/func_dialgroup.c | 1 | ||||
-rw-r--r-- | funcs/func_odbc.c | 3 | ||||
-rw-r--r-- | main/cli.c | 4 | ||||
-rw-r--r-- | main/config.c | 4 | ||||
-rw-r--r-- | main/data.c | 2 | ||||
-rw-r--r-- | main/editline/readline.c | 8 | ||||
-rw-r--r-- | main/editline/term.c | 16 | ||||
-rw-r--r-- | main/editline/tokenizer.c | 9 | ||||
-rw-r--r-- | main/enum.c | 3 | ||||
-rw-r--r-- | main/features.c | 2 | ||||
-rw-r--r-- | main/netsock2.c | 4 | ||||
-rw-r--r-- | main/pbx.c | 3 | ||||
-rw-r--r-- | main/xmldoc.c | 4 | ||||
-rw-r--r-- | res/res_calendar.c | 14 | ||||
-rw-r--r-- | res/res_calendar_caldav.c | 13 | ||||
-rw-r--r-- | res/res_calendar_exchange.c | 5 | ||||
-rw-r--r-- | res/res_calendar_icalendar.c | 8 | ||||
-rw-r--r-- | res/res_jabber.c | 1 | ||||
-rw-r--r-- | res/res_rtp_asterisk.c | 2 | ||||
-rw-r--r-- | res/res_srtp.c | 4 |
29 files changed, 152 insertions, 44 deletions
diff --git a/apps/app_minivm.c b/apps/app_minivm.c index eca7f307c..0b463114b 100644 --- a/apps/app_minivm.c +++ b/apps/app_minivm.c @@ -1255,6 +1255,8 @@ static int sendmail(struct minivm_template *template, struct minivm_account *vmu if (ast_strlen_zero(email)) { ast_log(LOG_WARNING, "No address to send message to.\n"); + ast_free(str1); + ast_free(str2); return -1; } @@ -1309,11 +1311,15 @@ static int sendmail(struct minivm_template *template, struct minivm_account *vmu } if (!p) { ast_log(LOG_WARNING, "Unable to open temporary file '%s'\n", tmp); + ast_free(str1); + ast_free(str2); return -1; } /* Allocate channel used for chanvar substitution */ ast = ast_dummy_channel_alloc(); if (!ast) { + ast_free(str1); + ast_free(str2); return -1; } diff --git a/apps/app_page.c b/apps/app_page.c index 61172fc8e..8c5694841 100644 --- a/apps/app_page.c +++ b/apps/app_page.c @@ -270,6 +270,7 @@ static int page_exec(struct ast_channel *chan, const char *data) /* Append technology and resource */ if (ast_dial_append(dial, tech, resource) == -1) { ast_log(LOG_ERROR, "Failed to add %s to outbound dial\n", tech); + ast_dial_destroy(dial); continue; } diff --git a/apps/app_queue.c b/apps/app_queue.c index 151f03cd4..a566c9aed 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -1973,9 +1973,17 @@ static int insert_penaltychange(const char *list_name, const char *content, cons if (!inserted) { AST_LIST_INSERT_TAIL(&rl_iter->rules, rule, list); + inserted = 1; } + + break; } + if (!inserted) { + ast_log(LOG_WARNING, "Unknown rule list name %s; ignoring.\n", list_name); + ast_free(rule); + return -1; + } return 0; } @@ -4538,6 +4546,7 @@ static struct ast_datastore *setup_transfer_datastore(struct queue_ent *qe, stru ast_channel_lock(qe->chan); if (!(ds = ast_datastore_alloc(&queue_transfer_info, NULL))) { ast_channel_unlock(qe->chan); + ast_free(qtds); ast_log(LOG_WARNING, "Unable to create transfer datastore. queue_log will not show attended transfer\n"); return NULL; } diff --git a/apps/app_record.c b/apps/app_record.c index 3499cb118..ff233d6a9 100644 --- a/apps/app_record.c +++ b/apps/app_record.c @@ -415,12 +415,14 @@ static int record_exec(struct ast_channel *chan, const char *data) out: if ((silence > 0) && rfmt.id) { res = ast_set_read_format(chan, &rfmt); - if (res) + if (res) { ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", ast_channel_name(chan)); - if (sildet) - ast_dsp_free(sildet); + } } + if (sildet) { + ast_dsp_free(sildet); + } return res; } diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 7e75ea9a9..eec08a484 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -11728,16 +11728,22 @@ static int handle_subscribe(void *datap) static void mwi_unsub_event_cb(const struct ast_event *event, void *userdata) { uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); - if (ast_event_get_type(event) != AST_EVENT_UNSUB) + + if (!uniqueid) { + ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); return; + } - if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) + if (ast_event_get_type(event) != AST_EVENT_UNSUB) { + ast_free(uniqueid); return; + } - if (!uniqueid) { - ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); + if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) { + ast_free(uniqueid); return; } + u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); *uniqueid = u; if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { @@ -12728,8 +12734,10 @@ static void read_password_from_file(const char *secretfn, char *password, int pa const char *val = ast_variable_retrieve(pwconf, "general", "password"); if (val) { ast_copy_string(password, val, passwordlen); - return; + ast_config_destroy(pwconf); + return; } + ast_config_destroy(pwconf); } ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); } @@ -12738,26 +12746,33 @@ static int write_password_to_file(const char *secretfn, const char *password) { struct ast_config *conf; struct ast_category *cat; struct ast_variable *var; + int res = -1; - if (!(conf=ast_config_new())) { + if (!(conf = ast_config_new())) { ast_log(LOG_ERROR, "Error creating new config structure\n"); - return -1; + return res; } - if (!(cat=ast_category_new("general","",1))) { + if (!(cat = ast_category_new("general", "", 1))) { ast_log(LOG_ERROR, "Error creating new category structure\n"); - return -1; + ast_config_destroy(conf); + return res; } - if (!(var=ast_variable_new("password",password,""))) { + if (!(var = ast_variable_new("password", password, ""))) { ast_log(LOG_ERROR, "Error creating new variable structure\n"); - return -1; + ast_config_destroy(conf); + ast_category_destroy(cat); + return res; } - ast_category_append(conf,cat); - ast_variable_append(cat,var); - if (ast_config_text_file_save(secretfn, conf, "app_voicemail")) { + ast_category_append(conf, cat); + ast_variable_append(cat, var); + if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) { + res = 0; + } else { ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); - return -1; } - return 0; + + ast_config_destroy(conf); + return res; } static int vmsayname_exec(struct ast_channel *chan, const char *data) diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 8f4da6f56..77b2eb8f0 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -9315,6 +9315,7 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast) * Treat this as a "hangup" instead of a "busy" on the * assumption that a busy means the incoming call went away. */ + ast_frfree(f); f = NULL; } } else if (p->dialtone_detect && !p->outgoing && f->frametype == AST_FRAME_VOICE) { @@ -9345,7 +9346,8 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast) if (ast_tvdiff_ms(ast_tvnow(), p->waitingfordt) >= p->waitfordialtone ) { p->waitingfordt.tv_sec = 0; ast_log(LOG_WARNING, "Never saw dialtone on channel %d\n", p->channel); - f=NULL; + ast_frfree(f); + f = NULL; } else if (f->frametype == AST_FRAME_VOICE) { f->frametype = AST_FRAME_NULL; f->subclass.integer = 0; @@ -9360,6 +9362,7 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast) ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel); p->dop.dialstr[0] = '\0'; ast_mutex_unlock(&p->lock); + ast_frfree(f); return NULL; } else { ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr); diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 0d9af6979..3b2d8ccb0 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -6899,6 +6899,7 @@ static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct } else { ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); } + peer_unref(p); } else { ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); } @@ -9847,6 +9848,7 @@ static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *dat } varlist = ast_calloc(1, sizeof(*varlist)); if (!varlist) { + ast_datastore_free(variablestore); ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); return -1; } diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 5d0cf0bdd..a21ebf394 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -7657,6 +7657,7 @@ static struct ast_frame *sip_read(struct ast_channel *ast) if (ast_async_goto(ast, target_context, "fax", 1)) { ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context); } + ast_frfree(fr); fr = &ast_null_frame; } else { ast_channel_lock(ast); @@ -7668,6 +7669,7 @@ static struct ast_frame *sip_read(struct ast_channel *ast) /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast_channel_state(ast) != AST_STATE_UP) { + ast_frfree(fr); fr = &ast_null_frame; } diff --git a/channels/sip/config_parser.c b/channels/sip/config_parser.c index 98b42d5a8..ba6880d30 100644 --- a/channels/sip/config_parser.c +++ b/channels/sip/config_parser.c @@ -597,6 +597,8 @@ AST_TEST_DEFINE(sip_parse_register_line_test) ast_test_status_update(test, "Test 13, add domain port failed.\n"); res = AST_TEST_FAIL; } + ast_string_field_free_memory(reg); + ast_free(reg); /* ---Test reg14, domain port without secret --- */ if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) { @@ -623,7 +625,9 @@ AST_TEST_DEFINE(sip_parse_register_line_test) ast_test_status_update(test, "Test 14, domain port without secret failed.\n"); res = AST_TEST_FAIL; -} + } + ast_string_field_free_memory(reg); + ast_free(reg); return res; diff --git a/funcs/func_dialgroup.c b/funcs/func_dialgroup.c index c3322e3f9..0e078cd80 100644 --- a/funcs/func_dialgroup.c +++ b/funcs/func_dialgroup.c @@ -165,6 +165,7 @@ static int dialgroup_read(struct ast_channel *chan, const char *cmd, char *data, ao2_ref(entry, -1); } ao2_iterator_destroy(&i); + ao2_ref(grhead, -1); return res; } diff --git a/funcs/func_odbc.c b/funcs/func_odbc.c index 1ee9771ad..72a87cc0b 100644 --- a/funcs/func_odbc.c +++ b/funcs/func_odbc.c @@ -539,6 +539,7 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount); ast_autoservice_stop(chan); } + ast_free(resultset); return -1; } @@ -553,6 +554,7 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount); ast_autoservice_stop(chan); } + ast_free(resultset); return -1; } @@ -578,6 +580,7 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status); ast_autoservice_stop(chan); } + ast_free(resultset); return res1; } diff --git a/main/cli.c b/main/cli.c index 6c79c7bb2..c54d89e87 100644 --- a/main/cli.c +++ b/main/cli.c @@ -2350,8 +2350,10 @@ char **ast_cli_completion_matches(const char *text, const char *word) max_equal = i; } - if (!(retstr = ast_malloc(max_equal + 1))) + if (!(retstr = ast_malloc(max_equal + 1))) { + ast_free(match_list); return NULL; + } ast_copy_string(retstr, match_list[1], max_equal + 1); match_list[0] = retstr; diff --git a/main/config.c b/main/config.c index 249cf0403..7f7f35558 100644 --- a/main/config.c +++ b/main/config.c @@ -1491,6 +1491,8 @@ static struct ast_config *config_text_file_load(const char *database, const char if (unchanged) { AST_LIST_UNLOCK(&cfmtime_head); + ast_free(comment_buffer); + ast_free(lline_buffer); return CONFIG_STATUS_FILEUNCHANGED; } } @@ -1643,7 +1645,7 @@ static struct ast_config *config_text_file_load(const char *database, const char } #endif - if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID && cfg->include_level == 1 && ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { + if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) { ast_free(comment_buffer); ast_free(lline_buffer); comment_buffer = NULL; diff --git a/main/data.c b/main/data.c index 146b15453..3a7d5e92c 100644 --- a/main/data.c +++ b/main/data.c @@ -1042,6 +1042,7 @@ static int data_search_cmp_ptr(const struct ast_data_search *root, const char *n cmp_type = child->cmp_type; if (sscanf(child->value, "%p", &node_ptr) <= 0) { + ao2_ref(child, -1); return 1; } @@ -2186,6 +2187,7 @@ struct ast_xml_doc *ast_data_get_xml(const struct ast_data_query *query) doc = ast_xml_new(); if (!doc) { + ast_data_free(res); return NULL; } diff --git a/main/editline/readline.c b/main/editline/readline.c index 4729fa952..77827c3f9 100644 --- a/main/editline/readline.c +++ b/main/editline/readline.c @@ -549,6 +549,7 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) from = strdup(search); else { from = NULL; + free(line); return (-1); } } @@ -609,8 +610,13 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) end = max - ((end < -1) ? 1 : 0); /* check boundaries ... */ - if (start > max || end > max || start > end) + if (start > max || end > max || start > end) { + for (i = 0; i <= max; i++) { + free(arr[i]); + } + free(arr), arr = (char **) NULL; return (-1); + } for (i = 0; i <= max; i++) { char *temp; diff --git a/main/editline/term.c b/main/editline/term.c index fb627cabb..63cec6e43 100644 --- a/main/editline/term.c +++ b/main/editline/term.c @@ -472,7 +472,7 @@ term_rebuffer_display(EditLine *el) private int term_alloc_display(EditLine *el) { - int i; + int i, j; char **b; coord_t *c = &el->el_term.t_size; @@ -481,8 +481,13 @@ term_alloc_display(EditLine *el) return (-1); for (i = 0; i < c->v; i++) { b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); - if (b[i] == NULL) + if (b[i] == NULL) { + for (j = 0; j < i; j++) { + el_free(b[j]); + } + el_free(b); return (-1); + } } b[c->v] = NULL; el->el_display = b; @@ -492,8 +497,13 @@ term_alloc_display(EditLine *el) return (-1); for (i = 0; i < c->v; i++) { b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); - if (b[i] == NULL) + if (b[i] == NULL) { + for (j = 0; j < i; j++) { + el_free(b[j]); + } + el_free(b); return (-1); + } } b[c->v] = NULL; el->el_vdisplay = b; diff --git a/main/editline/tokenizer.c b/main/editline/tokenizer.c index f0de39bc9..67398c686 100644 --- a/main/editline/tokenizer.c +++ b/main/editline/tokenizer.c @@ -113,12 +113,17 @@ tok_init(const char *ifs) tok->argc = 0; tok->amax = AINCR; tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax); - if (tok->argv == NULL) + if (tok->argv == NULL) { + tok_free(tok); return (NULL); + } tok->argv[0] = NULL; tok->wspace = (char *) tok_malloc(WINCR); - if (tok->wspace == NULL) + if (tok->wspace == NULL) { + tok_free(tok->argv); + tok_free(tok); return (NULL); + } tok->wmax = tok->wspace + WINCR; tok->wstart = tok->wspace; tok->wptr = tok->wspace; diff --git a/main/enum.c b/main/enum.c index 413085e7f..9c31c93b2 100644 --- a/main/enum.c +++ b/main/enum.c @@ -790,6 +790,7 @@ int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int ds if (sdl > strlen(number)) { /* Number too short for this sdl? */ ast_log(LOG_WARNING, "I-ENUM: subdomain location %d behind number %s\n", sdl, number); + ast_free(context); return 0; } ast_copy_string(left, number + sdl, sizeof(left)); @@ -802,6 +803,7 @@ int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int ds /* check the space we need for middle */ if ((sdl * 2 + strlen(middle) + 2) > sizeof(middle)) { ast_log(LOG_WARNING, "ast_get_enum: not enough space for I-ENUM rewrite.\n"); + ast_free(context); return -1; } @@ -819,6 +821,7 @@ int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int ds if (strlen(left) * 2 + 2 > sizeof(domain)) { ast_log(LOG_WARNING, "string to long in ast_get_enum\n"); + ast_free(context); return -1; } diff --git a/main/features.c b/main/features.c index 433c1a647..964e53614 100644 --- a/main/features.c +++ b/main/features.c @@ -6044,6 +6044,7 @@ static void process_applicationmap_line(struct ast_variable *var) } else { ast_log(LOG_NOTICE, "Invalid 'ActivateOn' specification for feature '%s'," " must be 'self', or 'peer'\n", var->name); + ast_free(feature); return; } @@ -6058,6 +6059,7 @@ static void process_applicationmap_line(struct ast_variable *var) } else { ast_log(LOG_NOTICE, "Invalid 'ActivatedBy' specification for feature '%s'," " must be 'caller', or 'callee', or 'both'\n", var->name); + ast_free(feature); return; } diff --git a/main/netsock2.c b/main/netsock2.c index 1922ac388..5ae4ceb70 100644 --- a/main/netsock2.c +++ b/main/netsock2.c @@ -270,6 +270,10 @@ int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, res_cnt++; } + if (res_cnt == 0) { + goto cleanup; + } + if ((*addrs = ast_malloc(res_cnt * sizeof(struct ast_sockaddr))) == NULL) { res_cnt = 0; goto cleanup; diff --git a/main/pbx.c b/main/pbx.c index 2860218af..250737b22 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -7511,6 +7511,8 @@ static void context_merge(struct ast_context **extcontexts, struct ast_hashtab * if (!new) { ast_log(LOG_ERROR,"Could not allocate a new context for %s in merge_and_delete! Danger!\n", context->name); + ast_hashtab_end_traversal(prio_iter); + ast_hashtab_end_traversal(exten_iter); return; /* no sense continuing. */ } /* we will not replace existing entries in the new context with stuff from the old context. @@ -8236,6 +8238,7 @@ int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const if (!strcasecmp(ignorepatc->pattern, value)) { /* Already there */ ast_unlock_context(con); + ast_free(ignorepat); errno = EEXIST; return -1; } diff --git a/main/xmldoc.c b/main/xmldoc.c index 2735583ab..fad10e09a 100644 --- a/main/xmldoc.c +++ b/main/xmldoc.c @@ -1666,6 +1666,7 @@ static void xmldoc_parse_optionlist(struct ast_xml_node *fixnode, const char *ta ast_str_append(buffer, 0, "\n"); ast_xml_free_attr(optname); ast_xml_free_attr(hasparams); + ast_free(optionsyntax); } } @@ -1740,12 +1741,14 @@ char *ast_xmldoc_build_arguments(const char *type, const char *name, const char char *retstr = NULL; if (ast_strlen_zero(type) || ast_strlen_zero(name)) { + ast_free(ret); return NULL; } node = xmldoc_get_node(type, name, module, documentation_language); if (!node || !ast_xml_node_get_children(node)) { + ast_free(ret); return NULL; } @@ -1758,6 +1761,7 @@ char *ast_xmldoc_build_arguments(const char *type, const char *name, const char if (!node || !ast_xml_node_get_children(node)) { /* We couldn't find the syntax node. */ + ast_free(ret); return NULL; } diff --git a/res/res_calendar.c b/res/res_calendar.c index 5ddcaae07..8c349946b 100644 --- a/res/res_calendar.c +++ b/res/res_calendar.c @@ -374,6 +374,7 @@ static int calendar_is_busy(struct ast_calendar *cal) static enum ast_device_state calendarstate(const char *data) { + enum ast_device_state state; struct ast_calendar *cal; if (ast_strlen_zero(data) || (!(cal = find_calendar(data)))) { @@ -381,10 +382,13 @@ static enum ast_device_state calendarstate(const char *data) } if (cal->tech->is_busy) { - return cal->tech->is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE; + state = cal->tech->is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE; + } else { + state = calendar_is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE; } - return calendar_is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE; + cal = unref_calendar(cal); + return state; } static struct ast_calendar *build_calendar(struct ast_config *cfg, const char *cat, const struct ast_calendar_tech *tech) @@ -1060,6 +1064,7 @@ static int calendar_busy_exec(struct ast_channel *chan, const char *cmd, char *d } strcpy(buf, calendar_is_busy(cal) ? "1" : "0"); + cal = unref_calendar(cal); return 0; } @@ -1214,6 +1219,8 @@ static int calendar_query_exec(struct ast_channel *chan, const char *cmd, char * ast_debug(10, "%s (%ld - %ld) overlapped with (%ld - %ld)\n", event->summary, (long) event->start, (long) event->end, (long) start, (long) end); if (add_event_to_list(events, event, start, end) < 0) { event = ast_calendar_unref_event(event); + cal = unref_calendar(cal); + ao2_ref(events, -1); ao2_iterator_destroy(&i); return -1; } @@ -1231,6 +1238,8 @@ static int calendar_query_exec(struct ast_channel *chan, const char *cmd, char * if (!(eventlist_datastore = ast_datastore_alloc(&eventlist_datastore_info, buf))) { ast_log(LOG_ERROR, "Could not allocate datastore!\n"); + cal = unref_calendar(cal); + ao2_ref(events, -1); return -1; } @@ -1241,6 +1250,7 @@ static int calendar_query_exec(struct ast_channel *chan, const char *cmd, char * ast_channel_datastore_add(chan, eventlist_datastore); ast_channel_unlock(chan); + cal = unref_calendar(cal); return 0; } diff --git a/res/res_calendar_caldav.c b/res/res_calendar_caldav.c index 88b043290..b1dd628a8 100644 --- a/res/res_calendar_caldav.c +++ b/res/res_calendar_caldav.c @@ -188,9 +188,8 @@ static int caldav_write_event(struct ast_calendar_event *event) return -1; } if (!(body = ast_str_create(512)) || - !(subdir = ast_str_create(32)) || - !(response = ast_str_create(512))) { - ast_log(LOG_ERROR, "Could not allocate memory for request and response!\n"); + !(subdir = ast_str_create(32))) { + ast_log(LOG_ERROR, "Could not allocate memory for request!\n"); goto write_cleanup; } @@ -417,10 +416,12 @@ static void caldav_add_event(icalcomponent *comp, struct icaltime_span *span, vo return; } data = icalproperty_get_attendee(prop); - if (!ast_strlen_zero(data)) { - attendee->data = ast_strdup(data);; - AST_LIST_INSERT_TAIL(&event->attendees, attendee, next); + if (ast_strlen_zero(data)) { + ast_free(attendee); + continue; } + attendee->data = ast_strdup(data); + AST_LIST_INSERT_TAIL(&event->attendees, attendee, next); } diff --git a/res/res_calendar_exchange.c b/res/res_calendar_exchange.c index 6c0982a63..e7beeafb2 100644 --- a/res/res_calendar_exchange.c +++ b/res/res_calendar_exchange.c @@ -433,9 +433,8 @@ static int exchangecal_write_event(struct ast_calendar_event *event) return -1; } if (!(body = ast_str_create(512)) || - !(subdir = ast_str_create(32)) || - !(response = ast_str_create(512))) { - ast_log(LOG_ERROR, "Could not allocate memory for request and response!\n"); + !(subdir = ast_str_create(32))) { + ast_log(LOG_ERROR, "Could not allocate memory for request!\n"); goto write_cleanup; } diff --git a/res/res_calendar_icalendar.c b/res/res_calendar_icalendar.c index b177b4941..dc7b5f31c 100644 --- a/res/res_calendar_icalendar.c +++ b/res/res_calendar_icalendar.c @@ -261,10 +261,12 @@ static void icalendar_add_event(icalcomponent *comp, struct icaltime_span *span, return; } data = icalproperty_get_attendee(prop); - if (!ast_strlen_zero(data)) { - attendee->data = ast_strdup(data);; - AST_LIST_INSERT_TAIL(&event->attendees, attendee, next); + if (ast_strlen_zero(data)) { + ast_free(attendee); + continue; } + attendee->data = ast_strdup(data);; + AST_LIST_INSERT_TAIL(&event->attendees, attendee, next); } diff --git a/res/res_jabber.c b/res/res_jabber.c index a68864f22..384b12c43 100644 --- a/res/res_jabber.c +++ b/res/res_jabber.c @@ -2292,6 +2292,7 @@ static void aji_handle_message(struct aji_client *client, ikspak *pak) /* insert will furtherly be added to message list */ insert->from = ast_strdup(pak->from->full); if (!insert->from) { + ast_free(insert); ast_log(LOG_ERROR, "Memory allocation failure\n"); return; } diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index 62a321147..32b762e8d 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -566,6 +566,8 @@ static int ast_rtp_new(struct ast_rtp_instance *instance, /* See if we ran out of ports or if the bind actually failed because of something other than the address being in use */ if (x == startplace || errno != EADDRINUSE) { ast_log(LOG_ERROR, "Oh dear... we couldn't allocate a port for RTP instance '%p'\n", instance); + close(rtp->s); + ast_free(rtp); return -1; } } diff --git a/res/res_srtp.c b/res/res_srtp.c index 756c62e2f..f651c4067 100644 --- a/res/res_srtp.c +++ b/res/res_srtp.c @@ -433,12 +433,14 @@ static int ast_srtp_create(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, if (!(temp = res_srtp_new())) { return -1; } + ast_module_ref(ast_module_info->self); + /* Any failures after this point can use ast_srtp_destroy to destroy the instance */ if (srtp_create(&temp->session, &policy->sp) != err_status_ok) { + ast_srtp_destroy(temp); return -1; } - ast_module_ref(ast_module_info->self); temp->rtp = rtp; *srtp = temp; |