From patchwork Mon Nov 25 14:46:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 13885046 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E39BC184527 for ; Mon, 25 Nov 2024 14:46:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=195.135.223.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732545996; cv=none; b=jz81UKN2qupixDowwrCTDmgzv7oxsN8n8lWBbm/fq/KmudL7+fgIcE2kxV1mKdp8GVPaJLNNFEIBxThGkiC4/vPIleJuJL3a2NsLGMfPWaX1OkhLy83dNgwdUtRj7+0r3Z0lsFeYeEjrvtHPgGGZY5rstdADzevOYN4L3R8Q45Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732545996; c=relaxed/simple; bh=2ScGa+JA5d8OS/bw//Nu3VJVYCHuNJA/I/B47SA894Y=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=Whp6Vtfwc8y43YxDAhm7tn1fqaYQhvfJU1Xm4DJSos2PHp7CA0Ivm0AMW32tUWZ5a9RNjE9d7nzNl1Va42O6/8ea3k8lOZLBWTUcNuMgSbBvSU9IzO96US8Bk6SKAfaJ209UgGbhgMWQ6r7Coj79fxzO9d9EsTDBO0N5NSETGD4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=suse.de; spf=pass smtp.mailfrom=suse.de; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.b=EaKMm8jP; dkim=permerror (0-bit key) header.d=suse.de header.i=@suse.de header.b=ge6l0NDV; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.b=EaKMm8jP; dkim=permerror (0-bit key) header.d=suse.de header.i=@suse.de header.b=ge6l0NDV; arc=none smtp.client-ip=195.135.223.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=suse.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.b="EaKMm8jP"; dkim=permerror (0-bit key) header.d=suse.de header.i=@suse.de header.b="ge6l0NDV"; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.b="EaKMm8jP"; dkim=permerror (0-bit key) header.d=suse.de header.i=@suse.de header.b="ge6l0NDV" Received: from imap1.dmz-prg2.suse.org (unknown [10.150.64.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 3699721120; Mon, 25 Nov 2024 14:46:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1732545993; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LlnTbOU2J41zXytx2BYcef0NhCBkXPOmBrnyCqfz72s=; b=EaKMm8jPYcYiPab//D8wWDmHhU6oCky9QonV+TALjUrzIpeeCJoSy1svQ89cazJpWWstPP nnn6ZT9WfeuH2NJR4995eR6mV0Is7I7HsokVyXr47aZg8XjtmmyFVMiPttVveV0SFOHinf ZY+m1ZRc5GpRQhB5vCsFO1dvIe3TD8M= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1732545993; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LlnTbOU2J41zXytx2BYcef0NhCBkXPOmBrnyCqfz72s=; b=ge6l0NDV6sXXQ08/WO6fqjmdzg3HlsDd3gDMjYor0/mavEHKJoGm2VNsGib2xHnNIV4dLk 6kAEzCTdSq+4w2Cw== Authentication-Results: smtp-out1.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1732545993; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LlnTbOU2J41zXytx2BYcef0NhCBkXPOmBrnyCqfz72s=; b=EaKMm8jPYcYiPab//D8wWDmHhU6oCky9QonV+TALjUrzIpeeCJoSy1svQ89cazJpWWstPP nnn6ZT9WfeuH2NJR4995eR6mV0Is7I7HsokVyXr47aZg8XjtmmyFVMiPttVveV0SFOHinf ZY+m1ZRc5GpRQhB5vCsFO1dvIe3TD8M= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1732545993; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LlnTbOU2J41zXytx2BYcef0NhCBkXPOmBrnyCqfz72s=; b=ge6l0NDV6sXXQ08/WO6fqjmdzg3HlsDd3gDMjYor0/mavEHKJoGm2VNsGib2xHnNIV4dLk 6kAEzCTdSq+4w2Cw== Received: from imap1.dmz-prg2.suse.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id 17858137D4; Mon, 25 Nov 2024 14:46:33 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap1.dmz-prg2.suse.org with ESMTPSA id kQmLBMmNRGdnTgAAD6G6ig (envelope-from ); Mon, 25 Nov 2024 14:46:33 +0000 From: Takashi Iwai To: linux-sound@vger.kernel.org Cc: =?utf-8?q?Beno=C3=AEt_Sevens?= Subject: [PATCH] ALSA: usb-audio: Fix out of bounds reads when finding clock sources Date: Mon, 25 Nov 2024 15:46:16 +0100 Message-ID: <20241125144629.20757-1-tiwai@suse.de> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-sound@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Score: -3.30 X-Spamd-Result: default: False [-3.30 / 50.00]; BAYES_HAM(-3.00)[99.99%]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000]; NEURAL_HAM_SHORT(-0.20)[-0.999]; MIME_GOOD(-0.10)[text/plain]; RCVD_VIA_SMTP_AUTH(0.00)[]; ARC_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; RCPT_COUNT_TWO(0.00)[2]; RCVD_TLS_ALL(0.00)[]; FUZZY_BLOCKED(0.00)[rspamd.com]; TO_DN_SOME(0.00)[]; FROM_HAS_DN(0.00)[]; DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; FROM_EQ_ENVFROM(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; DBL_BLOCKED_OPENRESOLVER(0.00)[suse.de:mid,suse.de:email,imap1.dmz-prg2.suse.org:helo] X-Spam-Flag: NO X-Spam-Level: The current USB-audio driver code doesn't check bLength of each descriptor at traversing for clock descriptors. That is, when a device provides a bogus descriptor with a shorter bLength, the driver might hit out-of-bounds reads. For addressing it, this patch adds sanity checks to the validator functions for the clock descriptor traversal. When the descriptor length is shorter than expected, it's skipped in the loop. For the clock source and clock multiplier descriptors, we can just check bLength against the sizeof() of each descriptor type. OTOH, the clock selector descriptor of UAC2 and UAC3 has an array of bNrInPins elements and two more fields at its tail, hence those have to be checked in addition to the sizeof() check. Reported-by: BenoƮt Sevens Cc: Link: https://lore.kernel.org/20241121140613.3651-1-bsevens@google.com Signed-off-by: Takashi Iwai --- sound/usb/clock.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 8f85200292f3..842ba5b801ea 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c @@ -36,6 +36,12 @@ union uac23_clock_multiplier_desc { struct uac_clock_multiplier_descriptor v3; }; +/* check whether the descriptor bLength has the minimal length */ +#define DESC_LENGTH_CHECK(p, proto) \ + ((proto) == UAC_VERSION_3 ? \ + ((p)->v3.bLength >= sizeof((p)->v3)) : \ + ((p)->v2.bLength >= sizeof((p)->v2))) + #define GET_VAL(p, proto, field) \ ((proto) == UAC_VERSION_3 ? (p)->v3.field : (p)->v2.field) @@ -58,6 +64,8 @@ static bool validate_clock_source(void *p, int id, int proto) { union uac23_clock_source_desc *cs = p; + if (!DESC_LENGTH_CHECK(cs, proto)) + return false; return GET_VAL(cs, proto, bClockID) == id; } @@ -65,13 +73,27 @@ static bool validate_clock_selector(void *p, int id, int proto) { union uac23_clock_selector_desc *cs = p; - return GET_VAL(cs, proto, bClockID) == id; + if (!DESC_LENGTH_CHECK(cs, proto)) + return false; + if (GET_VAL(cs, proto, bClockID) != id) + return false; + /* additional length check for baCSourceID array (in bNrInPins size) + * and two more fields (which sizes depend on the protocol) + */ + if (proto == UAC_VERSION_3) + return cs->v3.bLength >= sizeof(cs->v3) + cs->v3.bNrInPins + + 4 /* bmControls */ + 2 /* wCSelectorDescrStr */; + else + return cs->v2.bLength >= sizeof(cs->v2) + cs->v2.bNrInPins + + 1 /* bmControls */ + 1 /* iClockSelector */; } static bool validate_clock_multiplier(void *p, int id, int proto) { union uac23_clock_multiplier_desc *cs = p; + if (!DESC_LENGTH_CHECK(cs, proto)) + return false; return GET_VAL(cs, proto, bClockID) == id; }