]> git.alsa-project.org Git - alsa-lib.git/commitdiff
topology: fix uint32_t overflow in control decoder size checks
authorHarsh Raj Singhania <raj.harshraut@gmail.com>
Wed, 30 Sep 2026 18:58:15 +0000 (00:28 +0530)
committerTakashi Iwai <tiwai@suse.de>
Thu, 15 Oct 2026 13:30:00 +0000 (15:30 +0200)
size2 = x->size + x->priv.size was computed in 32-bit arithmetic and could
wrap on a 64-bit host, bypassing the subsequent bounds check. Pre-check
for overflow then cast to size_t. Affects tplg_decode_control_mixer,
tplg_decode_control_enum, and tplg_decode_control_bytes.

Closes: https://github.com/alsa-project/alsa-lib/pull/527
Signed-off-by: Harsh Raj Singhania <raj.harshraut@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
src/topology/ctl.c

index 322c461cef506591ac1d1f8f61c1478cfb148888..93a09f1ef04d8d28c348e3a534236da3e50cf8fb 100644 (file)
@@ -1315,7 +1315,12 @@ next:
        }
        INIT_LIST_HEAD(&heap);
        mc = bin;
-       size2 = mc->size + mc->priv.size;
+       if (mc->priv.size > size || mc->size > size - mc->priv.size) {
+               snd_error(TOPOLOGY, "mixer: element sizes overflow (%d, priv %d)",
+                                   mc->size, mc->priv.size);
+               return -EINVAL;
+       }
+       size2 = (size_t)mc->size + (size_t)mc->priv.size;
        if (size2 > size) {
                snd_error(TOPOLOGY, "mixer: wrong element size (%d, priv %d)",
                                    mc->size, mc->priv.size);
@@ -1419,7 +1424,12 @@ next:
        }
        INIT_LIST_HEAD(&heap);
        ec = bin;
-       size2 = ec->size + ec->priv.size;
+       if (ec->priv.size > size || ec->size > size - ec->priv.size) {
+               snd_error(TOPOLOGY, "enum: element sizes overflow (%d, priv %d)",
+                                   ec->size, ec->priv.size);
+               return -EINVAL;
+       }
+       size2 = (size_t)ec->size + (size_t)ec->priv.size;
        if (size2 > size) {
                snd_error(TOPOLOGY, "enum: wrong element size (%d, priv %d)",
                                    ec->size, ec->priv.size);
@@ -1510,7 +1520,12 @@ next:
                return -EINVAL;
        }
        bc = bin;
-       size2 = bc->size + bc->priv.size;
+       if (bc->priv.size > size || bc->size > size - bc->priv.size) {
+               snd_error(TOPOLOGY, "bytes: element sizes overflow (%d, priv %d)",
+                                   bc->size, bc->priv.size);
+               return -EINVAL;
+       }
+       size2 = (size_t)bc->size + (size_t)bc->priv.size;
        if (size2 > size) {
                snd_error(TOPOLOGY, "bytes: wrong element size (%d, priv %d)",
                                    bc->size, bc->priv.size);