]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Fix a variety of memory leaks
authorMatthew Jordan <mjordan@digium.com>
Fri, 18 May 2012 14:01:56 +0000 (14:01 +0000)
committerMatthew Jordan <mjordan@digium.com>
Fri, 18 May 2012 14:01:56 +0000 (14:01 +0000)
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

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@366881 65c4cc65-6c06-0410-ace0-fbb531ad65f3

30 files changed:
apps/app_minivm.c
apps/app_page.c
apps/app_queue.c
apps/app_record.c
apps/app_voicemail.c
channels/chan_dahdi.c
channels/chan_iax2.c
channels/chan_sip.c
channels/sip/config_parser.c
funcs/func_dialgroup.c
funcs/func_odbc.c
main/cli.c
main/config.c
main/data.c
main/editline/readline.c
main/editline/term.c
main/editline/tokenizer.c
main/enum.c
main/features.c
main/netsock2.c
main/pbx.c
main/xmldoc.c
res/res_calendar.c
res/res_calendar_caldav.c
res/res_calendar_exchange.c
res/res_calendar_icalendar.c
res/res_jabber.c
res/res_musiconhold.c
res/res_rtp_asterisk.c
res/res_srtp.c

index edffd4d3f45dfd8704f898d2f055e3ec94b50d31..b88653d3f817a5e7a7e07f961345e02692cf5ae6 100644 (file)
@@ -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;
        }
 
index 9908bcbcd21cf14981141d20b8fdb100707b1101..2a8f85a7b79f53ac701af92287b10184b4b2b914 100644 (file)
@@ -248,6 +248,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;
                }
 
index 535170205ddd0990b596fe517fe9590e16f19c4e..cba347f12a4f108926e59269749fcf5d70351ed5 100644 (file)
@@ -1851,9 +1851,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;
 }
 
@@ -4319,6 +4327,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;
        }
index 6098ca7290ca3007be3e2fae66c80a28ceccba3d..91fbd984b4333e63c8ecadcca839a8e579fffdbb 100644 (file)
@@ -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", chan->name);
-               if (sildet)
-                       ast_dsp_free(sildet);
+               }
        }
 
+       if (sildet) {
+               ast_dsp_free(sildet);
+       }
        return res;
 }
 
index 58f96fd86542c41611acc2d92595a52c7ee732aa..7101cb5c96a340935f69a763be7e06b8ade23871 100644 (file)
@@ -11517,16 +11517,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) {
@@ -12510,8 +12516,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);
 }
@@ -12520,26 +12528,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)
index 85b621882adb3be4ba35cd484f6803c8e99ad5d4..ebd1ea5edec18d1c6eeaa138a8e96ca65f9e5522 100644 (file)
@@ -9304,6 +9304,7 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
                                if ((ast->_state == AST_STATE_UP) && !p->outgoing) {
                                        /* Treat this as a "hangup" instead of a "busy" on the assumption that
                                           a busy */
+                                       ast_frfree(f);
                                        f = NULL;
                                }
                        } else if (f->frametype == AST_FRAME_DTMF_BEGIN
@@ -9329,7 +9330,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;
@@ -9344,6 +9346,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);
index a92f04f4a041f865c57adf9d99703c2672a78b12..a9c58a80aa28b30e46001f60eb7e9cf13ac025e6 100644 (file)
@@ -6990,6 +6990,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]);
        }
@@ -9942,6 +9943,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;
                }
index 494f45df8a5509c021a9b2ae97aa05049eaf021f..60fd68f26dfb51ef1f1fe4dae2cf7ca0ff8ac9fa 100644 (file)
@@ -7573,6 +7573,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->name, target_context);
                                }
+                               ast_frfree(fr);
                                fr = &ast_null_frame;
                        } else {
                                ast_channel_lock(ast);
@@ -7584,6 +7585,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->_state != AST_STATE_UP) {
+               ast_frfree(fr);
                fr = &ast_null_frame;
        }
 
index 89f1a988edd4c3378d38852c4512573d2dc03083..239346bf4d0d55a5a218848bf6f9a1dd64ff74af 100644 (file)
@@ -556,6 +556,8 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
                ast_test_status_update(test, "Test 12, add domain port failed.\n");
                res = AST_TEST_FAIL;
        }
+       ast_string_field_free_memory(reg);
+       ast_free(reg);
 
        /* ---Test reg13, domain port without secret --- */
        if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
@@ -582,7 +584,9 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
 
                ast_test_status_update(test, "Test 13, domain port without secret failed.\n");
                res = AST_TEST_FAIL;
-}
+       }
+       ast_string_field_free_memory(reg);
+       ast_free(reg);
 
        /* ---Test reg 9, missing domain, expected to fail --- */
        if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
index c3322e3f9b451ccf5967accdc1856fbbd711b492..0e078cd80dd45bbbadaa12d8ddaacdd7040425ee 100644 (file)
@@ -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;
 }
