Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2476242pxj; Mon, 10 May 2021 04:02:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxgC0oAolb5ygm5LMzbvhHQ9i1XbdXXw6YzL8dBy1bSEMpryNK7bCdQ5/dZ8IsJKvFuVuCX X-Received: by 2002:a05:6e02:8f2:: with SMTP id n18mr20003457ilt.299.1620644561030; Mon, 10 May 2021 04:02:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620644561; cv=none; d=google.com; s=arc-20160816; b=XcSNHwcWAexLdPQSrRn8HWBL5z2wWY1fQhF0M+ZQkWjYuhTfnq2NhBR0wUXJ8DvJpn f699rMaCVTpCZJgX1aGcG9lLX6icVF6VZorC7K3n3Jp62JOxYTq+TJ7Lkknwwx4uMsHO eKHJeTGAn/zMpzvQfIG6kcHvSR4f6JL9Rc29IzqlbAAWlV5vQaVr6mkqItl+BSAc7Vql tVSZ1B3o8ZEs2Ai7LpXcW2ljRirp9PTkZEjn0s0sQI0rnP+M23YoM419tPQU6ytflzXR EzUidUWLV44WFIKox4yHA5X6MEYNnpyc0TkZWoe4mjaDoLSxE6KFHG6FYyvefvQW72ie Rz0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=c5WlBrlrh3S4e7v0n6+GDWU0dH1TttNm0vPzDwzg1ho=; b=e28m5cahKjYHONxOUZbu5C77ibvMz0N2UNhuejgdea7SOVhz+rxpkik6MsXuDZkzIu vnNIHeT3uIHXkxBnhRi6fvjEemI/8V2Ljw4ZzIDlx5r1mm7RI6ICcoef9qQfxFVxJDnn FoZcm7eYkQ7+ChKHNTuH0x0SZg/Gw9qp8mkjZTy1w84gMHuGCBevLbZtssh2lT04wKnt l23V0DTkM2hBiepmhNyXm0dNA6aYTbqqRDlf5mO4AlCt9uMhnlIiL/7D5ZIz6Vs07qGv VzkZgTqui+n8A2GKWG/IY32rmclFL1sqVL+Sf3JHhxJ+X2Y8b2b7rvsGnaLO70z8uO9l LT3Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=vWFAcYwY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h27si15766917jaq.100.2021.05.10.04.02.28; Mon, 10 May 2021 04:02:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=vWFAcYwY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233853AbhEJKzb (ORCPT + 99 others); Mon, 10 May 2021 06:55:31 -0400 Received: from mail.kernel.org ([198.145.29.99]:59674 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232723AbhEJKof (ORCPT ); Mon, 10 May 2021 06:44:35 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 2137161965; Mon, 10 May 2021 10:33:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1620642819; bh=4lQy9e8dkXC93bot0YqUtqhnEIMxfdIuRsAE80tMiwo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vWFAcYwYBaoknCJZf3o6TlzjDbOMfTSW6DraTZdiiDE/ERhLYJ9m2wubjxIs3+lF0 /y9CF3mLJ+MYnlZ1QzpN6s1No9D/5PJ/OYI4CmAGNB/I3+HvDr8Fm9JgYLAme4gJCq 4fGO+2w2I6tDJlpPhtoWtP99N6Y9iEkXSrB5wsXA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ruslan Bilovol , Sasha Levin Subject: [PATCH 5.10 064/299] usb: gadget: f_uac1: validate input parameters Date: Mon, 10 May 2021 12:17:41 +0200 Message-Id: <20210510102007.000988005@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210510102004.821838356@linuxfoundation.org> References: <20210510102004.821838356@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ruslan Bilovol [ Upstream commit a59c68a6a3d1b18e2494f526eb19893a34fa6ec6 ] Currently user can configure UAC1 function with parameters that violate UAC1 spec or are not supported by UAC1 gadget implementation. This can lead to incorrect behavior if such gadget is connected to the host - like enumeration failure or other issues depending on host's UAC1 driver implementation, bringing user to a long hours of debugging the issue. Instead of silently accept these parameters, throw an error if they are not valid. Signed-off-by: Ruslan Bilovol Link: https://lore.kernel.org/r/1614599375-8803-5-git-send-email-ruslan.bilovol@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/gadget/function/f_uac1.c | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 560382e0a8f3..e65f474ad7b3 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -19,6 +19,9 @@ #include "u_audio.h" #include "u_uac1.h" +/* UAC1 spec: 3.7.2.3 Audio Channel Cluster Format */ +#define UAC1_CHANNEL_MASK 0x0FFF + struct f_uac1 { struct g_audio g_audio; u8 ac_intf, as_in_intf, as_out_intf; @@ -30,6 +33,11 @@ static inline struct f_uac1 *func_to_uac1(struct usb_function *f) return container_of(f, struct f_uac1, g_audio.func); } +static inline struct f_uac1_opts *g_audio_to_uac1_opts(struct g_audio *audio) +{ + return container_of(audio->func.fi, struct f_uac1_opts, func_inst); +} + /* * DESCRIPTORS ... most are static, but strings and full * configuration descriptors are built on demand. @@ -505,11 +513,42 @@ static void f_audio_disable(struct usb_function *f) /*-------------------------------------------------------------------------*/ +static int f_audio_validate_opts(struct g_audio *audio, struct device *dev) +{ + struct f_uac1_opts *opts = g_audio_to_uac1_opts(audio); + + if (!opts->p_chmask && !opts->c_chmask) { + dev_err(dev, "Error: no playback and capture channels\n"); + return -EINVAL; + } else if (opts->p_chmask & ~UAC1_CHANNEL_MASK) { + dev_err(dev, "Error: unsupported playback channels mask\n"); + return -EINVAL; + } else if (opts->c_chmask & ~UAC1_CHANNEL_MASK) { + dev_err(dev, "Error: unsupported capture channels mask\n"); + return -EINVAL; + } else if ((opts->p_ssize < 1) || (opts->p_ssize > 4)) { + dev_err(dev, "Error: incorrect playback sample size\n"); + return -EINVAL; + } else if ((opts->c_ssize < 1) || (opts->c_ssize > 4)) { + dev_err(dev, "Error: incorrect capture sample size\n"); + return -EINVAL; + } else if (!opts->p_srate) { + dev_err(dev, "Error: incorrect playback sampling rate\n"); + return -EINVAL; + } else if (!opts->c_srate) { + dev_err(dev, "Error: incorrect capture sampling rate\n"); + return -EINVAL; + } + + return 0; +} + /* audio function driver setup/binding */ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; struct usb_gadget *gadget = cdev->gadget; + struct device *dev = &gadget->dev; struct f_uac1 *uac1 = func_to_uac1(f); struct g_audio *audio = func_to_g_audio(f); struct f_uac1_opts *audio_opts; @@ -519,6 +558,10 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) int rate; int status; + status = f_audio_validate_opts(audio, dev); + if (status) + return status; + audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst); us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); -- 2.30.2