aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonald S. Bultje <rsbultje@gmail.com>2012-02-22 11:33:24 -0800
committerRonald S. Bultje <rsbultje@gmail.com>2012-02-22 12:00:23 -0800
commitaac07a7a4c2c7a4a29cf6dbc88c1b9fdd191b99d (patch)
treee3adffb893f208b380c9225a1bda0dccf0abf022
parent1cd9a6154bc1ac1193c703cea980ed21c3e53792 (diff)
downloadffmpeg-aac07a7a4c2c7a4a29cf6dbc88c1b9fdd191b99d.tar.gz
rm: prevent infinite loops for index parsing.
Specifically, prevent jumping back in the file for the next index, since this can lead to infinite loops where we jump between indexes referring to each other, and don't read indexes that don't fit in the file. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org
-rw-r--r--libavformat/rmdec.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index ed16b0715c..6775294d06 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -370,8 +370,19 @@ static int rm_read_index(AVFormatContext *s)
st = s->streams[n];
break;
}
- if (n == s->nb_streams)
+ if (n == s->nb_streams) {
+ av_log(s, AV_LOG_ERROR,
+ "Invalid stream index %d for index at pos %"PRId64"\n",
+ str_id, avio_tell(pb));
goto skip;
+ } else if ((avio_size(pb) - avio_tell(pb)) / 14 < n_pkts) {
+ av_log(s, AV_LOG_ERROR,
+ "Nr. of packets in packet index for stream index %d "
+ "exceeds filesize (%"PRId64" at %"PRId64" = %d)\n",
+ str_id, avio_size(pb), avio_tell(pb),
+ (avio_size(pb) - avio_tell(pb)) / 14);
+ goto skip;
+ }
for (n = 0; n < n_pkts; n++) {
avio_skip(pb, 2);
@@ -383,9 +394,12 @@ static int rm_read_index(AVFormatContext *s)
}
skip:
- if (next_off && avio_tell(pb) != next_off &&
- avio_seek(pb, next_off, SEEK_SET) < 0)
+ if (next_off && avio_tell(pb) < next_off &&
+ avio_seek(pb, next_off, SEEK_SET) < 0) {
+ av_log(s, AV_LOG_ERROR,
+ "Non-linear index detected, not supported\n");
return -1;
+ }
} while (next_off);
return 0;