From 1171ae8ac218ea85f8dc41203a2ee146ff322a20 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 12 Jan 2026 13:21:48 +0200
Subject: [PATCH 1/5] wavparse: Remove pointless duplicated GST_ROUND_UP_2()

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10903>
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -1666,7 +1666,6 @@ gst_wavparse_stream_headers (GstWavParse * wav)
         } else {
           gst_buffer_unref (buf);
         }
-        size = GST_ROUND_UP_2 (size);
         wav->offset += size;
         break;
       }
@@ -1712,7 +1711,6 @@ gst_wavparse_stream_headers (GstWavParse * wav)
         } else {
           gst_buffer_unref (buf);
         }
-        size = GST_ROUND_UP_2 (size);
         wav->offset += size;
         break;
       }
-- 
GitLab


From 3564405b6919469427750f6b89d4abbe43534fa2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 12 Jan 2026 13:22:03 +0200
Subject: [PATCH 2/5] wavparse: Use unsigned integers for data sizes

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10903>
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -1535,7 +1535,7 @@ gst_wavparse_stream_headers (GstWavParse * wav)
         }
         switch (ltag) {
           case GST_RIFF_LIST_INFO:{
-            const gint data_size = size - 4;
+            const guint data_size = size - 4;
             GstTagList *new;
 
             GST_INFO_OBJECT (wav, "Have LIST chunk INFO size %u", data_size);
@@ -1581,7 +1581,7 @@ gst_wavparse_stream_headers (GstWavParse * wav)
             break;
           }
           case GST_RIFF_LIST_adtl:{
-            const gint data_size = size - 4;
+            const guint data_size = size - 4;
 
             GST_INFO_OBJECT (wav, "Have 'adtl' LIST, size %u", data_size);
             if (wav->streaming) {
@@ -1670,7 +1670,7 @@ gst_wavparse_stream_headers (GstWavParse * wav)
         break;
       }
       case GST_RIFF_TAG_smpl:{
-        const gint data_size = size;
+        const guint data_size = size;
 
         GST_DEBUG_OBJECT (wav, "Have 'smpl' TAG, size : %u", data_size);
         if (wav->streaming) {
-- 
GitLab


From c73a1f4427ecb2e77d00fdd9576bd9864cfaba97 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 12 Jan 2026 13:41:31 +0200
Subject: [PATCH 3/5] wavparse: Use GST_ROUND_UP_2() in two more places instead
 of a manual implementation

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10903>
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -701,7 +701,7 @@ gst_wavparse_peek_chunk (GstWavParse * wav, guint32 * tag, guint32 * size)
     wav->abort_buffering = TRUE;
     return FALSE;
   }
-  peek_size = (*size + 1) & ~1;
+  peek_size = GST_ROUND_UP_2 (*size);
   available = gst_adapter_available (wav->adapter);
 
   if (available >= (8 + peek_size)) {
@@ -757,7 +757,7 @@ gst_waveparse_ignore_chunk (GstWavParse * wav, GstBuffer * buf, guint32 tag,
   }
   GST_DEBUG_OBJECT (wav, "Ignoring tag %" GST_FOURCC_FORMAT,
       GST_FOURCC_ARGS (tag));
-  flush = 8 + ((size + 1) & ~1);
+  flush = 8 + GST_ROUND_UP_2 (size);
   wav->offset += flush;
   if (wav->streaming) {
     gst_adapter_flush (wav->adapter, flush);
-- 
GitLab


From 8822ee3b2397d865c21cbbd8e36fb2d64d6ab380 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 12 Jan 2026 13:48:20 +0200
Subject: [PATCH 4/5] wavparse: Define maximum chunk size in a single place

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10903>
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -64,6 +64,9 @@ GST_DEBUG_CATEGORY_STATIC (wavparse_debug);
  * see http://tech.ebu.ch/docs/tech/tech3306-2009.pdf */
 #define GST_RS64_TAG_DS64 GST_MAKE_FOURCC ('d','s','6','4')
 
+/* Maximum valid size is INT32_MAX */
+#define MAX_CHUNK_SIZE ((guint32) G_MAXINT32)
+
 static void gst_wavparse_dispose (GObject * object);
 
 static gboolean gst_wavparse_sink_activate (GstPad * sinkpad,
@@ -694,7 +697,7 @@ gst_wavparse_peek_chunk (GstWavParse * wav, guint32 * tag, guint32 * size)
    * large size -> do not bother trying to squeeze that into adapter,
    * so we throw poor man's exception, which can be caught if caller really
    * wants to handle 0 size chunk */
-  if (!(*size) || (*size) >= (1 << 30)) {
+  if (!(*size) || (*size) > MAX_CHUNK_SIZE) {
     GST_INFO ("Invalid/unexpected chunk size %u for tag %" GST_FOURCC_FORMAT,
         *size, GST_FOURCC_ARGS (*tag));
     /* chain should give up */
@@ -1339,10 +1342,9 @@ gst_wavparse_stream_headers (GstWavParse * wav)
         "Got TAG: %" GST_FOURCC_FORMAT ", offset %" G_GUINT64_FORMAT ", size %"
         G_GUINT32_FORMAT, GST_FOURCC_ARGS (tag), wav->offset, size);
 
-    /* Maximum valid size is INT_MAX */
-    if (size & 0x80000000) {
-      GST_WARNING_OBJECT (wav, "Invalid size, clipping to 0x7fffffff");
-      size = 0x7fffffff;
+    if (size > MAX_CHUNK_SIZE) {
+      GST_WARNING_OBJECT (wav, "Invalid size, clipping to %u", MAX_CHUNK_SIZE);
+      size = MAX_CHUNK_SIZE;
     }
 
     /* Clip to upstream size if known */
-- 
GitLab


From 081484ec99aa75fe24b3286d88e1f1280deea56a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 12 Jan 2026 14:26:19 +0200
Subject: [PATCH 5/5] wavparse: Avoid integer overflow and out-of-bounds read
 when parsing adtl chunks

Fixes GST-SA-2026-0001, CVE-2026-1940.

Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4854

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10903>
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -760,6 +760,8 @@ gst_waveparse_ignore_chunk (GstWavParse * wav, GstBuffer * buf, guint32 tag,
   }
   GST_DEBUG_OBJECT (wav, "Ignoring tag %" GST_FOURCC_FORMAT,
       GST_FOURCC_ARGS (tag));
+  /* Checked in all callers */
+  g_assert (size < MAX_CHUNK_SIZE);
   flush = 8 + GST_ROUND_UP_2 (size);
   wav->offset += flush;
   if (wav->streaming) {
@@ -940,7 +942,7 @@ gst_wavparse_adtl_chunk (GstWavParse * wav, const guint8 * data, guint32 size)
     ltag = GST_READ_UINT32_LE (data + offset);
     lsize = GST_READ_UINT32_LE (data + offset + 4);
 
-    if (lsize > (G_MAXUINT - 8) || lsize + 8 > size) {
+    if (lsize > MAX_CHUNK_SIZE || GST_ROUND_UP_2 (lsize) + 8 > size) {
       GST_WARNING_OBJECT (wav, "Invalid adtl size: %u + 8 > %u", lsize, size);
       return FALSE;
     }
@@ -958,8 +960,9 @@ gst_wavparse_adtl_chunk (GstWavParse * wav, const guint8 * data, guint32 size)
         GST_MEMDUMP_OBJECT (wav, "Unknowm adtl", &data[offset], lsize);
         break;
     }
-    offset += 8 + GST_ROUND_UP_2 (lsize);
-    size -= 8 + GST_ROUND_UP_2 (lsize);
+    lsize = GST_ROUND_UP_2 (lsize);
+    offset += 8 + lsize;
+    size -= 8 + lsize;
   }
 
   return TRUE;
-- 
GitLab

