Skip to content

Commit

Permalink
ALSA: usb-audio: Remove superfluous bLength checks
Browse files Browse the repository at this point in the history
Now that we got the more comprehensive validation code for USB-audio
descriptors, the check of overflow in each descriptor unit parser
became superfluous.  Drop some of the obvious cases.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Aug 22, 2019
1 parent 52c3e31 commit b8e4f1f
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 92 deletions.
14 changes: 6 additions & 8 deletions sound/usb/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,39 +38,37 @@ 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;
return cs->bLength == sizeof(*cs) && cs->bClockID == id;
return cs->bClockID == id;
}

static bool validate_clock_source_v3(void *p, int id)
{
struct uac3_clock_source_descriptor *cs = p;
return cs->bLength == sizeof(*cs) && cs->bClockID == id;
return cs->bClockID == id;
}

static bool validate_clock_selector_v2(void *p, int id)
{
struct uac_clock_selector_descriptor *cs = p;
return cs->bLength >= sizeof(*cs) && cs->bClockID == id &&
cs->bLength == 7 + cs->bNrInPins;
return cs->bClockID == id;
}

static bool validate_clock_selector_v3(void *p, int id)
{
struct uac3_clock_selector_descriptor *cs = p;
return cs->bLength >= sizeof(*cs) && cs->bClockID == id &&
cs->bLength == 11 + cs->bNrInPins;
return cs->bClockID == id;
}

static bool validate_clock_multiplier_v2(void *p, int id)
{
struct uac_clock_multiplier_descriptor *cs = p;
return cs->bLength == sizeof(*cs) && cs->bClockID == id;
return cs->bClockID == id;
}

static bool validate_clock_multiplier_v3(void *p, int id)
{
struct uac3_clock_multiplier_descriptor *cs = p;
return cs->bLength == sizeof(*cs) && cs->bClockID == id;
return cs->bClockID == id;
}

