Skip to content

Commit 5526c1c

Browse files
Shipei Qutiwai
authored andcommitted
ALSA: usb-mixer: us16x08: validate meter packet indices
get_meter_levels_from_urb() parses the 64-byte meter packets sent by the device and fills the per-channel arrays meter_level[], comp_level[] and master_level[] in struct snd_us16x08_meter_store. Currently the function derives the channel index directly from the meter packet (MUB2(meter_urb, s) - 1) and uses it to index those arrays without validating the range. If the packet contains a negative or out-of-range channel number, the driver may write past the end of these arrays. Introduce a local channel variable and validate it before updating the arrays. We reject negative indices, limit meter_level[] and comp_level[] to SND_US16X08_MAX_CHANNELS, and guard master_level[] updates with ARRAY_SIZE(master_level). Fixes: d2bb390 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk") Reported-by: DARKNAVY (@DarkNavyOrg) <vr@darknavy.com> Closes: https://lore.kernel.org/tencent_21C112743C44C1A2517FF219@qq.com Signed-off-by: Shipei Qu <qu@darknavy.com> Link: https://patch.msgid.link/20251217024630.59576-1-qu@darknavy.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 5032347 commit 5526c1c

1 file changed

Lines changed: 14 additions & 6 deletions

File tree

sound/usb/mixer_us16x08.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -655,17 +655,25 @@ static void get_meter_levels_from_urb(int s,
655655
u8 *meter_urb)
656656
{
657657
int val = MUC2(meter_urb, s) + (MUC3(meter_urb, s) << 8);
658+
int ch = MUB2(meter_urb, s) - 1;
659+
660+
if (ch < 0)
661+
return;
658662

659663
if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
660664
MUA2(meter_urb, s) == 0x04 && MUB0(meter_urb, s) == 0x62) {
661-
if (MUC0(meter_urb, s) == 0x72)
662-
store->meter_level[MUB2(meter_urb, s) - 1] = val;
663-
if (MUC0(meter_urb, s) == 0xb2)
664-
store->comp_level[MUB2(meter_urb, s) - 1] = val;
665+
if (ch < SND_US16X08_MAX_CHANNELS) {
666+
if (MUC0(meter_urb, s) == 0x72)
667+
store->meter_level[ch] = val;
668+
if (MUC0(meter_urb, s) == 0xb2)
669+
store->comp_level[ch] = val;
670+
}
665671
}
666672
if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
667-
MUA2(meter_urb, s) == 0x02 && MUB0(meter_urb, s) == 0x62)
668-
store->master_level[MUB2(meter_urb, s) - 1] = val;
673+
MUA2(meter_urb, s) == 0x02 && MUB0(meter_urb, s) == 0x62) {
674+
if (ch < ARRAY_SIZE(store->master_level))
675+
store->master_level[ch] = val;
676+
}
669677
}
670678

671679
/* Function to retrieve current meter values from the device.

0 commit comments

Comments
 (0)