diff options
4 files changed, 274 insertions, 0 deletions
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2025-47183-001.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2025-47183-001.patch new file mode 100644 index 0000000000..bd25c5f1ed --- /dev/null +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2025-47183-001.patch | |||
@@ -0,0 +1,151 @@ | |||
1 | From c4d0f4bbd9a8e97f119a4528b9f4662a6b80922c Mon Sep 17 00:00:00 2001 | ||
2 | From: Jochen Henneberg <jochen@centricular.com> | ||
3 | Date: Tue, 10 Dec 2024 21:34:48 +0100 | ||
4 | Subject: [PATCH] qtdemux: Use mvhd transform matrix and support for flipping | ||
5 | |||
6 | The mvhd matrix is now combined with the tkhd matrix. The combined | ||
7 | matrix is then checked if it matches one of the standard values for | ||
8 | GST_TAG_IMAGE_ORIENTATION. | ||
9 | This check now includes matrices with flipping. | ||
10 | |||
11 | Fixes #4064 | ||
12 | |||
13 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8127> | ||
14 | |||
15 | CVE: CVE-2025-47183 | ||
16 | Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/c4d0f4bbd9a8e97f119a4528b9f4662a6b80922c] | ||
17 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
18 | --- | ||
19 | gst/isomp4/qtdemux.c | 53 ++++++++++++++++++++++++++++++++++++++++---- | ||
20 | 1 file changed, 49 insertions(+), 4 deletions(-) | ||
21 | |||
22 | diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c | ||
23 | index 10b21a6..e708ef4 100644 | ||
24 | --- a/gst/isomp4/qtdemux.c | ||
25 | +++ b/gst/isomp4/qtdemux.c | ||
26 | @@ -10861,6 +10861,23 @@ qtdemux_parse_transformation_matrix (GstQTDemux * qtdemux, | ||
27 | return TRUE; | ||
28 | } | ||
29 | |||
30 | +static void | ||
31 | +qtdemux_mul_transformation_matrix (GstQTDemux * qtdemux, | ||
32 | + guint32 * a, guint32 * b, guint32 * c) | ||
33 | +{ | ||
34 | +#define QTMUL_MATRIX(_a,_b) (((_a) == 0 || (_b) == 0) ? 0 : \ | ||
35 | + ((_a) == (_b) ? 1 : -1)) | ||
36 | +#define QTADD_MATRIX(_a,_b) ((_a) + (_b) > 0 ? (1U << 16) : \ | ||
37 | + ((_a) + (_b) < 0) ? (G_MAXUINT16 << 16) : 0u) | ||
38 | + | ||
39 | + c[2] = c[5] = c[6] = c[7] = 0; | ||
40 | + c[0] = QTADD_MATRIX (QTMUL_MATRIX (a[0], b[0]), QTMUL_MATRIX (a[1], b[3])); | ||
41 | + c[1] = QTADD_MATRIX (QTMUL_MATRIX (a[0], b[1]), QTMUL_MATRIX (a[1], b[4])); | ||
42 | + c[3] = QTADD_MATRIX (QTMUL_MATRIX (a[3], b[0]), QTMUL_MATRIX (a[4], b[3])); | ||
43 | + c[4] = QTADD_MATRIX (QTMUL_MATRIX (a[3], b[1]), QTMUL_MATRIX (a[4], b[4])); | ||
44 | + c[8] = a[8]; | ||
45 | +} | ||
46 | + | ||
47 | static void | ||
48 | qtdemux_inspect_transformation_matrix (GstQTDemux * qtdemux, | ||
49 | QtDemuxStream * stream, guint32 * matrix, GstTagList ** taglist) | ||
50 | @@ -10889,6 +10906,14 @@ qtdemux_inspect_transformation_matrix (GstQTDemux * qtdemux, | ||
51 | rotation_tag = "rotate-180"; | ||
52 | } else if (QTCHECK_MATRIX (matrix, 0, G_MAXUINT16, 1, 0)) { | ||
53 | rotation_tag = "rotate-270"; | ||
54 | + } else if (QTCHECK_MATRIX (matrix, G_MAXUINT16, 0, 0, 1)) { | ||
55 | + rotation_tag = "flip-rotate-0"; | ||
56 | + } else if (QTCHECK_MATRIX (matrix, 0, G_MAXUINT16, 1, 0)) { | ||
57 | + rotation_tag = "flip-rotate-90"; | ||
58 | + } else if (QTCHECK_MATRIX (matrix, 1, 0, 0, G_MAXUINT16)) { | ||
59 | + rotation_tag = "flip-rotate-180"; | ||
60 | + } else if (QTCHECK_MATRIX (matrix, 0, 1, 1, 0)) { | ||
61 | + rotation_tag = "flip-rotate-270"; | ||
62 | } else { | ||
63 | GST_FIXME_OBJECT (qtdemux, "Unhandled transformation matrix values"); | ||
64 | } | ||
65 | @@ -11175,7 +11200,7 @@ qtdemux_parse_stereo_svmi_atom (GstQTDemux * qtdemux, QtDemuxStream * stream, | ||
66 | * traks that do not decode to something (like strm traks) will not have a pad. | ||
67 | */ | ||
68 | static gboolean | ||
69 | -qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak) | ||
70 | +qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak, guint32 * mvhd_matrix) | ||
71 | { | ||
72 | GstByteReader tkhd; | ||
73 | int offset; | ||
74 | @@ -11347,15 +11372,21 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak) | ||
75 | |||
76 | /* parse rest of tkhd */ | ||
77 | if (stream->subtype == FOURCC_vide) { | ||
78 | + guint32 tkhd_matrix[9]; | ||
79 | guint32 matrix[9]; | ||
80 | |||
81 | /* version 1 uses some 64-bit ints */ | ||
82 | if (!gst_byte_reader_skip (&tkhd, 20 + value_size)) | ||
83 | goto corrupt_file; | ||
84 | |||
85 | - if (!qtdemux_parse_transformation_matrix (qtdemux, &tkhd, matrix, "tkhd")) | ||
86 | + if (!qtdemux_parse_transformation_matrix (qtdemux, &tkhd, tkhd_matrix, | ||
87 | + "tkhd")) | ||
88 | goto corrupt_file; | ||
89 | |||
90 | + /* calculate the final matrix from the mvhd_matrix and the tkhd matrix */ | ||
91 | + qtdemux_mul_transformation_matrix (qtdemux, mvhd_matrix, tkhd_matrix, | ||
92 | + matrix); | ||
93 | + | ||
94 | if (!gst_byte_reader_get_uint32_be (&tkhd, &w) | ||
95 | || !gst_byte_reader_get_uint32_be (&tkhd, &h)) | ||
96 | goto corrupt_file; | ||
97 | @@ -14198,11 +14229,14 @@ qtdemux_parse_tree (GstQTDemux * qtdemux) | ||
98 | guint64 creation_time; | ||
99 | GstDateTime *datetime = NULL; | ||
100 | gint version; | ||
101 | + GstByteReader mvhd_reader; | ||
102 | + guint32 matrix[9]; | ||
103 | |||
104 | /* make sure we have a usable taglist */ | ||
105 | qtdemux->tag_list = gst_tag_list_make_writable (qtdemux->tag_list); | ||
106 | |||
107 | - mvhd = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_mvhd); | ||
108 | + mvhd = qtdemux_tree_get_child_by_type_full (qtdemux->moov_node, | ||
109 | + FOURCC_mvhd, &mvhd_reader); | ||
110 | if (mvhd == NULL) { | ||
111 | GST_LOG_OBJECT (qtdemux, "No mvhd node found, looking for redirects."); | ||
112 | return qtdemux_parse_redirects (qtdemux); | ||
113 | @@ -14213,15 +14247,26 @@ qtdemux_parse_tree (GstQTDemux * qtdemux) | ||
114 | creation_time = QT_UINT64 ((guint8 *) mvhd->data + 12); | ||
115 | qtdemux->timescale = QT_UINT32 ((guint8 *) mvhd->data + 28); | ||
116 | qtdemux->duration = QT_UINT64 ((guint8 *) mvhd->data + 32); | ||
117 | + if (!gst_byte_reader_skip (&mvhd_reader, 4 + 8 + 8 + 4 + 8)) | ||
118 | + return FALSE; | ||
119 | } else if (version == 0) { | ||
120 | creation_time = QT_UINT32 ((guint8 *) mvhd->data + 12); | ||
121 | qtdemux->timescale = QT_UINT32 ((guint8 *) mvhd->data + 20); | ||
122 | qtdemux->duration = QT_UINT32 ((guint8 *) mvhd->data + 24); | ||
123 | + if (!gst_byte_reader_skip (&mvhd_reader, 4 + 4 + 4 + 4 + 4)) | ||
124 | + return FALSE; | ||
125 | } else { | ||
126 | GST_WARNING_OBJECT (qtdemux, "Unhandled mvhd version %d", version); | ||
127 | return FALSE; | ||
128 | } | ||
129 | |||
130 | + if (!gst_byte_reader_skip (&mvhd_reader, 4 + 2 + 2 + 2 * 4)) | ||
131 | + return FALSE; | ||
132 | + | ||
133 | + if (!qtdemux_parse_transformation_matrix (qtdemux, &mvhd_reader, matrix, | ||
134 | + "mvhd")) | ||
135 | + return FALSE; | ||
136 | + | ||
137 | /* Moving qt creation time (secs since 1904) to unix time */ | ||
138 | if (creation_time != 0) { | ||
139 | /* Try to use epoch first as it should be faster and more commonly found */ | ||
140 | @@ -14290,7 +14335,7 @@ qtdemux_parse_tree (GstQTDemux * qtdemux) | ||
141 | /* parse all traks */ | ||
142 | trak = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_trak); | ||
143 | while (trak) { | ||
144 | - qtdemux_parse_trak (qtdemux, trak); | ||
145 | + qtdemux_parse_trak (qtdemux, trak, matrix); | ||
146 | /* iterate all siblings */ | ||
147 | trak = qtdemux_tree_get_sibling_by_type (trak, FOURCC_trak); | ||
148 | } | ||
149 | -- | ||
150 | 2.50.1 | ||
151 | |||
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2025-47183-002.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2025-47183-002.patch new file mode 100644 index 0000000000..77127dd466 --- /dev/null +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2025-47183-002.patch | |||
@@ -0,0 +1,80 @@ | |||
1 | From d76cae74dad89994bfcdad83da6ef1ad69074332 Mon Sep 17 00:00:00 2001 | ||
2 | From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com> | ||
3 | Date: Tue, 29 Apr 2025 09:43:58 +0300 | ||
4 | Subject: [PATCH] qtdemux: Use byte reader to parse mvhd box | ||
5 | |||
6 | This avoids OOB reads. | ||
7 | |||
8 | Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4394 | ||
9 | Fixes CVE-2025-47183 | ||
10 | |||
11 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9133> | ||
12 | |||
13 | CVE: CVE-2025-47183 | ||
14 | Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/d76cae74dad89994bfcdad83da6ef1ad69074332] | ||
15 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
16 | --- | ||
17 | gst/isomp4/qtdemux.c | 36 ++++++++++++++++++++++++++---------- | ||
18 | 1 file changed, 26 insertions(+), 10 deletions(-) | ||
19 | |||
20 | diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c | ||
21 | index e708ef4..0d29869 100644 | ||
22 | --- a/gst/isomp4/qtdemux.c | ||
23 | +++ b/gst/isomp4/qtdemux.c | ||
24 | @@ -14228,7 +14228,7 @@ qtdemux_parse_tree (GstQTDemux * qtdemux) | ||
25 | GNode *pssh; | ||
26 | guint64 creation_time; | ||
27 | GstDateTime *datetime = NULL; | ||
28 | - gint version; | ||
29 | + guint8 version; | ||
30 | GstByteReader mvhd_reader; | ||
31 | guint32 matrix[9]; | ||
32 | |||
33 | @@ -14242,19 +14242,35 @@ qtdemux_parse_tree (GstQTDemux * qtdemux) | ||
34 | return qtdemux_parse_redirects (qtdemux); | ||
35 | } | ||
36 | |||
37 | - version = QT_UINT8 ((guint8 *) mvhd->data + 8); | ||
38 | + if (!gst_byte_reader_get_uint8 (&mvhd_reader, &version)) | ||
39 | + return FALSE; | ||
40 | + /* flags */ | ||
41 | + if (!gst_byte_reader_skip (&mvhd_reader, 3)) | ||
42 | + return FALSE; | ||
43 | if (version == 1) { | ||
44 | - creation_time = QT_UINT64 ((guint8 *) mvhd->data + 12); | ||
45 | - qtdemux->timescale = QT_UINT32 ((guint8 *) mvhd->data + 28); | ||
46 | - qtdemux->duration = QT_UINT64 ((guint8 *) mvhd->data + 32); | ||
47 | - if (!gst_byte_reader_skip (&mvhd_reader, 4 + 8 + 8 + 4 + 8)) | ||
48 | + if (!gst_byte_reader_get_uint64_be (&mvhd_reader, &creation_time)) | ||
49 | + return FALSE; | ||
50 | + /* modification time */ | ||
51 | + if (!gst_byte_reader_skip (&mvhd_reader, 8)) | ||
52 | + return FALSE; | ||
53 | + if (!gst_byte_reader_get_uint32_be (&mvhd_reader, &qtdemux->timescale)) | ||
54 | + return FALSE; | ||
55 | + if (!gst_byte_reader_get_uint64_be (&mvhd_reader, &qtdemux->duration)) | ||
56 | return FALSE; | ||
57 | } else if (version == 0) { | ||
58 | - creation_time = QT_UINT32 ((guint8 *) mvhd->data + 12); | ||
59 | - qtdemux->timescale = QT_UINT32 ((guint8 *) mvhd->data + 20); | ||
60 | - qtdemux->duration = QT_UINT32 ((guint8 *) mvhd->data + 24); | ||
61 | - if (!gst_byte_reader_skip (&mvhd_reader, 4 + 4 + 4 + 4 + 4)) | ||
62 | + guint32 tmp; | ||
63 | + | ||
64 | + if (!gst_byte_reader_get_uint32_be (&mvhd_reader, &tmp)) | ||
65 | + return FALSE; | ||
66 | + creation_time = tmp; | ||
67 | + /* modification time */ | ||
68 | + if (!gst_byte_reader_skip (&mvhd_reader, 4)) | ||
69 | + return FALSE; | ||
70 | + if (!gst_byte_reader_get_uint32_be (&mvhd_reader, &qtdemux->timescale)) | ||
71 | + return FALSE; | ||
72 | + if (!gst_byte_reader_get_uint32_be (&mvhd_reader, &tmp)) | ||
73 | return FALSE; | ||
74 | + qtdemux->duration = tmp; | ||
75 | } else { | ||
76 | GST_WARNING_OBJECT (qtdemux, "Unhandled mvhd version %d", version); | ||
77 | return FALSE; | ||
78 | -- | ||
79 | 2.50.1 | ||
80 | |||
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2025-47219.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2025-47219.patch new file mode 100644 index 0000000000..0d7e02ec1e --- /dev/null +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2025-47219.patch | |||
@@ -0,0 +1,40 @@ | |||
1 | From b80803943388050cb870c95934fc52feeffb94ac Mon Sep 17 00:00:00 2001 | ||
2 | From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com> | ||
3 | Date: Sat, 3 May 2025 09:43:32 +0300 | ||
4 | Subject: [PATCH] qtdemux: Check if enough bytes are available for each stsd | ||
5 | entry | ||
6 | |||
7 | There must be at least 8 bytes for the length / fourcc of each entry. After | ||
8 | reading those, the length is already validated against the remaining available | ||
9 | bytes. | ||
10 | |||
11 | Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4407 | ||
12 | Fixes CVE-2025-47219 | ||
13 | |||
14 | Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9137> | ||
15 | |||
16 | CVE: CVE-2025-47219 | ||
17 | Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/b80803943388050cb870c95934fc52feeffb94ac] | ||
18 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
19 | --- | ||
20 | gst/isomp4/qtdemux.c | 4 ++++ | ||
21 | 1 file changed, 4 insertions(+) | ||
22 | |||
23 | diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c | ||
24 | index 10b21a6..b40aa81 100644 | ||
25 | --- a/gst/isomp4/qtdemux.c | ||
26 | +++ b/gst/isomp4/qtdemux.c | ||
27 | @@ -11399,6 +11399,10 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak) | ||
28 | gchar *codec = NULL; | ||
29 | QtDemuxStreamStsdEntry *entry = &stream->stsd_entries[stsd_index]; | ||
30 | |||
31 | + /* needs at least length and fourcc */ | ||
32 | + if (remaining_stsd_len < 8) | ||
33 | + goto corrupt_file; | ||
34 | + | ||
35 | /* and that entry should fit within stsd */ | ||
36 | len = QT_UINT32 (stsd_entry_data); | ||
37 | if (len > remaining_stsd_len) | ||
38 | -- | ||
39 | 2.50.1 | ||
40 | |||
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.22.12.bb b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.22.12.bb index 608c3030ba..31bc8af015 100644 --- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.22.12.bb +++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.22.12.bb | |||
@@ -38,6 +38,9 @@ SRC_URI = "https://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-go | |||
38 | file://0029-wavparse-Check-that-at-least-32-bytes-are-available-.patch \ | 38 | file://0029-wavparse-Check-that-at-least-32-bytes-are-available-.patch \ |
39 | file://0030-wavparse-Fix-clipping-of-size-to-the-file-size.patch \ | 39 | file://0030-wavparse-Fix-clipping-of-size-to-the-file-size.patch \ |
40 | file://0031-wavparse-Check-size-before-reading-ds64-chunk.patch \ | 40 | file://0031-wavparse-Check-size-before-reading-ds64-chunk.patch \ |
41 | file://CVE-2025-47183-001.patch \ | ||
42 | file://CVE-2025-47183-002.patch \ | ||
43 | file://CVE-2025-47219.patch \ | ||
41 | " | 44 | " |
42 | 45 | ||
43 | SRC_URI[sha256sum] = "9c1913f981900bd8867182639b20907b28ed78ef7a222cfbf2d8ba9dab992fa7" | 46 | SRC_URI[sha256sum] = "9c1913f981900bd8867182639b20907b28ed78ef7a222cfbf2d8ba9dab992fa7" |