[1/2] rtpdec_h264: Add input size checks

Message ID 1336160903-50388-1-git-send-email-martin@martin.st
State Superseded
Headers show

Commit Message

Martin Storsjö May 4, 2012, 7:48 p.m.
From: Ivan Kovtunov <belevern@gmail.com>

This fixes crashes if given too short data packets.
---
 libavformat/rtpdec_h264.c |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

Comments

Luca Barbato May 4, 2012, 8:32 p.m. | #1
"Martin Storsjö" <martin@martin.st> wrote:

>From: Ivan Kovtunov <belevern@gmail.com>
>
>This fixes crashes if given too short data packets.
>---
> libavformat/rtpdec_h264.c |   16 +++++++++++++---
> 1 file changed, 13 insertions(+), 3 deletions(-)
>
>diff --git a/libavformat/rtpdec_h264.c b/libavformat/rtpdec_h264.c
>index 32a57d3..9a8f12c 100644
>--- a/libavformat/rtpdec_h264.c
>+++ b/libavformat/rtpdec_h264.c
>@@ -173,11 +173,18 @@ static int h264_handle_packet(AVFormatContext
>*ctx,
>                               const uint8_t * buf,
>                               int len, int flags)
> {
>-    uint8_t nal = buf[0];
>-    uint8_t type = (nal & 0x1f);
>+    uint8_t nal;
>+    uint8_t type;
>     int result= 0;
>     uint8_t start_sequence[] = { 0, 0, 0, 1 };
> 
>+    if (!len) {
>+        av_log(ctx, AV_LOG_ERROR, "Empty H264 RTP packet\n");
>+        return -1;

AVERROR

>+    }
>+    nal  = buf[0];
>+    type = nal & 0x1f;
>+
> #ifdef DEBUG
>     assert(data);
>     assert(data->cookie == MAGIC_COOKIE);
>@@ -271,7 +278,7 @@ static int h264_handle_packet(AVFormatContext *ctx,
>     case 28:                   // FU-A (fragmented nal)
>         buf++;
>         len--;                  // skip the fu_indicator
>-        {
>+        if (len > 1) {
>  // these are the same as above, we just redo them here for clarity...
>             uint8_t fu_indicator = nal;
>             uint8_t fu_header = *buf;   // read the fu_header.
>@@ -302,6 +309,9 @@ static int h264_handle_packet(AVFormatContext *ctx,
>                 av_new_packet(pkt, len);
>                 memcpy(pkt->data, buf, len);
>             }
>+        } else {
>+            av_log(ctx, AV_LOG_ERROR, "Too short data for FU-A H264
>RTP packet\n");
>+            result = -1;

Again 

The rest is fine.

Patch

diff --git a/libavformat/rtpdec_h264.c b/libavformat/rtpdec_h264.c
index 32a57d3..9a8f12c 100644
--- a/libavformat/rtpdec_h264.c
+++ b/libavformat/rtpdec_h264.c
@@ -173,11 +173,18 @@  static int h264_handle_packet(AVFormatContext *ctx,
                               const uint8_t * buf,
                               int len, int flags)
 {
-    uint8_t nal = buf[0];
-    uint8_t type = (nal & 0x1f);
+    uint8_t nal;
+    uint8_t type;
     int result= 0;
     uint8_t start_sequence[] = { 0, 0, 0, 1 };
 
+    if (!len) {
+        av_log(ctx, AV_LOG_ERROR, "Empty H264 RTP packet\n");
+        return -1;
+    }
+    nal  = buf[0];
+    type = nal & 0x1f;
+
 #ifdef DEBUG
     assert(data);
     assert(data->cookie == MAGIC_COOKIE);
@@ -271,7 +278,7 @@  static int h264_handle_packet(AVFormatContext *ctx,
     case 28:                   // FU-A (fragmented nal)
         buf++;
         len--;                  // skip the fu_indicator
-        {
+        if (len > 1) {
             // these are the same as above, we just redo them here for clarity...
             uint8_t fu_indicator = nal;
             uint8_t fu_header = *buf;   // read the fu_header.
@@ -302,6 +309,9 @@  static int h264_handle_packet(AVFormatContext *ctx,
                 av_new_packet(pkt, len);
                 memcpy(pkt->data, buf, len);
             }
+        } else {
+            av_log(ctx, AV_LOG_ERROR, "Too short data for FU-A H264 RTP packet\n");
+            result = -1;
         }
         break;