From: Corey Farrell Date: Sun, 2 Nov 2014 08:03:18 +0000 (+0000) Subject: Fix ast_writestream leaks X-Git-Tag: 11.14.0-rc1~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9dc2f92921c89f63a232889e8b43e0b3c082e1d7;p=thirdparty%2Fasterisk.git Fix ast_writestream leaks Fix cleanup in __ast_play_and_record where others[x] may be leaked. This was caught where prepend != NULL && outmsg != NULL, once realfile[x] == NULL any further others[x] would be leaked. A cleanup block was also added for prepend != NULL && outmsg == NULL. 11+: Fix leak of ast_writestream recording_fs in app_voicemail:leave_voicemail. ASTERISK-24476 #close Reported by: Corey Farrell Review: https://reviewboard.asterisk.org/r/4138/ ........ Merged revisions 427023 from http://svn.asterisk.org/svn/asterisk/branches/1.8 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/11@427024 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 0fd9fb47ca..aebadb064d 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -6041,6 +6041,7 @@ static int msg_create_from_file(struct ast_vm_recording_data *recdata) ast_getformatbyname(recdata->recording_ext, &result); duration = (int) (framelength / ast_format_rate(&result)); } + ast_closeframe(recording_fs); } /* If the duration was below the minimum duration for the user, let's just drop the whole thing now */ diff --git a/main/app.c b/main/app.c index 1179233536..a31fa0c8ce 100644 --- a/main/app.c +++ b/main/app.c @@ -1385,18 +1385,20 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, ast_truncstream(others[x]); ast_closestream(others[x]); } - } - - if (prepend && outmsg) { + } else if (prepend && outmsg) { struct ast_filestream *realfiles[AST_MAX_FORMATS]; struct ast_frame *fr; for (x = 0; x < fmtcnt; x++) { snprintf(comment, sizeof(comment), "Opening the real file %s.%s\n", recordfile, sfmt[x]); realfiles[x] = ast_readfile(recordfile, sfmt[x], comment, O_RDONLY, 0, 0); - if (!others[x] || !realfiles[x]) { + if (!others[x]) { break; } + if (!realfiles[x]) { + ast_closestream(others[x]); + continue; + } /*!\note Same logic as above. */ if (dspsilence) { ast_stream_rewind(others[x], dspsilence - 200); @@ -1413,7 +1415,15 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile, ast_verb(4, "Recording Format: sfmts=%s, prependfile %s, recordfile %s\n", sfmt[x], prependfile, recordfile); ast_filedelete(prependfile, sfmt[x]); } + } else { + for (x = 0; x < fmtcnt; x++) { + if (!others[x]) { + break; + } + ast_closestream(others[x]); + } } + if (rfmt.id && ast_set_read_format(chan, &rfmt)) { ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(&rfmt), ast_channel_name(chan)); }