diff mbox series

[RFC,6/9] ALSA: compress: Don't embed device

Message ID 20230816160252.23396-7-tiwai@suse.de (mailing list archive)
State Accepted
Commit b53a41ee9c7281d961a29a3524bcaacfc9020dd5
Headers show
Series ALSA: Don't embed struct devices | expand

Commit Message

Takashi Iwai Aug. 16, 2023, 4:02 p.m. UTC
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().

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/sound/compress_driver.h |  2 +-
 sound/core/compress_offload.c   | 16 ++++++++++------
 2 files changed, 11 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h
index d91289c6f00e..bcf872c17dd3 100644
--- a/include/sound/compress_driver.h
+++ b/include/sound/compress_driver.h
@@ -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;
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index 30f73097447b..619371aa9964 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -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;
 }