diff --git a/gst/rtp/gstrtph263depay.c b/gst/rtp/gstrtph263depay.c index a63b0b13a3..41b0fc4b00 100644 --- a/gst/rtp/gstrtph263depay.c +++ b/gst/rtp/gstrtph263depay.c @@ -234,6 +234,9 @@ gst_rtp_h263_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf) M = gst_rtp_buffer_get_marker (&rtp); + if (payload_len < 1) + goto too_small; + /* Let's see what mode we are using */ F = (payload[0] & 0x80) == 0x80; P = (payload[0] & 0x40) == 0x40; @@ -255,6 +258,8 @@ gst_rtp_h263_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf) * |F|P|SBIT |EBIT | SRC |I|U|S|A|R |DBQ| TRB | TR | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ + if (payload_len <= header_len) + goto too_small; I = (payload[1] & 0x10) == 0x10; } else { if (P == 0) { @@ -271,6 +276,8 @@ gst_rtp_h263_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf) * |I|U|S|A| HMV1 | VMV1 | HMV2 | VMV2 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ + if (payload_len <= header_len) + goto too_small; I = (payload[4] & 0x80) == 0x80; } else { /* F == 1 and P == 1 @@ -288,6 +295,8 @@ gst_rtp_h263_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf) * | RR |DBQ| TRB | TR | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ + if (payload_len <= header_len) + goto too_small; I = (payload[4] & 0x80) == 0x80; } } @@ -389,6 +398,14 @@ skip: gst_rtp_buffer_unmap (&rtp); return NULL; + +too_small: + { + GST_ELEMENT_WARNING (rtph263depay, STREAM, DECODE, + ("Packet payload was too small"), (NULL)); + gst_rtp_buffer_unmap (&rtp); + return NULL; + } } static GstStateChangeReturn diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index a64f285ab1..29ad9bc067 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -215,7 +215,9 @@ check_replaygain = endif if USE_PLUGIN_RTP -check_rtp = elements/rtp-payloading +check_rtp = \ + elements/rtp-payloading \ + elements/rtph263 else check_rtp = endif @@ -522,6 +524,9 @@ elements_rtpbin_buffer_list_LDADD = $(GST_PLUGINS_BASE_LIBS) \ $(GST_BASE_LIBS) $(GST_LIBS) $(GST_CHECK_LIBS) $(LDADD) elements_rtpbin_buffer_list_SOURCES = elements/rtpbin_buffer_list.c +elements_rtph263_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(AM_CFLAGS) +elements_rtph263_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstrtp-$(GST_API_VERSION) $(GST_BASE_LIBS) $(LDADD) + elements_rtpmux_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(AM_CFLAGS) elements_rtpmux_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstrtp-$(GST_API_VERSION) $(GST_BASE_LIBS) $(LDADD) diff --git a/tests/check/elements/rtph263.c b/tests/check/elements/rtph263.c new file mode 100644 index 0000000000..2c77ece33b --- /dev/null +++ b/tests/check/elements/rtph263.c @@ -0,0 +1,116 @@ +/* GStreamer + * + * Copyright (C) 2015 Pexip AS + * @author Stian Selnes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#define RTP_H263_CAPS_STR(p) \ + "application/x-rtp,media=video,encoding-name=H263,clock-rate=90000," \ + "payload=" G_STRINGIFY(p) + +static GstBuffer * +create_rtp_buffer (guint8 * data, gsize size, guint ts, gint seqnum) +{ + GstBuffer *buf = gst_rtp_buffer_new_copy_data (data, size); + GstRTPBuffer rtp = GST_RTP_BUFFER_INIT; + + GST_BUFFER_PTS (buf) = (ts) * (GST_SECOND / 30); + + gst_rtp_buffer_map (buf, GST_MAP_WRITE, &rtp); + gst_rtp_buffer_set_seq (&rtp, seqnum); + gst_rtp_buffer_unmap (&rtp); + + return buf; +} + +GST_START_TEST (test_h263depay_start_packet_too_small_mode_a) +{ + GstHarness *h = gst_harness_new ("rtph263depay"); + guint8 packet[] = { + 0x80, 0xa2, 0x17, 0x62, 0x57, 0xbb, 0x48, 0x98, 0x4a, 0x59, 0xe8, 0xdc, + 0x00, 0x00, 0x80, 0x00 + }; + + gst_harness_set_src_caps_str (h, RTP_H263_CAPS_STR (34)); + fail_unless_equals_int (GST_FLOW_OK, + gst_harness_push (h, create_rtp_buffer (packet, sizeof (packet), 0, 0))); + + /* Packet should be dropped and depayloader not crash */ + fail_unless_equals_int (0, gst_harness_buffers_received (h)); + + gst_harness_teardown (h); +} +GST_END_TEST; + +GST_START_TEST (test_h263depay_start_packet_too_small_mode_b) +{ + GstHarness *h = gst_harness_new ("rtph263depay"); + guint8 packet[] = { + 0x80, 0xa2, 0x17, 0x62, 0x57, 0xbb, 0x48, 0x98, 0x4a, 0x59, 0xe8, 0xdc, + 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + gst_harness_set_src_caps_str (h, RTP_H263_CAPS_STR (34)); + fail_unless_equals_int (GST_FLOW_OK, + gst_harness_push (h, create_rtp_buffer (packet, sizeof (packet), 0, 0))); + + /* Packet should be dropped and depayloader not crash */ + fail_unless_equals_int (0, gst_harness_buffers_received (h)); + + gst_harness_teardown (h); +} +GST_END_TEST; + +GST_START_TEST (test_h263depay_start_packet_too_small_mode_c) +{ + GstHarness *h = gst_harness_new ("rtph263depay"); + guint8 packet[] = { + 0x80, 0xa2, 0x17, 0x62, 0x57, 0xbb, 0x48, 0x98, 0x4a, 0x59, 0xe8, 0xdc, + 0xc0, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + gst_harness_set_src_caps_str (h, RTP_H263_CAPS_STR (34)); + fail_unless_equals_int (GST_FLOW_OK, + gst_harness_push (h, create_rtp_buffer (packet, sizeof (packet), 0, 0))); + + /* Packet should be dropped and depayloader not crash */ + fail_unless_equals_int (0, gst_harness_buffers_received (h)); + + gst_harness_teardown (h); +} +GST_END_TEST; + +static Suite * +rtph263_suite (void) +{ + Suite *s = suite_create ("rtph263"); + TCase *tc_chain; + + suite_add_tcase (s, (tc_chain = tcase_create ("h263depay"))); + tcase_add_test (tc_chain, test_h263depay_start_packet_too_small_mode_a); + tcase_add_test (tc_chain, test_h263depay_start_packet_too_small_mode_b); + tcase_add_test (tc_chain, test_h263depay_start_packet_too_small_mode_c); + + return s; +} + +GST_CHECK_MAIN (rtph263);