aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonald S. Bultje <rsbultje@gmail.com>2012-02-22 11:33:24 -0800
committerReinhard Tartler <siretart@tauware.de>2012-04-01 18:33:27 +0200
commit811989e91092bfa8cbcf6305eee7c1353da99809 (patch)
tree37d408c6896f39998c0afcdf19c86d8e163e6ad0
parent678737c26be4fb93dc6b3ede04b8231bd39b2e3b (diff)
downloadffmpeg-811989e91092bfa8cbcf6305eee7c1353da99809.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 (cherry picked from commit aac07a7a4c2c7a4a29cf6dbc88c1b9fdd191b99d) Signed-off-by: Reinhard Tartler <siretart@tauware.de>
-rw-r--r--libavformat/rmdec.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index fbc4d0cee6..dbfeb927cf 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -350,8 +350,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);
@@ -363,9 +374,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;