CVE-2023-40474: Integer overflow leading to heap overwrite in MXF

This commit is contained in:
Wim Taymans 2024-01-17 15:21:26 +01:00 committed by root
parent 747bc41b90
commit dbf9d925c8
6 changed files with 285 additions and 1 deletions

View File

@ -0,0 +1 @@
fb0172c16d7e8ab7c7c6497f302d64a6e0ff974b gst-plugins-bad-free-1.22.1.tar.xz

View File

@ -0,0 +1,114 @@
From 27959a895db3949dee1c93cc05cb73465e2a1fbe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Thu, 10 Aug 2023 15:45:01 +0300
Subject: [PATCH 1/4] mxfdemux: Fix integer overflow causing out of bounds
writes when handling invalid uncompressed video
Check ahead of time when parsing the track information whether
width, height and bpp are valid and usable without overflows.
Fixes ZDI-CAN-21660, CVE-2023-40474
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2896
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5362>
---
subprojects/gst-plugins-bad/gst/mxf/mxfup.c | 51 +++++++++++++++++----
1 file changed, 43 insertions(+), 8 deletions(-)
diff --git a/subprojects/gst-plugins-bad/gst/mxf/mxfup.c b/subprojects/gst-plugins-bad/gst/mxf/mxfup.c
index d8b6664dab..ba86255f20 100644
--- a/subprojects/gst-plugins-bad/gst/mxf/mxfup.c
+++ b/subprojects/gst-plugins-bad/gst/mxf/mxfup.c
@@ -134,6 +134,8 @@ mxf_up_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
gpointer mapping_data, GstBuffer ** outbuf)
{
MXFUPMappingData *data = mapping_data;
+ gsize expected_in_stride = 0, out_stride = 0;
+ gsize expected_in_size = 0, out_size = 0;
/* SMPTE 384M 7.1 */
if (key->u[12] != 0x15 || (key->u[14] != 0x01 && key->u[14] != 0x02
@@ -162,22 +164,25 @@ mxf_up_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
}
}
- if (gst_buffer_get_size (buffer) != data->bpp * data->width * data->height) {
+ // Checked for overflows when parsing the descriptor
+ expected_in_stride = data->bpp * data->width;
+ out_stride = GST_ROUND_UP_4 (expected_in_stride);
+ expected_in_size = expected_in_stride * data->height;
+ out_size = out_stride * data->height;
+
+ if (gst_buffer_get_size (buffer) != expected_in_size) {
GST_ERROR ("Invalid buffer size");
gst_buffer_unref (buffer);
return GST_FLOW_ERROR;
}
- if (data->bpp != 4
- || GST_ROUND_UP_4 (data->width * data->bpp) != data->width * data->bpp) {
+ if (data->bpp != 4 || out_stride != expected_in_stride) {
guint y;
GstBuffer *ret;
GstMapInfo inmap, outmap;
guint8 *indata, *outdata;
- ret =
- gst_buffer_new_and_alloc (GST_ROUND_UP_4 (data->width * data->bpp) *
- data->height);
+ ret = gst_buffer_new_and_alloc (out_size);
gst_buffer_map (buffer, &inmap, GST_MAP_READ);
gst_buffer_map (ret, &outmap, GST_MAP_WRITE);
indata = inmap.data;
@@ -185,8 +190,8 @@ mxf_up_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
for (y = 0; y < data->height; y++) {
memcpy (outdata, indata, data->width * data->bpp);
- outdata += GST_ROUND_UP_4 (data->width * data->bpp);
- indata += data->width * data->bpp;
+ outdata += out_stride;
+ indata += expected_in_stride;
}
gst_buffer_unmap (buffer, &inmap);
@@ -394,6 +399,36 @@ mxf_up_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
return NULL;
}
+ if (caps) {
+ MXFUPMappingData *data = *mapping_data;
+ gsize expected_in_stride = 0, out_stride = 0;
+ gsize expected_in_size = 0, out_size = 0;
+
+ // Do some checking of the parameters to see if they're valid and
+ // we can actually work with them.
+ if (data->image_start_offset > data->image_end_offset) {
+ GST_WARNING ("Invalid image start/end offset");
+ g_free (data);
+ *mapping_data = NULL;
+ gst_clear_caps (&caps);
+
+ return NULL;
+ }
+
+ if (!g_size_checked_mul (&expected_in_stride, data->bpp, data->width) ||
+ (out_stride = GST_ROUND_UP_4 (expected_in_stride)) < expected_in_stride
+ || !g_size_checked_mul (&expected_in_size, expected_in_stride,
+ data->height)
+ || !g_size_checked_mul (&out_size, out_stride, data->height)) {
+ GST_ERROR ("Invalid resolution or bit depth");
+ g_free (data);
+ *mapping_data = NULL;
+ gst_clear_caps (&caps);
+
+ return NULL;
+ }
+ }
+
return caps;
}
--
2.43.0

View File

@ -0,0 +1,45 @@
From cfccf4b36197359271c95f20bfcda854f6c812cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Thu, 10 Aug 2023 15:47:03 +0300
Subject: [PATCH 2/4] mxfdemux: Check number of channels for AES3 audio
Only up to 8 channels are allowed and using a higher number would cause
integer overflows when copying the data, and lead to out of bound
writes.
Also check that each buffer is at least 4 bytes long to avoid another
overflow.
Fixes ZDI-CAN-21661, CVE-2023-40475
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2897
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5362>
---
subprojects/gst-plugins-bad/gst/mxf/mxfd10.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/subprojects/gst-plugins-bad/gst/mxf/mxfd10.c b/subprojects/gst-plugins-bad/gst/mxf/mxfd10.c
index 66c071372a..060d5a02de 100644
--- a/subprojects/gst-plugins-bad/gst/mxf/mxfd10.c
+++ b/subprojects/gst-plugins-bad/gst/mxf/mxfd10.c
@@ -119,7 +119,7 @@ mxf_d10_sound_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
gst_buffer_map (buffer, &map, GST_MAP_READ);
/* Now transform raw AES3 into raw audio, see SMPTE 331M */
- if ((map.size - 4) % 32 != 0) {
+ if (map.size < 4 || (map.size - 4) % 32 != 0) {
gst_buffer_unmap (buffer, &map);
GST_ERROR ("Invalid D10 sound essence buffer size");
return GST_FLOW_ERROR;
@@ -219,6 +219,7 @@ mxf_d10_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
GstAudioFormat audio_format;
if (s->channel_count == 0 ||
+ s->channel_count > 8 ||
s->quantization_bits == 0 ||
s->audio_sampling_rate.n == 0 || s->audio_sampling_rate.d == 0) {
GST_ERROR ("Invalid descriptor");
--
2.43.0

View File

@ -0,0 +1,66 @@
From 0ded5a6d028ad40604093690c44eb022ef793531 Mon Sep 17 00:00:00 2001
From: Seungha Yang <seungha@centricular.com>
Date: Thu, 23 Nov 2023 20:24:42 +0900
Subject: [PATCH 3/4] av1parser: Fix array sizes in scalability structure
Since the AV1 specification is not explicitly mentioning about
the array size bounds, array sizes in scalability structure
should be defined as possible maximum sizes that can have.
Also, this commit removes GST_AV1_MAX_SPATIAL_LAYERS define from
public header which is API break but the define is misleading
and this patch is introducing ABI break already
ZDI-CAN-22300
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5824>
---
.../gst-libs/gst/codecparsers/gstav1parser.h | 11 +++++------
.../gst-plugins-bad/gst/videoparsers/gstav1parse.c | 2 +-
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gstav1parser.h b/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gstav1parser.h
index a5f1c761f6..7d2ec69fb5 100644
--- a/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gstav1parser.h
+++ b/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gstav1parser.h
@@ -71,9 +71,8 @@ G_BEGIN_DECLS
#define GST_AV1_MAX_TILE_COUNT 512
#define GST_AV1_MAX_OPERATING_POINTS \
(GST_AV1_MAX_NUM_TEMPORAL_LAYERS * GST_AV1_MAX_NUM_SPATIAL_LAYERS)
-#define GST_AV1_MAX_SPATIAL_LAYERS 2 /* correct? */
-#define GST_AV1_MAX_TEMPORAL_GROUP_SIZE 8 /* correct? */
-#define GST_AV1_MAX_TEMPORAL_GROUP_REFERENCES 8 /* correct? */
+#define GST_AV1_MAX_TEMPORAL_GROUP_SIZE 255
+#define GST_AV1_MAX_TEMPORAL_GROUP_REFERENCES 7
#define GST_AV1_MAX_NUM_Y_POINTS 16
#define GST_AV1_MAX_NUM_CB_POINTS 16
#define GST_AV1_MAX_NUM_CR_POINTS 16
@@ -968,9 +967,9 @@ struct _GstAV1MetadataScalability {
gboolean spatial_layer_dimensions_present_flag;
gboolean spatial_layer_description_present_flag;
gboolean temporal_group_description_present_flag;
- guint16 spatial_layer_max_width[GST_AV1_MAX_SPATIAL_LAYERS];
- guint16 spatial_layer_max_height[GST_AV1_MAX_SPATIAL_LAYERS];
- guint8 spatial_layer_ref_id[GST_AV1_MAX_SPATIAL_LAYERS];
+ guint16 spatial_layer_max_width[GST_AV1_MAX_NUM_SPATIAL_LAYERS];
+ guint16 spatial_layer_max_height[GST_AV1_MAX_NUM_SPATIAL_LAYERS];
+ guint8 spatial_layer_ref_id[GST_AV1_MAX_NUM_SPATIAL_LAYERS];
guint8 temporal_group_size;
guint8 temporal_group_temporal_id[GST_AV1_MAX_TEMPORAL_GROUP_SIZE];
diff --git a/subprojects/gst-plugins-bad/gst/videoparsers/gstav1parse.c b/subprojects/gst-plugins-bad/gst/videoparsers/gstav1parse.c
index 923bc5d70a..9eaa1f47d9 100644
--- a/subprojects/gst-plugins-bad/gst/videoparsers/gstav1parse.c
+++ b/subprojects/gst-plugins-bad/gst/videoparsers/gstav1parse.c
@@ -1271,7 +1271,7 @@ gst_av1_parse_handle_sequence_obu (GstAV1Parse * self, GstAV1OBU * obu)
}
val = (self->parser->state.operating_point_idc >> 8) & 0x0f;
- for (i = 0; i < (1 << GST_AV1_MAX_SPATIAL_LAYERS); i++) {
+ for (i = 0; i < GST_AV1_MAX_NUM_SPATIAL_LAYERS; i++) {
if (val & (1 << i))
self->highest_spatial_id = i;
}
--
2.43.0

View File

@ -0,0 +1,42 @@
From 6780451f22c87e926ebf60fe55e1a9e10517f6d1 Mon Sep 17 00:00:00 2001
From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Date: Wed, 9 Aug 2023 12:49:19 -0400
Subject: [PATCH 4/4] h265parser: Fix possible overflow using
max_sub_layers_minus1
This fixes a possible overflow that can be triggered by an invalid value of
max_sub_layers_minus1 being set in the bitstream. The bitstream uses 3 bits,
but the allowed range is 0 to 6 only.
Fixes ZDI-CAN-21768, CVE-2023-40476
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2895
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5364>
---
.../gst-plugins-bad/gst-libs/gst/codecparsers/gsth265parser.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gsth265parser.c b/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gsth265parser.c
index fe775a86cd..44b723737a 100644
--- a/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gsth265parser.c
+++ b/subprojects/gst-plugins-bad/gst-libs/gst/codecparsers/gsth265parser.c
@@ -1845,6 +1845,7 @@ gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
READ_UINT8 (&nr, vps->max_layers_minus1, 6);
READ_UINT8 (&nr, vps->max_sub_layers_minus1, 3);
+ CHECK_ALLOWED (vps->max_sub_layers_minus1, 0, 6);
READ_UINT8 (&nr, vps->temporal_id_nesting_flag, 1);
/* skip reserved_0xffff_16bits */
@@ -2015,6 +2016,7 @@ gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
READ_UINT8 (&nr, sps->vps_id, 4);
READ_UINT8 (&nr, sps->max_sub_layers_minus1, 3);
+ CHECK_ALLOWED (sps->max_sub_layers_minus1, 0, 6);
READ_UINT8 (&nr, sps->temporal_id_nesting_flag, 1);
if (!gst_h265_parse_profile_tier_level (&sps->profile_tier_level, &nr,
--
2.43.0

View File

@ -14,7 +14,7 @@
Name: gstreamer1-plugins-bad-free
Version: 1.22.1
Release: 3%{?gitcommit:.git%{shortcommit}}%{?dist}
Release: 4%{?gitcommit:.git%{shortcommit}}%{?dist}
Summary: GStreamer streaming media framework "bad" plugins
License: LGPLv2+ and LGPLv2
@ -33,6 +33,11 @@ Source1: gst-p-bad-cleanup.sh
Patch0: 0001-mxfdemux-Store-GstMXFDemuxEssenceTrack-in-their-own-.patch
Patch1: 0002-codecparsers-av1-Clip-max-tile-rows-and-cols-values.patch
Patch2: 0001-mxfdemux-Fix-integer-overflow-causing-out-of-bounds-.patch
Patch3: 0002-mxfdemux-Check-number-of-channels-for-AES3-audio.patch
Patch4: 0003-av1parser-Fix-array-sizes-in-scalability-structure.patch
Patch5: 0004-h265parser-Fix-possible-overflow-using-max_sub_layer.patch
BuildRequires: meson >= 0.48.0
BuildRequires: gcc-c++
@ -236,6 +241,10 @@ aren't tested well enough, or the code is not of good enough quality.
%setup -q -n gst-plugins-bad-%{version}
%patch0 -p3
%patch1 -p3
%patch2 -p3
%patch3 -p3
%patch4 -p3
%patch5 -p3
%build
%meson \
@ -670,6 +679,13 @@ rm $RPM_BUILD_ROOT%{_bindir}/playout
%changelog
* Wed Jan 17 2024 Wim Taymans <wtaymans@redhat.com> - 1.22.1-4
- CVE-2023-40474: Integer overflow leading to heap overwrite in MXF
- CVE-2023-40475: Integer overflow leading to heap overwrite in MXF
- CVE-2023-40476: Integer overflow in H.265 video parser
- ZDI-CAN-22300: buffer overflow vulnerability
- Resolves: RHEL-19501, RHEL-19505, RHEL-19506, RHEL-20201
* Thu Jan 11 2024 Wim Taymans <wtaymans@redhat.com> - 1.22.1-3
- Bump version
- Resolves: RHEL-16795, RHEL-16788