Commit ff0316d3 authored by Takashi Iwai's avatar Takashi Iwai Committed by Lin Ruifeng
Browse files

ALSA: 6fire: Release resources at card release

stable inclusion
from stable-v5.10.231
commit f2d06d4e129e2508e356136f99bb20a332ff1a00
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBEAEC
CVE: CVE-2024-53239

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=f2d06d4e129e2508e356136f99bb20a332ff1a00



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

[ Upstream commit a0810c3d6dd2d29a9b92604d682eacd2902ce947 ]

The current 6fire code tries to release the resources right after the
call of usb6fire_chip_abort().  But at this moment, the card object
might be still in use (as we're calling snd_card_free_when_closed()).

For avoid potential UAFs, move the release of resources to the card's
private_free instead of the manual call of usb6fire_chip_destroy() at
the USB disconnect callback.

Fixes: c6d43ba8 ("ALSA: usb/6fire - Driver for TerraTec DMX 6Fire USB")
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20241113111042.15058-6-tiwai@suse.de


Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarLin Ruifeng <linruifeng4@huawei.com>
parent ed8467e7
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -62,8 +62,10 @@ static void usb6fire_chip_abort(struct sfire_chip *chip)
	}
}

static void usb6fire_chip_destroy(struct sfire_chip *chip)
static void usb6fire_card_free(struct snd_card *card)
{
	struct sfire_chip *chip = card->private_data;

	if (chip) {
		if (chip->pcm)
			usb6fire_pcm_destroy(chip);
@@ -73,8 +75,6 @@ static void usb6fire_chip_destroy(struct sfire_chip *chip)
			usb6fire_comm_destroy(chip);
		if (chip->control)
			usb6fire_control_destroy(chip);
		if (chip->card)
			snd_card_free(chip->card);
	}
}

@@ -137,6 +137,7 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
	chip->regidx = regidx;
	chip->intf_count = 1;
	chip->card = card;
	card->private_free = usb6fire_card_free;

	ret = usb6fire_comm_init(chip);
	if (ret < 0)
@@ -163,7 +164,7 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
	return 0;

destroy_chip:
	usb6fire_chip_destroy(chip);
	snd_card_free(card);
	return ret;
}

@@ -182,7 +183,6 @@ static void usb6fire_chip_disconnect(struct usb_interface *intf)

			chip->shutdown = true;
			usb6fire_chip_abort(chip);
			usb6fire_chip_destroy(chip);
		}
	}
}