Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions sound/usb/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
#include "clock.h"
#include "quirks.h"

/* check whether the descriptor bLength has the minimal length */
#define DESC_LENGTH_CHECK(p) \
(p->bLength >= sizeof(*p))

static void *find_uac_clock_desc(struct usb_host_interface *iface, int id,
bool (*validator)(void *, int), u8 type)
{
Expand All @@ -52,36 +56,60 @@ static void *find_uac_clock_desc(struct usb_host_interface *iface, int id,
static bool validate_clock_source_v2(void *p, int id)
{
struct uac_clock_source_descriptor *cs = p;
if (!DESC_LENGTH_CHECK(cs))
return false;
return cs->bClockID == id;
}

static bool validate_clock_source_v3(void *p, int id)
{
struct uac3_clock_source_descriptor *cs = p;
if (!DESC_LENGTH_CHECK(cs))
return false;
return cs->bClockID == id;
}

static bool validate_clock_selector_v2(void *p, int id)
{
struct uac_clock_selector_descriptor *cs = p;
return cs->bClockID == id;
if (!DESC_LENGTH_CHECK(cs))
return false;
if (cs->bClockID != id)
return false;
/* additional length check for baCSourceID array (in bNrInPins size)
* and two more fields (which sizes depend on the protocol)
*/
return cs->bLength >= sizeof(*cs) + cs->bNrInPins +
1 /* bmControls */ + 1 /* iClockSelector */;
}

static bool validate_clock_selector_v3(void *p, int id)
{
struct uac3_clock_selector_descriptor *cs = p;
return cs->bClockID == id;
if (!DESC_LENGTH_CHECK(cs))
return false;
if (cs->bClockID != id)
return false;
/* additional length check for baCSourceID array (in bNrInPins size)
* and two more fields (which sizes depend on the protocol)
*/
return cs->bLength >= sizeof(*cs) + cs->bNrInPins +
4 /* bmControls */ + 2 /* wCSelectorDescrStr */;
}

static bool validate_clock_multiplier_v2(void *p, int id)
{
struct uac_clock_multiplier_descriptor *cs = p;
if (!DESC_LENGTH_CHECK(cs))
return false;
return cs->bClockID == id;
}

static bool validate_clock_multiplier_v3(void *p, int id)
{
struct uac3_clock_multiplier_descriptor *cs = p;
if (!DESC_LENGTH_CHECK(cs))
return false;
return cs->bClockID == id;
}

Expand Down