提交 74041b3d 编写于 作者: R Ruslan Bilovol 提交者: Zheng Zengkai

usb: gadget: f_uac2: validate input parameters

stable inclusion
from stable-5.10.36
commit f63390de9b4371b9eae23eb04332a15687925ed1
bugzilla: 51867
CVE: NA

--------------------------------

[ Upstream commit 3713d5ce ]

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: NRuslan Bilovol <ruslan.bilovol@gmail.com>
Link: https://lore.kernel.org/r/1614599375-8803-4-git-send-email-ruslan.bilovol@gmail.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Acked-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 ee1e297f
......@@ -14,6 +14,9 @@
#include "u_audio.h"
#include "u_uac2.h"
/* UAC2 spec: 4.1 Audio Channel Cluster Descriptor */
#define UAC2_CHANNEL_MASK 0x07FFFFFF
/*
* The driver implements a simple UAC_2 topology.
* USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture
......@@ -604,6 +607,36 @@ static void setup_descriptor(struct f_uac2_opts *opts)
hs_audio_desc[i] = NULL;
}
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)
{
......@@ -612,11 +645,13 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
struct usb_composite_dev *cdev = cfg->cdev;
struct usb_gadget *gadget = cdev->gadget;
struct device *dev = &gadget->dev;
struct f_uac2_opts *uac2_opts;
struct f_uac2_opts *uac2_opts = g_audio_to_uac2_opts(agdev);
struct usb_string *us;
int ret;
uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst);
ret = afunc_validate_opts(agdev, dev);
if (ret)
return ret;
us = usb_gstrings_attach(cdev, fn_strings, ARRAY_SIZE(strings_fn));
if (IS_ERR(us))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册