summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Brooks <john.brooks@bluecherry.net>2011-10-12 00:53:12 -0600
committerMichael Niedermayer <michaelni@gmx.at>2011-10-13 03:31:01 +0200
commitc1847c932b1576e8224c38e112a5fd29fa8a6098 (patch)
treeec6ca120e791ec174718e8762338aee2e9163ea9
parentdc66951bb2a10c1c6e1352fd6f0a601dc77785e5 (diff)
Correct buffer handling for RTCP packets
Previous code could read 4 bytes past the end of the buffer on a RTCP_SR packet or offset a pointer by an unchecked external value (payload_len), though neither will reliably cause a crash or other misbehavior beyond garbage timestamps. Additionally, unknown RTCP packet types, even in compounded packets, are now ignored as per RFC 3550 section 6.1, page 22, though currently this only has any practical effect if a sender puts an unrecognized type before RTCP_BYE in a compounded packet, or (incorrectly) does not put RTCP_SR first. Signed-off-by: John Brooks <john.brooks@bluecherry.net> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavformat/rtpdec.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index f9252a9bb3..002222f0ee 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -112,14 +112,15 @@ RTPDynamicProtocolHandler *ff_rtp_handler_find_by_id(int id,
static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len)
{
int payload_len;
- while (len >= 2) {
+ while (len >= 4) {
+ payload_len = FFMIN(len, (AV_RB16(buf + 2) + 1) * 4);
+
switch (buf[1]) {
case RTCP_SR:
- if (len < 16) {
+ if (payload_len < 20) {
av_log(NULL, AV_LOG_ERROR, "Invalid length for RTCP SR packet\n");
return AVERROR_INVALIDDATA;
}
- payload_len = (AV_RB16(buf + 2) + 1) * 4;
s->last_rtcp_ntp_time = AV_RB64(buf + 8);
s->last_rtcp_timestamp = AV_RB32(buf + 16);
@@ -130,14 +131,13 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int l
s->rtcp_ts_offset = s->last_rtcp_timestamp - s->base_timestamp;
}
- buf += payload_len;
- len -= payload_len;
break;
case RTCP_BYE:
return -RTCP_BYE;
- default:
- return -1;
}
+
+ buf += payload_len;
+ len -= payload_len;
}
return -1;
}