From 02c79c7ec46f13ba2fd6818b4a2046d763f4ac3d Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 1 Mar 2021 13:49:33 +0200 Subject: [PATCH] UPSTREAM: usb: gadget: f_uac2: validate input parameters Currently user can configure UAC2 function with parameters that violate UAC2 spec or are not supported by UAC2 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 UAC2 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-4-git-send-email-ruslan.bilovol@gmail.com Signed-off-by: Greg Kroah-Hartman Bug: 187332233 (cherry picked from commit 3713d5ceb04d5ab6a5e2b86dfca49170053f3a5e) Change-Id: Icc684c620e039f7dbb3591e5669506f6f69574d6 Signed-off-by: Jack Pham --- drivers/usb/gadget/function/f_uac2.c | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index dd960cea642f..003a568489f8 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -637,6 +637,36 @@ static int afunc_validate_opts(struct g_audio *agdev, struct device *dev) return 0; } +static int afunc_validate_opts(struct g_audio *agdev, struct device *dev) +{ + struct f_uac2_opts *opts = g_audio_to_uac2_opts(agdev); + + if (!opts->p_chmask && !opts->c_chmask) { + dev_err(dev, "Error: no playback and capture channels\n"); + return -EINVAL; + } else if (opts->p_chmask & ~UAC2_CHANNEL_MASK) { + dev_err(dev, "Error: unsupported playback channels mask\n"); + return -EINVAL; + } else if (opts->c_chmask & ~UAC2_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; +} + static int afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) {