Browse code

avformat/mms: Add missing chunksize check

Fixes: out of array read
Fixes: mms-crash-01b6c5d85f9d9f40f4e879896103e9f5b222816a

Found-by: Paul Ch <paulcher@icloud.com>
1st hunk by Paul Ch <paulcher@icloud.com>
Tested-by: Paul Ch <paulcher@icloud.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit cced03dd667a5df6df8fd40d8de0bff477ee02e8)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

Michael Niedermayer authored on 2018/07/04 03:33:04
Showing 1 changed files
... ...
@@ -94,24 +94,26 @@ int ff_mms_asf_header_parser(MMSContext *mms)
94 94
                 }
95 95
             }
96 96
         } else if (!memcmp(p, ff_asf_stream_header, sizeof(ff_asf_guid))) {
97
-            flags     = AV_RL16(p + sizeof(ff_asf_guid)*3 + 24);
98
-            stream_id = flags & 0x7F;
99
-            //The second condition is for checking CS_PKT_STREAM_ID_REQUEST packet size,
100
-            //we can calculate the packet size by stream_num.
101
-            //Please see function send_stream_selection_request().
102
-            if (mms->stream_num < MMS_MAX_STREAMS &&
103
-                    46 + mms->stream_num * 6 < sizeof(mms->out_buffer)) {
104
-                mms->streams = av_fast_realloc(mms->streams,
105
-                                   &mms->nb_streams_allocated,
106
-                                   (mms->stream_num + 1) * sizeof(MMSStream));
107
-                if (!mms->streams)
108
-                    return AVERROR(ENOMEM);
109
-                mms->streams[mms->stream_num].id = stream_id;
110
-                mms->stream_num++;
111
-            } else {
112
-                av_log(NULL, AV_LOG_ERROR,
113
-                       "Corrupt stream (too many A/V streams)\n");
114
-                return AVERROR_INVALIDDATA;
97
+            if (end - p >= (sizeof(ff_asf_guid) * 3 + 26)) {
98
+                flags     = AV_RL16(p + sizeof(ff_asf_guid)*3 + 24);
99
+                stream_id = flags & 0x7F;
100
+                //The second condition is for checking CS_PKT_STREAM_ID_REQUEST packet size,
101
+                //we can calculate the packet size by stream_num.
102
+                //Please see function send_stream_selection_request().
103
+                if (mms->stream_num < MMS_MAX_STREAMS &&
104
+                        46 + mms->stream_num * 6 < sizeof(mms->out_buffer)) {
105
+                    mms->streams = av_fast_realloc(mms->streams,
106
+                                       &mms->nb_streams_allocated,
107
+                                       (mms->stream_num + 1) * sizeof(MMSStream));
108
+                    if (!mms->streams)
109
+                        return AVERROR(ENOMEM);
110
+                    mms->streams[mms->stream_num].id = stream_id;
111
+                    mms->stream_num++;
112
+                } else {
113
+                    av_log(NULL, AV_LOG_ERROR,
114
+                           "Corrupt stream (too many A/V streams)\n");
115
+                    return AVERROR_INVALIDDATA;
116
+                }
115 117
             }
116 118
         } else if (!memcmp(p, ff_asf_ext_stream_header, sizeof(ff_asf_guid))) {
117 119
             if (end - p >= 88) {
... ...
@@ -143,6 +145,12 @@ int ff_mms_asf_header_parser(MMSContext *mms)
143 143
             }
144 144
         } else if (!memcmp(p, ff_asf_head1_guid, sizeof(ff_asf_guid))) {
145 145
             chunksize = 46; // see references [2] section 3.4. This should be set 46.
146
+            if (chunksize > end - p) {
147
+                av_log(NULL, AV_LOG_ERROR,
148
+                    "Corrupt stream (header chunksize %"PRId64" is invalid)\n",
149
+                    chunksize);
150
+                return AVERROR_INVALIDDATA;
151
+            }
146 152
         }
147 153
         p += chunksize;
148 154
     }