[FFmpeg-devel,2/6] h264_mp4toannexb_bsf: Improve extradata overread checks

Submitted by Andreas Rheinhardt on July 24, 2019, 5:15 p.m.

Details

Message ID 20190724171557.10037-1-andreas.rheinhardt@gmail.com
State New
Headers show

Commit Message

Andreas Rheinhardt July 24, 2019, 5:15 p.m.
Currently during parsing the extradata, h264_mp4toannexb checks for
overreads by adding the size of the current unit to the current position
pointer and comparing this to the end position of the extradata. But
pointer comparisons and pointer arithmetic is only defined if it does not
exceed the object it is used on (one past the last element of an array
is allowed, too). In practice, this might lead to overflows. Therefore
the check has been changed.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavcodec/h264_mp4toannexb_bsf.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c
index bbf124ad04..374c2d59fb 100644
--- a/libavcodec/h264_mp4toannexb_bsf.c
+++ b/libavcodec/h264_mp4toannexb_bsf.c
@@ -72,7 +72,8 @@  static int h264_extradata_to_annexb(AVBSFContext *ctx, const int padding)
     uint32_t total_size                 = 0;
     uint8_t *out                        = NULL, unit_nb, sps_done = 0,
              sps_seen                   = 0, pps_seen = 0;
-    const uint8_t *extradata            = ctx->par_in->extradata + 4;
+    const uint8_t *extradata            = ctx->par_in->extradata + 4,
+                  *extradata_end        = ctx->par_in->extradata + ctx->par_in->extradata_size;
     static const uint8_t nalu_header[4] = { 0, 0, 0, 1 };
     int length_size = (*extradata++ & 0x3) + 1; // retrieve length coded size
 
@@ -91,9 +92,10 @@  static int h264_extradata_to_annexb(AVBSFContext *ctx, const int padding)
         int err;
 
         unit_size   = AV_RB16(extradata);
+        extradata  += 2;
         total_size += unit_size + 4;
         av_assert1(total_size <= INT_MAX - padding);
-        if (extradata + 2 + unit_size > ctx->par_in->extradata + ctx->par_in->extradata_size) {
+        if (extradata_end - extradata < unit_size) {
             av_log(ctx, AV_LOG_ERROR, "Packet header is not contained in global extradata, "
                    "corrupted stream or invalid MP4/AVCC bitstream\n");
             av_free(out);
@@ -102,8 +104,8 @@  static int h264_extradata_to_annexb(AVBSFContext *ctx, const int padding)
         if ((err = av_reallocp(&out, total_size + padding)) < 0)
             return err;
         memcpy(out + total_size - unit_size - 4, nalu_header, 4);
-        memcpy(out + total_size - unit_size, extradata + 2, unit_size);
-        extradata += 2 + unit_size;
+        memcpy(out + total_size - unit_size, extradata, unit_size);
+        extradata += unit_size;
 pps:
         if (!unit_nb && !sps_done++) {
             unit_nb = *extradata++; /* number of pps unit(s) */