#define DEFINE_FIND_HELPER(name, obj, validator, type) \
Expand Down
84 changes: 0 additions & 84 deletions sound/usb/mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,13 +740,6 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
{
int mu_channels;

if (desc->bLength < sizeof(*desc))
return -EINVAL;
if (!desc->bNrInPins)
return -EINVAL;
if (desc->bLength < sizeof(*desc) + desc->bNrInPins)
return -EINVAL;

switch (state->mixer->protocol) {
case UAC_VERSION_1:
case UAC_VERSION_2:
Expand Down Expand Up @@ -1781,13 +1774,6 @@ static int parse_clock_source_unit(struct mixer_build *state, int unitid,
if (state->mixer->protocol != UAC_VERSION_2)
return -EINVAL;

if (hdr->bLength != sizeof(*hdr)) {
usb_audio_dbg(state->chip,
"Bogus clock source descriptor length of %d, ignoring.\n",
hdr->bLength);
return 0;
}

/*
* The only property of this unit we are interested in is the
* clock source validity. If that isn't readable, just bail out.
Expand Down Expand Up @@ -1846,62 +1832,20 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
__u8 *bmaControls;

if (state->mixer->protocol == UAC_VERSION_1) {
if (hdr->bLength < 7) {
usb_audio_err(state->chip,
"unit %u: invalid UAC_FEATURE_UNIT descriptor\n",
unitid);
return -EINVAL;
}
csize = hdr->bControlSize;
if (!csize) {
usb_audio_dbg(state->chip,
"unit %u: invalid bControlSize == 0\n",
unitid);
return -EINVAL;
}
channels = (hdr->bLength - 7) / csize - 1;
bmaControls = hdr->bmaControls;
if (hdr->bLength < 7 + csize) {
usb_audio_err(state->chip,
"unit %u: invalid UAC_FEATURE_UNIT descriptor\n",
unitid);
return -EINVAL;
}
} else if (state->mixer->protocol == UAC_VERSION_2) {
struct uac2_feature_unit_descriptor *ftr = _ftr;
if (hdr->bLength < 6) {
usb_audio_err(state->chip,
"unit %u: invalid UAC_FEATURE_UNIT descriptor\n",
unitid);
return -EINVAL;
}
csize = 4;
channels = (hdr->bLength - 6) / 4 - 1;
bmaControls = ftr->bmaControls;
if (hdr->bLength < 6 + csize) {
usb_audio_err(state->chip,
"unit %u: invalid UAC_FEATURE_UNIT descriptor\n",
unitid);
return -EINVAL;
}
} else { /* UAC_VERSION_3 */
struct uac3_feature_unit_descriptor *ftr = _ftr;

if (hdr->bLength < 7) {
usb_audio_err(state->chip,
"unit %u: invalid UAC3_FEATURE_UNIT descriptor\n",
unitid);
return -EINVAL;
}
csize = 4;
channels = (ftr->bLength - 7) / 4 - 1;
bmaControls = ftr->bmaControls;
if (hdr->bLength < 7 + csize) {
usb_audio_err(state->chip,
"unit %u: invalid UAC3_FEATURE_UNIT descriptor\n",
unitid);
return -EINVAL;
}
}

/* parse the source unit */
Expand Down Expand Up @@ -2101,15 +2045,11 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid,

if (state->mixer->protocol == UAC_VERSION_2) {
struct uac2_input_terminal_descriptor *d_v2 = raw_desc;
if (d_v2->bLength < sizeof(*d_v2))
return -EINVAL;
control = UAC2_TE_CONNECTOR;
term_id = d_v2->bTerminalID;
bmctls = le16_to_cpu(d_v2->bmControls);
} else if (state->mixer->protocol == UAC_VERSION_3) {
struct uac3_input_terminal_descriptor *d_v3 = raw_desc;
if (d_v3->bLength < sizeof(*d_v3))
return -EINVAL;
control = UAC3_TE_INSERTION;
term_id = d_v3->bTerminalID;
bmctls = le32_to_cpu(d_v3->bmControls);
Expand Down Expand Up @@ -2371,18 +2311,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid,
const char *name = extension_unit ?
"Extension Unit" : "Processing Unit";

if (desc->bLength < 13) {
usb_audio_err(state->chip, "invalid %s descriptor (id %d)\n", name, unitid);
return -EINVAL;
}

num_ins = desc->bNrInPins;
if (desc->bLength < 13 + num_ins ||
desc->bLength < num_ins + uac_processing_unit_bControlSize(desc, state->mixer->protocol)) {
usb_audio_err(state->chip, "invalid %s descriptor (id %d)\n", name, unitid);
return -EINVAL;
}

for (i = 0; i < num_ins; i++) {
err = parse_audio_unit(state, desc->baSourceID[i]);
if (err < 0)
Expand Down Expand Up @@ -2637,13 +2566,6 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
const struct usbmix_name_map *map;
char **namelist;

if (desc->bLength < 5 || !desc->bNrInPins ||
desc->bLength < 5 + desc->bNrInPins) {
usb_audio_err(state->chip,
"invalid SELECTOR UNIT descriptor %d\n", unitid);
return -EINVAL;
}

for (i = 0; i < desc->bNrInPins; i++) {
err = parse_audio_unit(state, desc->baSourceID[i]);
if (err < 0)
Expand Down Expand Up @@ -3149,8 +3071,6 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if (mixer->protocol == UAC_VERSION_1) {
struct uac1_output_terminal_descriptor *desc = p;

if (desc->bLength < sizeof(*desc))
continue; /* invalid descriptor? */
/* mark terminal ID as visited */
set_bit(desc->bTerminalID, state.unitbitmap);
state.oterm.id = desc->bTerminalID;
Expand All @@ -3162,8 +3082,6 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
} else if (mixer->protocol == UAC_VERSION_2) {
struct uac2_output_terminal_descriptor *desc = p;

if (desc->bLength < sizeof(*desc))
continue; /* invalid descriptor? */
/* mark terminal ID as visited */
set_bit(desc->bTerminalID, state.unitbitmap);
state.oterm.id = desc->bTerminalID;
Expand All @@ -3189,8 +3107,6 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
} else { /* UAC_VERSION_3 */
struct uac3_output_terminal_descriptor *desc = p;

if (desc->bLength < sizeof(*desc))
continue; /* invalid descriptor? */
/* mark terminal ID as visited */
set_bit(desc->bTerminalID, state.unitbitmap);
state.oterm.id = desc->bTerminalID;
Expand Down

0 comments on commit b8e4f1f

Please sign in to comment.