From d3ed07d38a99b103179bf8cb12b68d2628758702 Mon Sep 17 00:00:00 2001 From: Matthew Jordan Date: Sat, 25 Feb 2012 17:21:29 +0000 Subject: [PATCH] Fix crash in app_voicemail during close_mailbox 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. git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@356797 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_voicemail.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index e74d76db5f..b15c239b41 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -7938,9 +7938,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 @@ -8017,7 +8017,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); @@ -8027,10 +8028,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); }