]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: firewire: isight: bound the sample count to the packet payload
authorMaoyi Xie <maoyixie.tju@gmail.com>
Sun, 21 Jun 2026 15:09:07 +0000 (23:09 +0800)
committerTakashi Iwai <tiwai@suse.de>
Thu, 25 Jun 2026 12:02:13 +0000 (14:02 +0200)
isight_packet() takes the frame count from the device iso packet and
checks it only against the device claimed iso length.

count = be32_to_cpu(payload->sample_count);
if (likely(count <= (length - 16) / 4))
isight_samples(isight, payload->samples, count);

length is the iso header data_length. It can be up to 0xffff. So the
gate allows a count up to about 16379. isight_samples() then copies
count frames out of payload->samples into the PCM DMA buffer.

payload->samples holds only 2 * MAX_FRAMES_PER_PACKET values. The
device multiplexes two samples per frame. A count past
MAX_FRAMES_PER_PACKET reads past the payload. A count past the buffer
size writes past runtime->dma_area. The smallest PCM buffer is larger
than MAX_FRAMES_PER_PACKET. Bounding the count to MAX_FRAMES_PER_PACKET
keeps both the read and the write in range.

A malicious or faulty Apple iSight on the FireWire bus reaches this
during a normal capture.

Add the MAX_FRAMES_PER_PACKET bound to the gate.

Fixes: 3a691b28a0ca ("ALSA: add Apple iSight microphone driver")
Suggested-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Cc: stable@vger.kernel.org
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
Link: https://patch.msgid.link/178205454729.1900991.7807310178296762772@maoyixie.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/firewire/isight.c

index 2b7f071d593b95db6434803767f690f1c4b19edf..33c9dd48b3b0bb4e48984777568e080290edd897 100644 (file)
@@ -179,7 +179,8 @@ static void isight_packet(struct fw_iso_context *context, u32 cycle,
        if (likely(length >= 16 &&
                   payload->signature == cpu_to_be32(0x73676874/*"sght"*/))) {
                count = be32_to_cpu(payload->sample_count);
-               if (likely(count <= (length - 16) / 4)) {
+               if (likely(count <= (length - 16) / 4 &&
+                          count <= MAX_FRAMES_PER_PACKET)) {
                        total = be32_to_cpu(payload->sample_total);
                        if (unlikely(total != isight->total_samples)) {
                                if (!isight->first_packet)