Commit b53a41ee authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: compress: Don't embed device



Embedding the struct device to snd_compr object may result in UAF when
the delayed kobj release is used.  Like other devices, let's detach
the struct device from the snd_compr by allocating dynamically via
snd_device_alloc().

Reviewed-by: default avatarJaroslav Kysela <perex@perex.cz>
Signed-off-by: default avatarCurtis Malainey <cujomalainey@chromium.org>
Tested-by: default avatarCurtis Malainey <cujomalainey@chromium.org>
Link: https://lore.kernel.org/r/20230816160252.23396-7-tiwai@suse.de


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent ea29a02f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -148,7 +148,7 @@ struct snd_compr_ops {
 */
struct snd_compr {
	const char *name;
	struct device dev;
	struct device *dev;
	struct snd_compr_ops *ops;
	void *private_data;
	struct snd_card *card;
+10 −6
Original line number Diff line number Diff line
@@ -546,7 +546,7 @@ static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
		if (stream->runtime->dma_buffer_p) {

			if (buffer_size > stream->runtime->dma_buffer_p->bytes)
				dev_err(&stream->device->dev,
				dev_err(stream->device->dev,
						"Not enough DMA buffer");
			else
				buffer = stream->runtime->dma_buffer_p->area;
@@ -1070,7 +1070,7 @@ static int snd_compress_dev_register(struct snd_device *device)
	/* register compressed device */
	ret = snd_register_device(SNDRV_DEVICE_TYPE_COMPRESS,
				  compr->card, compr->device,
				  &snd_compr_file_ops, compr, &compr->dev);
				  &snd_compr_file_ops, compr, compr->dev);
	if (ret < 0) {
		pr_err("snd_register_device failed %d\n", ret);
		return ret;
@@ -1084,7 +1084,7 @@ static int snd_compress_dev_disconnect(struct snd_device *device)
	struct snd_compr *compr;

	compr = device->device_data;
	snd_unregister_device(&compr->dev);
	snd_unregister_device(compr->dev);
	return 0;
}

@@ -1158,7 +1158,7 @@ static int snd_compress_dev_free(struct snd_device *device)

	compr = device->device_data;
	snd_compress_proc_done(compr);
	put_device(&compr->dev);
	put_device(compr->dev);
	return 0;
}

@@ -1189,12 +1189,16 @@ int snd_compress_new(struct snd_card *card, int device,

	snd_compress_set_id(compr, id);

	snd_device_initialize(&compr->dev, card);
	dev_set_name(&compr->dev, "comprC%iD%i", card->number, device);
	ret = snd_device_alloc(&compr->dev, card);
	if (ret)
		return ret;
	dev_set_name(compr->dev, "comprC%iD%i", card->number, device);

	ret = snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops);
	if (ret == 0)
		snd_compress_proc_init(compr);
	else
		put_device(compr->dev);

	return ret;
}