summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Miller <will.miller@pexip.com>2020-10-12 12:21:17 +0100
committerTim-Philipp Müller <tim@centricular.com>2020-10-12 18:43:31 +0100
commit78ad7a6598c7e15cd157d9065eb50a4fe5bdb4c6 (patch)
treeee8478350436c46b8e235c967b3042dcde120f1a
parentb43853574320a840caef9bba9fa3fe5263abf6a5 (diff)
downloadgstreamer-plugins-base-78ad7a6598c7e15cd157d9065eb50a4fe5bdb4c6.tar.gz
gstrtpbuffer: fix header extension length validation
We validate the header extensions length of an RTP buffer by comparing it against the block size. Since we multiply the length in words by 4 to get the length in bytes, a suitably large length could cause a wrapround of the uint16, giving a lower length which erroneously passes the check and allows the buffer to be mapped. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/866>
-rw-r--r--gst-libs/gst/rtp/gstrtpbuffer.c2
-rw-r--r--tests/check/libs/rtp.c25
2 files changed, 26 insertions, 1 deletions
diff --git a/gst-libs/gst/rtp/gstrtpbuffer.c b/gst-libs/gst/rtp/gstrtpbuffer.c
index fb4f573ba..d434e7ec3 100644
--- a/gst-libs/gst/rtp/gstrtpbuffer.c
+++ b/gst-libs/gst/rtp/gstrtpbuffer.c
@@ -369,7 +369,7 @@ gst_rtp_buffer_map (GstBuffer * buffer, GstMapFlags flags, GstRTPBuffer * rtp)
/* calc extension length when present. */
if (data[0] & 0x10) {
guint8 *extdata;
- guint16 extlen;
+ gsize extlen;
/* find memory for the extension bits, we find the block for the first 4
* bytes, all other extension bytes should also be in this block */
diff --git a/tests/check/libs/rtp.c b/tests/check/libs/rtp.c
index cdb9224c0..d6a74b8a0 100644
--- a/tests/check/libs/rtp.c
+++ b/tests/check/libs/rtp.c
@@ -1898,6 +1898,29 @@ GST_START_TEST (test_ext_timestamp_wraparound_disordered_cannot_unwrap)
GST_END_TEST;
+GST_START_TEST (test_rtp_buffer_extlen_wraparound)
+{
+ GstBuffer *buf;
+ guint8 rtp_test_buffer[] = {
+ 0x90, 0x7c, 0x18, 0xa6, /* |V=2|P|X|CC|M|PT|sequence number| */
+ 0x7a, 0x62, 0x17, 0x0f, /* |timestamp| */
+ 0x70, 0x23, 0x91, 0x38, /* |synchronization source (SSRC) identifier| */
+ 0xbe, 0xde, 0x40, 0x01, /* |0xBE|0xDE|length=16385| */
+ 0x00, 0x00, 0x00, 0x00, /* |0 (pad)|0 (pad)|0 (pad)|0 (pad)| */
+ 0x00, 0x00, 0x00, 0x00, /* |0 (pad)|0 (pad)|0 (pad)|0 (pad)| */
+ 0xff, 0xff, 0xff, 0xff /* |dummy payload| */
+ };
+
+ GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
+
+ buf = gst_buffer_new_and_alloc (sizeof (rtp_test_buffer));
+ gst_buffer_fill (buf, 0, rtp_test_buffer, sizeof (rtp_test_buffer));
+ fail_if (gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp));
+ gst_buffer_unref (buf);
+}
+
+GST_END_TEST;
+
static Suite *
rtp_suite (void)
{
@@ -1947,6 +1970,8 @@ rtp_suite (void)
tcase_add_test (tc_chain,
test_ext_timestamp_wraparound_disordered_cannot_unwrap);
+ tcase_add_test (tc_chain, test_rtp_buffer_extlen_wraparound);
+
return s;
}