Add patches for CVE-2026-2923 and CVE-2026-3082
Resolves: RHEL-156118, RHEL-156189
This commit is contained in:
parent
bec699998a
commit
c4df609397
94
0001-dvbsuboverlay-Mark-parsed-byte-array-as-const.patch
Normal file
94
0001-dvbsuboverlay-Mark-parsed-byte-array-as-const.patch
Normal file
@ -0,0 +1,94 @@
|
||||
From e0eb8a3227b7cba80939aaeb953e5d1229f695a4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
|
||||
Date: Wed, 25 Feb 2026 17:22:52 +0200
|
||||
Subject: [PATCH 1/4] dvbsuboverlay: Mark parsed byte array as const
|
||||
|
||||
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10884>
|
||||
---
|
||||
.../gst/dvbsuboverlay/dvb-sub.c | 21 ++++++++++---------
|
||||
.../gst/dvbsuboverlay/dvb-sub.h | 2 +-
|
||||
2 files changed, 12 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c b/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
|
||||
index c3ed520513..d49828929c 100644
|
||||
--- a/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
|
||||
+++ b/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
|
||||
@@ -373,8 +373,8 @@ dvb_sub_init (void)
|
||||
}
|
||||
|
||||
static void
|
||||
-_dvb_sub_parse_page_segment (DvbSub * dvb_sub, guint16 page_id, guint8 * buf,
|
||||
- gint buf_size)
|
||||
+_dvb_sub_parse_page_segment (DvbSub * dvb_sub, guint16 page_id,
|
||||
+ const guint8 * buf, gint buf_size)
|
||||
{ /* FIXME: Use guint for buf_size here and in many other places? */
|
||||
DVBSubRegionDisplay *display;
|
||||
DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
|
||||
@@ -451,8 +451,8 @@ _dvb_sub_parse_page_segment (DvbSub * dvb_sub, guint16 page_id, guint8 * buf,
|
||||
}
|
||||
|
||||
static void
|
||||
-_dvb_sub_parse_region_segment (DvbSub * dvb_sub, guint16 page_id, guint8 * buf,
|
||||
- gint buf_size)
|
||||
+_dvb_sub_parse_region_segment (DvbSub * dvb_sub, guint16 page_id,
|
||||
+ const guint8 * buf, gint buf_size)
|
||||
{
|
||||
const guint8 *buf_end = buf + buf_size;
|
||||
guint8 region_id;
|
||||
@@ -574,8 +574,8 @@ _dvb_sub_parse_region_segment (DvbSub * dvb_sub, guint16 page_id, guint8 * buf,
|
||||
}
|
||||
|
||||
static void
|
||||
-_dvb_sub_parse_clut_segment (DvbSub * dvb_sub, guint16 page_id, guint8 * buf,
|
||||
- gint buf_size)
|
||||
+_dvb_sub_parse_clut_segment (DvbSub * dvb_sub, guint16 page_id,
|
||||
+ const guint8 * buf, gint buf_size)
|
||||
{
|
||||
const guint8 *buf_end = buf + buf_size;
|
||||
guint8 clut_id;
|
||||
@@ -1076,8 +1076,8 @@ _dvb_sub_parse_pixel_data_block (DvbSub * dvb_sub,
|
||||
}
|
||||
|
||||
static void
|
||||
-_dvb_sub_parse_object_segment (DvbSub * dvb_sub, guint16 page_id, guint8 * buf,
|
||||
- gint buf_size)
|
||||
+_dvb_sub_parse_object_segment (DvbSub * dvb_sub, guint16 page_id,
|
||||
+ const guint8 * buf, gint buf_size)
|
||||
{
|
||||
const guint8 *buf_end = buf + buf_size;
|
||||
guint object_id;
|
||||
@@ -1147,7 +1147,7 @@ _dvb_sub_parse_object_segment (DvbSub * dvb_sub, guint16 page_id, guint8 * buf,
|
||||
}
|
||||
|
||||
static gint
|
||||
-_dvb_sub_parse_display_definition_segment (DvbSub * dvb_sub, guint8 * buf,
|
||||
+_dvb_sub_parse_display_definition_segment (DvbSub * dvb_sub, const guint8 * buf,
|
||||
gint buf_size)
|
||||
{
|
||||
int dds_version, info_byte;
|
||||
@@ -1386,7 +1386,8 @@ dvb_sub_free (DvbSub * sub)
|
||||
* 0 or positive if data was handled. If positive, then amount of data consumed on success. FIXME: List the positive return values.
|
||||
*/
|
||||
gint
|
||||
-dvb_sub_feed_with_pts (DvbSub * dvb_sub, guint64 pts, guint8 * data, gint len)
|
||||
+dvb_sub_feed_with_pts (DvbSub * dvb_sub, guint64 pts, const guint8 * data,
|
||||
+ gint len)
|
||||
{
|
||||
unsigned int pos = 0;
|
||||
guint8 segment_type;
|
||||
diff --git a/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.h b/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.h
|
||||
index c986422a6a..0f78a171b1 100644
|
||||
--- a/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.h
|
||||
+++ b/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.h
|
||||
@@ -129,7 +129,7 @@ typedef struct {
|
||||
DvbSub *dvb_sub_new (void);
|
||||
void dvb_sub_free (DvbSub * sub);
|
||||
|
||||
-gint dvb_sub_feed_with_pts (DvbSub *dvb_sub, guint64 pts, guint8 *data, gint len);
|
||||
+gint dvb_sub_feed_with_pts (DvbSub *dvb_sub, guint64 pts, const guint8 *data, gint len);
|
||||
void dvb_sub_set_callbacks (DvbSub *dvb_sub, DvbSubCallbacks *callbacks, gpointer user_data);
|
||||
void dvb_subtitles_free (DVBSubtitles *sub);
|
||||
|
||||
--
|
||||
2.53.0
|
||||
|
||||
442
0002-dvbsuboverlay-Add-missing-bounds-checks-to-the-parse.patch
Normal file
442
0002-dvbsuboverlay-Add-missing-bounds-checks-to-the-parse.patch
Normal file
@ -0,0 +1,442 @@
|
||||
From 63fa69ec181f5defeb1193458b9322206ced4b85 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
|
||||
Date: Wed, 11 Feb 2026 20:45:12 +0200
|
||||
Subject: [PATCH 2/4] dvbsuboverlay: Add missing bounds checks to the parser
|
||||
everywhere
|
||||
|
||||
Fixes SA-2026-0007, ZDI-CAN-28838, CVE-2026-2923.
|
||||
|
||||
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4897
|
||||
|
||||
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10884>
|
||||
---
|
||||
.../gst/dvbsuboverlay/dvb-sub.c | 186 ++++++++++--------
|
||||
1 file changed, 109 insertions(+), 77 deletions(-)
|
||||
|
||||
diff --git a/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c b/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
|
||||
index d49828929c..9d7704b86d 100644
|
||||
--- a/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
|
||||
+++ b/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
|
||||
@@ -585,6 +585,9 @@ _dvb_sub_parse_clut_segment (DvbSub * dvb_sub, guint16 page_id,
|
||||
|
||||
GST_MEMDUMP ("DVB clut packet", buf, buf_size);
|
||||
|
||||
+ if (buf_size < 1)
|
||||
+ return;
|
||||
+
|
||||
clut_id = *buf++;
|
||||
buf += 1;
|
||||
|
||||
@@ -601,7 +604,7 @@ _dvb_sub_parse_clut_segment (DvbSub * dvb_sub, guint16 page_id,
|
||||
dvb_sub->clut_list = clut;
|
||||
}
|
||||
|
||||
- while (buf + 4 < buf_end) {
|
||||
+ while (buf + 2 < buf_end) {
|
||||
entry_id = *buf++;
|
||||
|
||||
depth = (*buf) & 0xe0;
|
||||
@@ -614,11 +617,15 @@ _dvb_sub_parse_clut_segment (DvbSub * dvb_sub, guint16 page_id,
|
||||
full_range = (*buf++) & 1;
|
||||
|
||||
if (full_range) {
|
||||
+ if (buf + 4 > buf_end)
|
||||
+ break;
|
||||
y = *buf++;
|
||||
cr = *buf++;
|
||||
cb = *buf++;
|
||||
alpha = *buf++;
|
||||
} else {
|
||||
+ if (buf + 2 > buf_end)
|
||||
+ break;
|
||||
y = buf[0] & 0xfc;
|
||||
cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
|
||||
cb = (buf[1] << 2) & 0xf0;
|
||||
@@ -633,11 +640,11 @@ _dvb_sub_parse_clut_segment (DvbSub * dvb_sub, guint16 page_id,
|
||||
GST_DEBUG ("CLUT DEFINITION: clut %d := (%d,%d,%d,%d)", entry_id, y, cb, cr,
|
||||
alpha);
|
||||
|
||||
- if (depth & 0x80)
|
||||
+ if ((depth & 0x80) && entry_id < 4)
|
||||
clut->clut4[entry_id] = AYUV (y, cb, cr, 255 - alpha);
|
||||
- if (depth & 0x40)
|
||||
+ if ((depth & 0x40) && entry_id < 16)
|
||||
clut->clut16[entry_id] = AYUV (y, cb, cr, 255 - alpha);
|
||||
- if (depth & 0x20)
|
||||
+ if ((depth & 0x20) && entry_id < 256)
|
||||
clut->clut256[entry_id] = AYUV (y, cb, cr, 255 - alpha);
|
||||
}
|
||||
}
|
||||
@@ -649,8 +656,6 @@ _dvb_sub_read_2bit_string (guint8 * destbuf, gint dbuf_len,
|
||||
const guint8 ** srcbuf, gint buf_size, guint8 non_mod, guint8 * map_table)
|
||||
{
|
||||
GstBitReader gb = GST_BIT_READER_INIT (*srcbuf, buf_size);
|
||||
- /* FIXME: Handle FALSE returns from gst_bit_reader_get_* calls? */
|
||||
-
|
||||
gboolean stop_parsing = FALSE;
|
||||
guint32 bits = 0;
|
||||
guint32 pixels_read = 0;
|
||||
@@ -661,23 +666,29 @@ _dvb_sub_read_2bit_string (guint8 * destbuf, gint dbuf_len,
|
||||
while (!stop_parsing && (gst_bit_reader_get_remaining (&gb) > 1)) {
|
||||
guint run_length = 0, clut_index = 0;
|
||||
|
||||
- bits = gst_bit_reader_get_bits_uint32_unchecked (&gb, 2);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &bits, 2))
|
||||
+ goto not_enough_data;
|
||||
|
||||
if (bits) { /* 2-bit_pixel-code */
|
||||
run_length = 1;
|
||||
clut_index = bits;
|
||||
} else { /* 2-bit_zero */
|
||||
- bits = gst_bit_reader_get_bits_uint32_unchecked (&gb, 1);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &bits, 1))
|
||||
+ goto not_enough_data;
|
||||
if (bits == 1) { /* switch_1 == '1' */
|
||||
- run_length = gst_bit_reader_get_bits_uint32_unchecked (&gb, 3);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &run_length, 3))
|
||||
+ goto not_enough_data;
|
||||
run_length += 3;
|
||||
- clut_index = gst_bit_reader_get_bits_uint32_unchecked (&gb, 2);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &clut_index, 2))
|
||||
+ goto not_enough_data;
|
||||
} else { /* switch_1 == '0' */
|
||||
- bits = gst_bit_reader_get_bits_uint32_unchecked (&gb, 1);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &bits, 1))
|
||||
+ goto not_enough_data;
|
||||
if (bits == 1) { /* switch_2 == '1' */
|
||||
run_length = 1; /* 1x pseudo-colour '00' */
|
||||
} else { /* switch_2 == '0' */
|
||||
- bits = gst_bit_reader_get_bits_uint32_unchecked (&gb, 2);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &bits, 2))
|
||||
+ goto not_enough_data;
|
||||
switch (bits) { /* switch_3 */
|
||||
case 0x0: /* end of 2-bit/pixel_code_string */
|
||||
stop_parsing = TRUE;
|
||||
@@ -686,14 +697,18 @@ _dvb_sub_read_2bit_string (guint8 * destbuf, gint dbuf_len,
|
||||
run_length = 2;
|
||||
break;
|
||||
case 0x2: /* the following 6 bits contain run length coded pixel data */
|
||||
- run_length = gst_bit_reader_get_bits_uint32_unchecked (&gb, 4);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &run_length, 4))
|
||||
+ goto not_enough_data;
|
||||
run_length += 12;
|
||||
- clut_index = gst_bit_reader_get_bits_uint32_unchecked (&gb, 2);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &clut_index, 2))
|
||||
+ goto not_enough_data;
|
||||
break;
|
||||
case 0x3: /* the following 10 bits contain run length coded pixel data */
|
||||
- run_length = gst_bit_reader_get_bits_uint32_unchecked (&gb, 8);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &run_length, 8))
|
||||
+ goto not_enough_data;
|
||||
run_length += 29;
|
||||
- clut_index = gst_bit_reader_get_bits_uint32_unchecked (&gb, 2);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &clut_index, 2))
|
||||
+ goto not_enough_data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -727,13 +742,18 @@ _dvb_sub_read_2bit_string (guint8 * destbuf, gint dbuf_len,
|
||||
pixels_read += run_length;
|
||||
}
|
||||
|
||||
- // FIXME: Test skip_to_byte instead of adding 7 bits, once everything else is working good
|
||||
- //gst_bit_reader_skip_to_byte (&gb);
|
||||
- *srcbuf += (gst_bit_reader_get_pos (&gb) + 7) >> 3;
|
||||
+ gst_bit_reader_skip_to_byte (&gb);
|
||||
+ *srcbuf = gb.data + gb.byte;
|
||||
|
||||
GST_TRACE ("PIXEL: returning, read %u pixels", pixels_read);
|
||||
// FIXME: Shouldn't need this variable if tracking things in the loop better
|
||||
return pixels_read;
|
||||
+
|
||||
+not_enough_data:
|
||||
+ GST_WARNING ("Not enough data");
|
||||
+ // Go to the end of the buffer so the caller stops parsing
|
||||
+ *srcbuf += buf_size;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
// FFMPEG-FIXME: The same code in ffmpeg is much more complex, it could use the same
|
||||
@@ -743,7 +763,6 @@ _dvb_sub_read_4bit_string (guint8 * destbuf, gint dbuf_len,
|
||||
const guint8 ** srcbuf, gint buf_size, guint8 non_mod, guint8 * map_table)
|
||||
{
|
||||
GstBitReader gb = GST_BIT_READER_INIT (*srcbuf, buf_size);
|
||||
- /* FIXME: Handle FALSE returns from gst_bit_reader_get_* calls? */
|
||||
gboolean stop_parsing = FALSE;
|
||||
guint32 bits = 0;
|
||||
guint32 pixels_read = 0;
|
||||
@@ -755,28 +774,35 @@ _dvb_sub_read_4bit_string (guint8 * destbuf, gint dbuf_len,
|
||||
while (!stop_parsing && (gst_bit_reader_get_remaining (&gb) > 3)) {
|
||||
guint run_length = 0, clut_index = 0;
|
||||
|
||||
- bits = gst_bit_reader_get_bits_uint32_unchecked (&gb, 4);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &bits, 4))
|
||||
+ goto not_enough_data;
|
||||
|
||||
if (bits) {
|
||||
run_length = 1;
|
||||
clut_index = bits;
|
||||
} else {
|
||||
- bits = gst_bit_reader_get_bits_uint32_unchecked (&gb, 1);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &bits, 1))
|
||||
+ goto not_enough_data;
|
||||
if (bits == 0) { /* switch_1 == '0' */
|
||||
- run_length = gst_bit_reader_get_bits_uint32_unchecked (&gb, 3);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &run_length, 3))
|
||||
+ goto not_enough_data;
|
||||
if (!run_length) {
|
||||
stop_parsing = TRUE;
|
||||
} else {
|
||||
run_length += 2;
|
||||
}
|
||||
} else { /* switch_1 == '1' */
|
||||
- bits = gst_bit_reader_get_bits_uint32_unchecked (&gb, 1);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &bits, 1))
|
||||
+ goto not_enough_data;
|
||||
if (bits == 0) { /* switch_2 == '0' */
|
||||
- run_length = gst_bit_reader_get_bits_uint32_unchecked (&gb, 2);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &run_length, 2))
|
||||
+ goto not_enough_data;
|
||||
run_length += 4;
|
||||
- clut_index = gst_bit_reader_get_bits_uint32_unchecked (&gb, 4);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &clut_index, 4))
|
||||
+ goto not_enough_data;
|
||||
} else { /* switch_2 == '1' */
|
||||
- bits = gst_bit_reader_get_bits_uint32_unchecked (&gb, 2);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &bits, 2))
|
||||
+ goto not_enough_data;
|
||||
switch (bits) {
|
||||
case 0x0: /* switch_3 == '00' */
|
||||
run_length = 1; /* 1 pixel of pseudo-color 0 */
|
||||
@@ -785,14 +811,18 @@ _dvb_sub_read_4bit_string (guint8 * destbuf, gint dbuf_len,
|
||||
run_length = 2; /* 2 pixels of pseudo-color 0 */
|
||||
break;
|
||||
case 0x2: /* switch_3 == '10' */
|
||||
- run_length = gst_bit_reader_get_bits_uint32_unchecked (&gb, 4);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &run_length, 4))
|
||||
+ goto not_enough_data;
|
||||
run_length += 9;
|
||||
- clut_index = gst_bit_reader_get_bits_uint32_unchecked (&gb, 4);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &clut_index, 4))
|
||||
+ goto not_enough_data;
|
||||
break;
|
||||
case 0x3: /* switch_3 == '11' */
|
||||
- run_length = gst_bit_reader_get_bits_uint32_unchecked (&gb, 8);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &run_length, 8))
|
||||
+ goto not_enough_data;
|
||||
run_length += 25;
|
||||
- clut_index = gst_bit_reader_get_bits_uint32_unchecked (&gb, 4);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &clut_index, 4))
|
||||
+ goto not_enough_data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -826,14 +856,19 @@ _dvb_sub_read_4bit_string (guint8 * destbuf, gint dbuf_len,
|
||||
pixels_read += run_length;
|
||||
}
|
||||
|
||||
- // FIXME: Test skip_to_byte instead of adding 7 bits, once everything else is working good
|
||||
- //gst_bit_reader_skip_to_byte (&gb);
|
||||
- *srcbuf += (gst_bit_reader_get_pos (&gb) + 7) >> 3;
|
||||
+ gst_bit_reader_skip_to_byte (&gb);
|
||||
+ *srcbuf = gb.data + gb.byte;
|
||||
|
||||
GST_LOG ("Returning with %u pixels read", pixels_read);
|
||||
|
||||
// FIXME: Shouldn't need this variable if tracking things in the loop better
|
||||
return pixels_read;
|
||||
+
|
||||
+not_enough_data:
|
||||
+ GST_WARNING ("Not enough data");
|
||||
+ // Go to the end of the buffer so the caller stops parsing
|
||||
+ *srcbuf += buf_size;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -841,8 +876,6 @@ _dvb_sub_read_8bit_string (guint8 * destbuf, gint dbuf_len,
|
||||
const guint8 ** srcbuf, gint buf_size, guint8 non_mod, guint8 * map_table)
|
||||
{
|
||||
GstBitReader gb = GST_BIT_READER_INIT (*srcbuf, buf_size);
|
||||
- /* FIXME: Handle FALSE returns from gst_bit_reader_get_* calls? */
|
||||
-
|
||||
gboolean stop_parsing = FALSE;
|
||||
guint32 bits = 0;
|
||||
guint32 pixels_read = 0;
|
||||
@@ -858,23 +891,29 @@ _dvb_sub_read_8bit_string (guint8 * destbuf, gint dbuf_len,
|
||||
/* Rephrased - it's better to work with bytes with default value '0' instead of reading from memory we don't own. */
|
||||
while (!stop_parsing && (gst_bit_reader_get_remaining (&gb) > 7)) {
|
||||
guint run_length = 0, clut_index = 0;
|
||||
- bits = gst_bit_reader_get_bits_uint32_unchecked (&gb, 8);
|
||||
+
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &bits, 8))
|
||||
+ goto not_enough_data;
|
||||
|
||||
if (bits) { /* 8-bit_pixel-code */
|
||||
run_length = 1;
|
||||
clut_index = bits;
|
||||
} else { /* 8-bit_zero */
|
||||
- bits = gst_bit_reader_get_bits_uint32_unchecked (&gb, 1);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &bits, 1))
|
||||
+ goto not_enough_data;
|
||||
if (bits == 0) { /* switch_1 == '0' */
|
||||
/* run_length_1-127 for pseudo-colour _entry) '0x00' */
|
||||
- run_length = gst_bit_reader_get_bits_uint32_unchecked (&gb, 7);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &run_length, 7))
|
||||
+ goto not_enough_data;
|
||||
if (run_length == 0) { /* end_of_string_signal */
|
||||
stop_parsing = TRUE;
|
||||
}
|
||||
} else { /* switch_1 == '1' */
|
||||
/* run_length_3-127 */
|
||||
- run_length = gst_bit_reader_get_bits_uint32_unchecked (&gb, 7);
|
||||
- clut_index = gst_bit_reader_get_bits_uint32_unchecked (&gb, 8);
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &run_length, 7))
|
||||
+ goto not_enough_data;
|
||||
+ if (!gst_bit_reader_get_bits_uint32 (&gb, &clut_index, 8))
|
||||
+ goto not_enough_data;
|
||||
|
||||
if (run_length < 3) {
|
||||
GST_WARNING ("runlength value was %u, but the spec requires it "
|
||||
@@ -912,10 +951,17 @@ _dvb_sub_read_8bit_string (guint8 * destbuf, gint dbuf_len,
|
||||
|
||||
GST_LOG ("Returning with %u pixels read", pixels_read);
|
||||
|
||||
- *srcbuf += (gst_bit_reader_get_pos (&gb) + 7) >> 3;
|
||||
+ gst_bit_reader_skip_to_byte (&gb);
|
||||
+ *srcbuf = gb.data + gb.byte;
|
||||
|
||||
// FIXME: Shouldn't need this variable if tracking things in the loop better
|
||||
return pixels_read;
|
||||
+
|
||||
+not_enough_data:
|
||||
+ GST_WARNING ("Not enough data");
|
||||
+ // Go to the end of the buffer so the caller stops parsing
|
||||
+ *srcbuf += buf_size;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -928,7 +974,6 @@ _dvb_sub_parse_pixel_data_block (DvbSub * dvb_sub,
|
||||
guint8 *pbuf;
|
||||
int x_pos, y_pos;
|
||||
int i;
|
||||
- gboolean dest_buf_filled = FALSE;
|
||||
|
||||
guint8 map2to4[] = { 0x0, 0x7, 0x8, 0xf };
|
||||
guint8 map2to8[] = { 0x00, 0x77, 0x88, 0xff };
|
||||
@@ -963,24 +1008,13 @@ _dvb_sub_parse_pixel_data_block (DvbSub * dvb_sub,
|
||||
|
||||
// FFMPEG-FIXME: ffmpeg doesn't check for equality and so can overflow destination buffer later on with bad input data
|
||||
// FFMPEG-FIXME: However that makes it warn on end_of_object_line and map tables as well, so we add the dest_buf_filled tracking
|
||||
- // FIXME: Removed x_pos checking here, because we don't want to turn dest_buf_filled to TRUE permanently in that case
|
||||
- // FIXME: We assume that region->width - x_pos as dbuf_len to read_nbit_string will take care of that case nicely;
|
||||
- // FIXME: That is, that read_nbit_string never scribbles anything if dbuf_len passed to it is zero due to this.
|
||||
- if (y_pos >= region->height) {
|
||||
- dest_buf_filled = TRUE;
|
||||
+ if (x_pos >= region->width || y_pos >= region->height) {
|
||||
+ GST_WARNING ("Invalid object location for data_type 0x%x!", *buf);
|
||||
+ return;
|
||||
}
|
||||
|
||||
switch (*buf++) {
|
||||
case 0x10:
|
||||
- if (dest_buf_filled) {
|
||||
- /* FIXME: Be more verbose */
|
||||
- GST_WARNING ("Invalid object location for data_type 0x%x!",
|
||||
- *(buf - 1));
|
||||
- GST_MEMDUMP ("Remaining data after invalid object location:", buf,
|
||||
- (guint) (buf_end - buf));
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
if (region->depth == 8)
|
||||
map_table = map2to8;
|
||||
else if (region->depth == 4)
|
||||
@@ -995,15 +1029,6 @@ _dvb_sub_parse_pixel_data_block (DvbSub * dvb_sub,
|
||||
region->width - x_pos, &buf, buf_end - buf, non_mod, map_table);
|
||||
break;
|
||||
case 0x11:
|
||||
- if (dest_buf_filled) {
|
||||
- /* FIXME: Be more verbose */
|
||||
- GST_WARNING ("Invalid object location for data_type 0x%x!",
|
||||
- *(buf - 1));
|
||||
- GST_MEMDUMP ("Remaining data after invalid object location:", buf,
|
||||
- buf_end - buf);
|
||||
- return; // FIXME: Perhaps tell read_nbit_string that dbuf_len is zero and let it walk the bytes regardless? (Same FIXME for 2bit and 8bit)
|
||||
- }
|
||||
-
|
||||
if (region->depth < 4) {
|
||||
GST_WARNING ("4-bit pixel string in %d-bit region!", region->depth);
|
||||
return;
|
||||
@@ -1024,15 +1049,6 @@ _dvb_sub_parse_pixel_data_block (DvbSub * dvb_sub,
|
||||
GST_DEBUG ("READ_4BIT_STRING finished: buf pointer now %p", buf);
|
||||
break;
|
||||
case 0x12:
|
||||
- if (dest_buf_filled) {
|
||||
- /* FIXME: Be more verbose */
|
||||
- GST_WARNING ("Invalid object location for data_type 0x%x!",
|
||||
- *(buf - 1));
|
||||
- GST_MEMDUMP ("Remaining data after invalid object location:",
|
||||
- buf, (guint) (buf_end - buf));
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
if (region->depth < 8) {
|
||||
GST_WARNING ("8-bit pixel string in %d-bit region!", region->depth);
|
||||
return;
|
||||
@@ -1046,19 +1062,29 @@ _dvb_sub_parse_pixel_data_block (DvbSub * dvb_sub,
|
||||
|
||||
case 0x20:
|
||||
GST_DEBUG ("handling map2to4 table data");
|
||||
- /* FIXME: I don't see any guards about buffer size here - buf++ happens with the switch, but
|
||||
- * FIXME: buffer is walked without length checks? Same deal in other map table cases */
|
||||
+ if (buf + 2 > buf_end) {
|
||||
+ GST_WARNING ("map2to4 table too short");
|
||||
+ return;
|
||||
+ }
|
||||
map2to4[0] = (*buf) >> 4;
|
||||
map2to4[1] = (*buf++) & 0xf;
|
||||
map2to4[2] = (*buf) >> 4;
|
||||
map2to4[3] = (*buf++) & 0xf;
|
||||
break;
|
||||
case 0x21:
|
||||
+ if (buf + 4 > buf_end) {
|
||||
+ GST_WARNING ("map2to8 table too short");
|
||||
+ return;
|
||||
+ }
|
||||
GST_DEBUG ("handling map2to8 table data");
|
||||
for (i = 0; i < 4; i++)
|
||||
map2to8[i] = *buf++;
|
||||
break;
|
||||
case 0x22:
|
||||
+ if (buf + 16 > buf_end) {
|
||||
+ GST_WARNING ("map4to8 table too short");
|
||||
+ return;
|
||||
+ }
|
||||
GST_DEBUG ("handling map4to8 table data");
|
||||
for (i = 0; i < 16; i++)
|
||||
map4to8[i] = *buf++;
|
||||
@@ -1085,6 +1111,9 @@ _dvb_sub_parse_object_segment (DvbSub * dvb_sub, guint16 page_id,
|
||||
|
||||
guint8 coding_method, non_modifying_color;
|
||||
|
||||
+ if (buf_size < 3)
|
||||
+ return;
|
||||
+
|
||||
object_id = GST_READ_UINT16_BE (buf);
|
||||
buf += 2;
|
||||
|
||||
@@ -1107,6 +1136,9 @@ _dvb_sub_parse_object_segment (DvbSub * dvb_sub, guint16 page_id,
|
||||
DVBSubObjectDisplay *display;
|
||||
guint16 top_field_len, bottom_field_len;
|
||||
|
||||
+ if (buf + 4 > buf_end)
|
||||
+ return;
|
||||
+
|
||||
top_field_len = GST_READ_UINT16_BE (buf);
|
||||
buf += 2;
|
||||
bottom_field_len = GST_READ_UINT16_BE (buf);
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
From ff291516bd4f51610b2914ebc72a7d238233bad2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
|
||||
Date: Thu, 12 Feb 2026 09:50:23 +0200
|
||||
Subject: [PATCH 3/4] dvbsuboverlay: Avoid integer overflows and unreasonably
|
||||
large displays/regions
|
||||
|
||||
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10884>
|
||||
---
|
||||
.../gst/dvbsuboverlay/dvb-sub.c | 23 +++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c b/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
|
||||
index 9d7704b86d..e44b8e2631 100644
|
||||
--- a/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
|
||||
+++ b/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
|
||||
@@ -483,6 +483,17 @@ _dvb_sub_parse_region_segment (DvbSub * dvb_sub, guint16 page_id,
|
||||
region->height = GST_READ_UINT16_BE (buf);
|
||||
buf += 2;
|
||||
|
||||
+ /* Avoid integer overflows and also clamp to a reasonable size of 8kx8k for
|
||||
+ * the region size. We allow 16kx16k display sizes. */
|
||||
+ if (region->width > 8192 || region->height > 8192) {
|
||||
+ GST_WARNING ("too large region of %ux%x", region->width, region->height);
|
||||
+ g_free (region->pbuf);
|
||||
+ region->pbuf = NULL;
|
||||
+ region->buf_size = 0;
|
||||
+ region->width = region->height = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (region->width * region->height != region->buf_size) { /* FIXME: Read closer from spec what happens when dimensions change */
|
||||
g_free (region->pbuf);
|
||||
|
||||
@@ -1196,6 +1207,18 @@ _dvb_sub_parse_display_definition_segment (DvbSub * dvb_sub, const guint8 * buf,
|
||||
display_height = GST_READ_UINT16_BE (buf) + 1;
|
||||
buf += 2;
|
||||
|
||||
+ /* Avoid integer overflows and also clamp to a reasonable size of 16kx16k */
|
||||
+ if (display_width > 16384 || display_height > 16384) {
|
||||
+ GST_WARNING ("too large display size of %ux%x", display_width,
|
||||
+ display_height);
|
||||
+ /* Reset to the initial values */
|
||||
+ dvb_sub->display_def.version = -1;
|
||||
+ dvb_sub->display_def.window_flag = 0;
|
||||
+ dvb_sub->display_def.display_width = 720;
|
||||
+ dvb_sub->display_def.display_height = 576;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
if ((display_width != dvb_sub->display_def.display_width)
|
||||
|| (display_height != dvb_sub->display_def.display_height)) {
|
||||
dvb_sub->display_def.display_width = display_width;
|
||||
--
|
||||
2.53.0
|
||||
|
||||
42
0004-libs-jpegparser-boundary-checks-before-copying-it.patch
Normal file
42
0004-libs-jpegparser-boundary-checks-before-copying-it.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From d569264a87740fc5fac702a90d8546ce5dfb15e4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?=
|
||||
<vjaquez@igalia.com>
|
||||
Date: Wed, 11 Feb 2026 22:07:49 +0100
|
||||
Subject: [PATCH 4/4] libs: jpegparser: boundary checks before copying it
|
||||
|
||||
READ_BYTES macro reads data from a byte reader and then copy it to a storage
|
||||
variable. This patch adds a validation that the length to read cannot be bigger
|
||||
than the storage size.
|
||||
|
||||
This macro right now is used only for storage variables of guint8 arrays.
|
||||
|
||||
We have validated in the specification (sections F.1.2.1.2 and F.1.2.2.1 in ITU
|
||||
T.81) that Huffman tables (both AC and DC) aren't bigger than 256.
|
||||
|
||||
Fixes SA-2026-0003, CVE-2026-3082, ZDI-CAN-28840.
|
||||
|
||||
Fixes: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4899>
|
||||
|
||||
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10885>
|
||||
---
|
||||
.../gst-plugins-bad/gst-libs/gst/codecparsers/gstjpegparser.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gstjpegparser.c b/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gstjpegparser.c
|
||||
index 0cb5d0b739..fd66f6cfdf 100644
|
||||
--- a/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gstjpegparser.c
|
||||
+++ b/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gstjpegparser.c
|
||||
@@ -77,6 +77,10 @@ ensure_debug_category (void)
|
||||
|
||||
#define READ_BYTES(reader, buf, length) G_STMT_START { \
|
||||
const guint8 *vals; \
|
||||
+ if (length > sizeof (buf)) { \
|
||||
+ GST_WARNING ("data size is bigger than its storage"); \
|
||||
+ goto failed; \
|
||||
+ } \
|
||||
if (!gst_byte_reader_get_data (reader, length, &vals)) { \
|
||||
GST_WARNING ("failed to read bytes, size:%d", length); \
|
||||
goto failed; \
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
|
||||
Name: gstreamer1-plugins-bad-free
|
||||
Version: 1.26.7
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
Summary: GStreamer streaming media framework "bad" plugins
|
||||
|
||||
License: LGPLv2+ and LGPLv2
|
||||
@ -40,7 +40,11 @@ Source: https://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugin
|
||||
%endif
|
||||
|
||||
# https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5622
|
||||
Patch0: openh264-add-license-file.patch
|
||||
Patch: openh264-add-license-file.patch
|
||||
Patch: 0001-dvbsuboverlay-Mark-parsed-byte-array-as-const.patch
|
||||
Patch: 0002-dvbsuboverlay-Add-missing-bounds-checks-to-the-parse.patch
|
||||
Patch: 0003-dvbsuboverlay-Avoid-integer-overflows-and-unreasonab.patch
|
||||
Patch: 0004-libs-jpegparser-boundary-checks-before-copying-it.patch
|
||||
|
||||
BuildRequires: meson >= 0.48.0
|
||||
BuildRequires: gcc-c++
|
||||
@ -868,6 +872,10 @@ EOF
|
||||
|
||||
|
||||
%changelog
|
||||
* Tue Mar 31 2026 Wim Taymans <wtaymans@redhat.com> - 1.26.7-2
|
||||
- Add patches for CVE-2026-2923 and CVE-2026-3082
|
||||
Resolves: RHEL-156118, RHEL-156189
|
||||
|
||||
* Tue Nov 04 2025 Wim Taymans <wtaymans@redhat.com> - 1.26.7-1
|
||||
- Update to 1.26.7
|
||||
Resolves: RHEL-126057
|
||||
|
||||
Loading…
Reference in New Issue
Block a user