Skip to content

{ciqlts9_2} ALSA: usb-audio: Fix out of bounds reads when finding clock sources #241

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 2, 2025
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
24 changes: 23 additions & 1 deletion sound/usb/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ union uac23_clock_multiplier_desc {
struct uac_clock_multiplier_descriptor v3;
};

/* check whether the descriptor bLength has the minimal length */
#define DESC_LENGTH_CHECK(p, proto) \
((proto) == UAC_VERSION_3 ? \
((p)->v3.bLength >= sizeof((p)->v3)) : \
((p)->v2.bLength >= sizeof((p)->v2)))

#define GET_VAL(p, proto, field) \
((proto) == UAC_VERSION_3 ? (p)->v3.field : (p)->v2.field)

Expand All @@ -58,20 +64,36 @@ static bool validate_clock_source(void *p, int id, int proto)
{
union uac23_clock_source_desc *cs = p;

if (!DESC_LENGTH_CHECK(cs, proto))
return false;
return GET_VAL(cs, proto, bClockID) == id;
}

static bool validate_clock_selector(void *p, int id, int proto)
{
union uac23_clock_selector_desc *cs = p;

return GET_VAL(cs, proto, bClockID) == id;
if (!DESC_LENGTH_CHECK(cs, proto))
return false;
if (GET_VAL(cs, proto, bClockID) != id)
return false;
/* additional length check for baCSourceID array (in bNrInPins size)
* and two more fields (which sizes depend on the protocol)
*/
if (proto == UAC_VERSION_3)
return cs->v3.bLength >= sizeof(cs->v3) + cs->v3.bNrInPins +
4 /* bmControls */ + 2 /* wCSelectorDescrStr */;
else
return cs->v2.bLength >= sizeof(cs->v2) + cs->v2.bNrInPins +
1 /* bmControls */ + 1 /* iClockSelector */;
}

static bool validate_clock_multiplier(void *p, int id, int proto)
{
union uac23_clock_multiplier_desc *cs = p;

if (!DESC_LENGTH_CHECK(cs, proto))
return false;
return GET_VAL(cs, proto, bClockID) == id;
}

Expand Down