index edb69f0930c982a9598c0aace065be463213cf41..667e093b30c5e6aa9ce4b9219c203237a0aee9dc 100644 (file)
@@ -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;
        }
 
index c35b941d1054e12d369638cb8089c8b3b47a8f3e..5802c1d54c6800b7b8e012d9c0a35ce89b6e1939 100644 (file)
@@ -2340,9 +2340,11 @@ 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;
 
index 668fba1bd9fe567a2bfa35db8f64ee4fd3264450..ac8063e09ec2036e819d65c1bc25c62ffe8d0236 100644 (file)
@@ -1487,6 +1487,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;
                        }
                }
@@ -1641,13 +1643,13 @@ 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;
                lline_buffer = NULL;
        }
-       
+
        if (count == 0)
                return NULL;
 
index a9ccb73a22864ce84266913766fb7a37b731e1be..47e7fd5bdad57256cd1b4522fa4f23e7e199f711 100644 (file)
@@ -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;
        }
 
index 4729fa952f9a5c82ace2dc11ad38b89f13274c1d..77827c3f911945e6d0c5722085f77848e08a864d 100644 (file)
@@ -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;
index fb627cabb72956edfbb1f28ba37dc144751f8494..63cec6e43e57de8929aff11b2298631fb2ea2f60 100644 (file)
@@ -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;
index f0de39bc9fb86c349f462455b4ba9c594626a090..67398c6869dd6259ac0ec8fba9086f0c2efa22c0 100644 (file)
@@ -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;
index 92f185c6079323b43c9d295b50929d69e9fb010d..d590666519a7da3ac8c515a071940b5e9b3c7770 100644 (file)
@@ -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;
        }
 
index 7c47c85f5655f11189ee9be1f431d73a94d291b2..aa62b5b3afe8baf90c3349d217251db1ea6e7978 100644 (file)
@@ -5740,6 +5740,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;
        }
 
@@ -5754,6 +5755,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;
        }
 
index 1922ac3881bead13cf563e1ad564d6773feeaa4a..5ae4ceb7095d79045ad68195b8a17adc70743bf1 100644 (file)
@@ -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;
index d0a24df9cb39e433db05b60ef8dedeec3de6ff11..8da4bb0161fc23205152525d70a4e6deee1b2f4d 100644 (file)
@@ -7493,6 +7493,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.
@@ -8218,6 +8220,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;
                }
index 1c5fe3d1ba7c5d0aed132ba84e0bcf81b4d228f2..b940404c928b41db7b0e2ab7cf8b3c89a6b0144d 100644 (file)
@@ -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;
        }
 
index bd06fe82deb3c7c14758f58186f4c96edcb56c65..18d778ce4f72c9cacc264f0cc08118166f954b16 100644 (file)
@@ -362,6 +362,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)))) {
@@ -369,10 +370,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)
@@ -1048,6 +1052,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;
 }
@@ -1202,6 +1207,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;
                        }
@@ -1219,6 +1226,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;
        }
 
@@ -1229,6 +1238,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;
 }
 
index f569b9eab34f8495cf328ae8a88a867bc8a2c130..21c180f227e6a4e4f9535978cc0745ce3f4618cd 100644 (file)
@@ -181,9 +181,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;
        }
 
@@ -406,10 +405,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);
        }
 
 
index 4a2df1822c825e041a278d908bec6b807b9145bc..968686293b3d76033798b06f7ac4e4dcddfdce11 100644 (file)
@@ -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;
        }
 
index b177b4941198e57c8ce30f1691e473fcbb6dccc8..dc7b5f31cdca17135454ed83abe3d73544ba5955 100644 (file)
@@ -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);
        }
 
 
index 870508d03242407ac52cf1075117d6bc26968e84..cd657e759e6f67463e3f5c8673d1ad41f6ea6aa3 100644 (file)
@@ -2294,6 +2294,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;
                }
index 34124e9ba15bfcf29f980ee97a67648a1e233627..9b5cb8c5c508e5050283c5a1214eb7534172535e 100644 (file)
@@ -1092,10 +1092,12 @@ static int moh_scan_files(struct mohclass *class) {
        class->total_files = 0;
        if (!getcwd(path, sizeof(path))) {
                ast_log(LOG_WARNING, "getcwd() failed: %s\n", strerror(errno));
+               closedir(files_DIR);
                return -1;
        }
        if (chdir(dir_path) < 0) {
                ast_log(LOG_WARNING, "chdir() failed: %s\n", strerror(errno));
+               closedir(files_DIR);
                return -1;
        }
        while ((files_dirent = readdir(files_DIR))) {
index 27329c6dffcad04c5211e681daeb01a67094cc3d..b5819b0f2476f41b334dda20333cb98a96a26d95 100644 (file)
@@ -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;
                }
        }
index 756c62e2fadb0e179f133ebc3b74fcb6575e12de..f651c406751c71372a9c31ea902931f62e1c64df 100644 (file)
@@ -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;