[FFmpeg-devel] [PATCH] pass MpegTSContext ptr explicitly when it's needed (fixes #3721)

Alexander V. Lukyanov lavv17f at gmail.com
Sun Jul 6 14:54:07 CEST 2014


From: "Alexander V. Lukyanov" <lavv17f at gmail.com>

AVFormatContext->priv_data is not always a MpegTSContext, it can be
RTSPState when decoding a RTP stream. So it is necessary to pass
MpegTSContext pointer explicitly along with AVFormatContext (or alone).

This fixes memory corruption from bug #3721 (RTSPState is smaller than
MpegTSContext thus innocent memory gets overwritten).

Signed-off-by: Alexander V. Lukyanov <lavv17f at gmail.com>
---
 libavformat/mpegts.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 3434341..6dc5d77 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -357,10 +357,9 @@ static int discard_pid(MpegTSContext *ts, unsigned int pid)
  *  Assemble PES packets out of TS packets, and then call the "section_cb"
  *  function when they are complete.
  */
-static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1,
+static void write_section_data(MpegTSContext *ts, MpegTSFilter *tss1,
                                const uint8_t *buf, int buf_size, int is_start)
 {
-    MpegTSContext *ts = s->priv_data;
     MpegTSSectionFilter *tss = &tss1->u.section_filter;
     int len;
 
@@ -2010,7 +2009,6 @@ static int parse_pcr(int64_t *ppcr_high, int *ppcr_low,
 /* handle one TS packet */
 static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
 {
-    AVFormatContext *s = ts->stream;
     MpegTSFilter *tss;
     int len, pid, cc, expected_cc, cc_ok, afc, is_start, is_discontinuity,
         has_adaptation, has_payload;
@@ -2084,7 +2082,7 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
                 return 0;
             if (len && cc_ok) {
                 /* write remaining section bytes */
-                write_section_data(s, tss,
+                write_section_data(ts, tss,
                                    p, len, 0);
                 /* check whether filter has been closed */
                 if (!ts->pids[pid])
@@ -2092,12 +2090,12 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
             }
             p += len;
             if (p < p_end) {
-                write_section_data(s, tss,
+                write_section_data(ts, tss,
                                    p, p_end - p, 1);
             }
         } else {
             if (cc_ok) {
-                write_section_data(s, tss,
+                write_section_data(ts, tss,
                                    p, p_end - p, 0);
             }
         }
@@ -2170,7 +2168,7 @@ static void reanalyze(MpegTSContext *ts) {
 
 /* XXX: try to find a better synchro over several packets (use
  * get_packet_size() ?) */
-static int mpegts_resync(AVFormatContext *s)
+static int mpegts_resync(AVFormatContext *s, MpegTSContext *ts)
 {
     AVIOContext *pb = s->pb;
     int c, i;
@@ -2181,7 +2179,7 @@ static int mpegts_resync(AVFormatContext *s)
             return AVERROR_EOF;
         if (c == 0x47) {
             avio_seek(pb, -1, SEEK_CUR);
-            reanalyze(s->priv_data);
+            reanalyze(ts);
             return 0;
         }
     }
@@ -2192,7 +2190,7 @@ static int mpegts_resync(AVFormatContext *s)
 }
 
 /* return AVERROR_something if error or EOF. Return 0 if OK. */
-static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size,
+static int read_packet(AVFormatContext *s, MpegTSContext *ts, uint8_t *buf, int raw_packet_size,
                        const uint8_t **data)
 {
     AVIOContext *pb = s->pb;
@@ -2208,7 +2206,7 @@ static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size,
             uint64_t pos = avio_tell(pb);
             avio_seek(pb, -FFMIN(raw_packet_size, pos), SEEK_CUR);
 
-            if (mpegts_resync(s) < 0)
+            if (mpegts_resync(s, ts) < 0)
                 return AVERROR(EAGAIN);
             else
                 continue;
@@ -2265,7 +2263,7 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
         if (ts->stop_parse > 0)
             break;
 
-        ret = read_packet(s, packet, ts->raw_packet_size, &data);
+        ret = read_packet(s, ts, packet, ts->raw_packet_size, &data);
         if (ret != 0)
             break;
         ret = handle_packet(ts, data);
@@ -2409,7 +2407,7 @@ static int mpegts_read_header(AVFormatContext *s)
         nb_pcrs    = 0;
         nb_packets = 0;
         for (;;) {
-            ret = read_packet(s, packet, ts->raw_packet_size, &data);
+            ret = read_packet(s, ts, packet, ts->raw_packet_size, &data);
             if (ret < 0)
                 return ret;
             pid = AV_RB16(data + 1) & 0x1fff;
@@ -2456,7 +2454,7 @@ static int mpegts_raw_read_packet(AVFormatContext *s, AVPacket *pkt)
 
     if (av_new_packet(pkt, TS_PACKET_SIZE) < 0)
         return AVERROR(ENOMEM);
-    ret = read_packet(s, pkt->data, ts->raw_packet_size, &data);
+    ret = read_packet(s, ts, pkt->data, ts->raw_packet_size, &data);
     pkt->pos = avio_tell(s->pb);
     if (ret < 0) {
         av_free_packet(pkt);
@@ -2558,7 +2556,7 @@ static av_unused int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index,
             return AV_NOPTS_VALUE;
         if (buf[0] != 0x47) {
             avio_seek(s->pb, -TS_PACKET_SIZE, SEEK_CUR);
-            if (mpegts_resync(s) < 0)
+            if (mpegts_resync(s, ts) < 0)
                 return AV_NOPTS_VALUE;
             pos = avio_tell(s->pb);
             continue;
-- 
1.8.3.1



More information about the ffmpeg-devel mailing list