shithub: sox

Download patch

ref: 9b27bc7f098efe4eb4a18a3033caceec723b4604
parent: 9c12c40e7cfee1fc552a4d93425c73ff1ea490ab
author: Mans Rullgard <mans@mansr.com>
date: Thu Apr 26 16:19:25 EDT 2018

amr: check for invalid block types [bug #305]

This fixes infinite loops and crashes with invalid inputs.

--- a/src/amr.h
+++ b/src/amr.h
@@ -74,14 +74,19 @@
 static size_t decode_1_frame(sox_format_t * ft)
 {
   priv_t * p = (priv_t *)ft->priv;
-  size_t n_1;
+  size_t n;
   uint8_t coded[AMR_CODED_MAX];
 
   if (lsx_readbuf(ft, &coded[0], (size_t)1) != 1)
     return AMR_FRAME;
-  n_1 = amr_block_size[(coded[0] >> 3) & 0x0F] - 1;
-  if (lsx_readbuf(ft, &coded[1], n_1) != n_1)
+  n = amr_block_size[(coded[0] >> 3) & 0x0F];
+  if (!n) {
+    lsx_fail("invalid block type");
     return AMR_FRAME;
+  }
+  n--;
+  if (lsx_readbuf(ft, &coded[1], n) != n)
+    return AMR_FRAME;
   AMR_CALL(p, AmrOpencoreDecoderDecode, AmrGp3DecoderDecode, (p->state, coded, p->pcm, 0));
   return 0;
 }
@@ -160,6 +165,10 @@
 
   for (frames = 0; lsx_readbuf(ft, &coded, (size_t)1) == 1; ++frames) {
     frame_size = amr_block_size[coded >> 3 & 15];
+    if (!frame_size) {
+      lsx_fail("invalid block type");
+      break;
+    }
     if (lsx_seeki(ft, frame_size - 1, SEEK_CUR)) {
       lsx_fail("seek");
       break;