Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 071d65da authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ALSA: usb-audio: Check out-of-bounds access by corrupted buffer descriptor"

parents 55a70891 2350901b
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -221,6 +221,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
	struct usb_interface *usb_iface;
	void *control_header;
	int i, protocol;
	int rest_bytes;

	usb_iface = usb_ifnum_to_if(dev, ctrlif);
	if (!usb_iface) {
@@ -247,6 +248,15 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
		return -EINVAL;
	}

	rest_bytes = (void *)(host_iface->extra + host_iface->extralen) -
		control_header;

	/* just to be sure -- this shouldn't hit at all */
	if (rest_bytes <= 0) {
		dev_err(&dev->dev, "invalid control header\n");
		return -EINVAL;
	}

	switch (protocol) {
	default:
		dev_warn(&dev->dev,
@@ -257,11 +267,21 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
	case UAC_VERSION_1: {
		struct uac1_ac_header_descriptor *h1 = control_header;

		if (rest_bytes < sizeof(*h1)) {
			dev_err(&dev->dev, "too short v1 buffer descriptor\n");
			return -EINVAL;
		}

		if (!h1->bInCollection) {
			dev_info(&dev->dev, "skipping empty audio interface (v1)\n");
			return -EINVAL;
		}

		if (rest_bytes < h1->bLength) {
			dev_err(&dev->dev, "invalid buffer length (v1)\n");
			return -EINVAL;
		}

		if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
			dev_err(&dev->dev, "invalid UAC_HEADER (v1)\n");
			return -EINVAL;