import UBI gstreamer1-plugins-bad-free-1.24.11-3.el10_1

This commit is contained in:
AlmaLinux RelEng Bot 2026-03-31 11:56:58 -04:00
parent f0d9f30e84
commit e99d5c8ab3
5 changed files with 643 additions and 2 deletions

View File

@ -0,0 +1,94 @@
From f2d874be5e3e6edab6167ba8213ee5abb10acfcb 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 6a0b322c03..e7328033ac 100644
--- a/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
+++ b/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
@@ -361,8 +361,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;
@@ -439,8 +439,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;
@@ -562,8 +562,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;
@@ -1064,8 +1064,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;
@@ -1135,7 +1135,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;
@@ -1374,7 +1374,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

View File

@ -0,0 +1,442 @@
From e3e08ac617fd387571d242118580205417ea6cbb 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 e7328033ac..41dd0ba34b 100644
--- a/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
+++ b/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
@@ -573,6 +573,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;
@@ -589,7 +592,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;
@@ -602,11 +605,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;
@@ -621,11 +628,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);
}
}
@@ -637,8 +644,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;
@@ -649,23 +654,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;
@@ -674,14 +685,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;
}
}
@@ -715,13 +730,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
@@ -731,7 +751,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;
@@ -743,28 +762,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 */
@@ -773,14 +799,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;
}
}
@@ -814,14 +844,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
@@ -829,8 +864,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;
@@ -846,23 +879,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 "
@@ -900,10 +939,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
@@ -916,7 +962,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 };
@@ -951,24 +996,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)
@@ -983,15 +1017,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;
@@ -1012,15 +1037,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;
@@ -1034,19 +1050,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++;
@@ -1073,6 +1099,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;
@@ -1095,6 +1124,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

View File

@ -0,0 +1,55 @@
From 05502643bdd8bb91c691f28d67d3eda11e322349 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 41dd0ba34b..8a3b46c56c 100644
--- a/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
+++ b/subprojects/gst-plugins-bad/gst/dvbsuboverlay/dvb-sub.c
@@ -471,6 +471,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);
@@ -1184,6 +1195,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

View File

@ -0,0 +1,42 @@
From 9fdae1520028e20520d8c0fbd85b8631d6ce94f7 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 64110763f2..86125b3747 100644
--- a/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gstjpegparser.c
+++ b/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gstjpegparser.c
@@ -79,6 +79,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

View File

@ -15,7 +15,7 @@
Name: gstreamer1-plugins-bad-free
Version: 1.24.11
Release: 2%{?dist}
Release: 3%{?dist}
Summary: GStreamer streaming media framework "bad" plugins
License: LGPLv2+ and LGPLv2
@ -37,6 +37,10 @@ Patch: openh264-add-license-file.patch
# https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8884
Patch: fix-CVE-2025-3887.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++
@ -818,9 +822,13 @@ EOF
%changelog
* Mon May 30 2026 Wim Taymans <wtaymans@redhat.com> - 1.24.11-3
- fix for CVE-2026-2923, CVE-2026-3082
Resolves: RHEL-156111, RHEL-156158
* Mon May 26 2025 Wim Taymans <wtaymans@redhat.com> - 1.24.11-2
- fix for CVE-2025-3887
Resolves: RHEL-93044
Resolves: RHEL-93045
* Tue Jan 14 2025 Wim Taymans <wtaymans@redhat.com> - 1.24.11-1
- Update to 1.24.11