Fix crash in app_voicemail during close_mailbox
authorMatthew Jordan <mjordan@digium.com>
Sat, 25 Feb 2012 17:22:55 +0000 (17:22 +0000)
committerMatthew Jordan <mjordan@digium.com>
Sat, 25 Feb 2012 17:22:55 +0000 (17:22 +0000)
In r354890, a memory leak in app_voicemail was fixed by properly disposing of
the allocated heard/deleted pointers.  However, there are situations,
particularly when no messages are found in a folder, where these pointers are
not allocated and not NULL.  In that case, an invalid free would be attempted,
which could crash app_voicemail.  As there are a number of code paths where
this could occur, this patch uses the number of messages detected in the folder
before it attempts to free the pointers.  This resolves the crash detected in
the Asterisk Test Suite's check_voicemail_nominal test.
........

Merged revisions 356797 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 356798 from http://svn.asterisk.org/svn/asterisk/branches/10

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

apps/app_voicemail.c

index 2453d01..fc7417b 100644 (file)
@@ -8042,9 +8042,9 @@ static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu, int box)
 static int close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
 {
        int x = 0;
+       int last_msg_idx = 0;
 
 #ifndef IMAP_STORAGE
-       int last_msg_idx;
        int res = 0, nummsg;
        char fn2[PATH_MAX];
 #endif
@@ -8121,7 +8121,8 @@ static int close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
        if (vms->deleted) {
                /* Since we now expunge after each delete, deleting in reverse order
                 * ensures that no reordering occurs between each step. */
-               for (x = vms->dh_arraysize - 1; x >= 0; x--) {
+               last_msg_idx = vms->dh_arraysize;
+               for (x = last_msg_idx - 1; x >= 0; x--) {
                        if (vms->deleted[x]) {
                                ast_debug(3, "IMAP delete of %d\n", x);
                                DELETE(vms->curdir, x, vms->fn, vmu);
@@ -8131,10 +8132,10 @@ static int close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
 #endif
 
 done:
-       if (vms->deleted) {
+       if (vms->deleted && last_msg_idx) {
                ast_free(vms->deleted);
        }
-       if (vms->heard) {
+       if (vms->heard && last_msg_idx) {
                ast_free(vms->heard);
        }