]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
translate: Move freeing of frame to after it is used.
authorJoshua Colp <jcolp@digium.com>
Fri, 22 Nov 2013 17:10:01 +0000 (17:10 +0000)
committerJoshua Colp <jcolp@digium.com>
Fri, 22 Nov 2013 17:10:01 +0000 (17:10 +0000)
When translating from one format to another it is possible
to inform the translation function that the source frame should
be freed. This was previously done immediately but shortly
afterwards the frame that was freed was accessed and used again.

This change moves code around a bit so that the frame is now
freed after it has been completely used.

(closes issue ASTERISK-22788)
Reported by: Corey Farrell
Patches:
translate-access-after-free-11up.patch uploaded by coreyfarrell (license 5909)
translate-access-after-free-1.8.patch uploaded by coreyfarrell (license 5909)

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

main/translate.c

index 1015ef6ef5009c7cd73acca8c6ac5e5972a5def5..ac5a8b9782b097c5a75a46b1bc6babfc3cedc4e8 100644 (file)
@@ -369,38 +369,41 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
                        ast_frfree(out);
                out = p->t->frameout(p);
        }
-       if (consume)
-               ast_frfree(f);
-       if (out == NULL)
-               return NULL;
-       /* we have a frame, play with times */
-       if (!ast_tvzero(delivery)) {
-               /* Regenerate prediction after a discontinuity */
-               if (ast_tvzero(path->nextout))
-                       path->nextout = ast_tvnow();
-
-               /* Use next predicted outgoing timestamp */
-               out->delivery = path->nextout;
-               
-               /* Predict next outgoing timestamp from samples in this
-                  frame. */
-               path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(out->subclass.codec)));
-               if (f->samples != out->samples && ast_test_flag(out, AST_FRFLAG_HAS_TIMING_INFO)) {
-                       ast_debug(4, "Sample size different %u vs %u\n", f->samples, out->samples);
-                       ast_clear_flag(out, AST_FRFLAG_HAS_TIMING_INFO);
+       if (out) {
+               /* we have a frame, play with times */
+               if (!ast_tvzero(delivery)) {
+                       /* Regenerate prediction after a discontinuity */
+                       if (ast_tvzero(path->nextout)) {
+                               path->nextout = ast_tvnow();
+                       }
+
+                       /* Use next predicted outgoing timestamp */
+                       out->delivery = path->nextout;
+
+                       /* Predict next outgoing timestamp from samples in this
+                          frame. */
+                       path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(out->subclass.codec)));
+                       if (f->samples != out->samples && ast_test_flag(out, AST_FRFLAG_HAS_TIMING_INFO)) {
+                               ast_debug(4, "Sample size different %u vs %u\n", f->samples, out->samples);
+                               ast_clear_flag(out, AST_FRFLAG_HAS_TIMING_INFO);
+                       }
+               } else {
+                       out->delivery = ast_tv(0, 0);
+                       ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
+                       if (has_timing_info) {
+                               out->ts = ts;
+                               out->len = len;
+                               out->seqno = seqno;
+                       }
                }
-       } else {
-               out->delivery = ast_tv(0, 0);
-               ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
-               if (has_timing_info) {
-                       out->ts = ts;
-                       out->len = len;
-                       out->seqno = seqno;
+               /* Invalidate prediction if we're entering a silence period */
+               if (out->frametype == AST_FRAME_CNG) {
+                       path->nextout = ast_tv(0, 0);
                }
        }
-       /* Invalidate prediction if we're entering a silence period */
-       if (out->frametype == AST_FRAME_CNG)
-               path->nextout = ast_tv(0, 0);
+       if (consume) {
+               ast_frfree(f);
+       }
        return out;
 }