[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240325033946.47052-1-duoming@zju.edu.cn>
Date: Mon, 25 Mar 2024 11:39:46 +0800
From: Duoming Zhou <duoming@....edu.cn>
To: linux-sound@...r.kernel.org
Cc: linux-kernel@...r.kernel.org,
tiwai@...e.com,
perex@...ex.cz,
Duoming Zhou <duoming@....edu.cn>
Subject: [PATCH] ALSA: sh: aica: reorder cleanup operations to avoid UAF bug
The dreamcastcard->timer could schedule the spu_dma_work and the
spu_dma_work could also arm the dreamcastcard->timer.
When the Yamaha AICA card is closing, the dreamcastcard->channel
will be deallocated. But it could still be dereferenced in the
worker thread. The reason is that del_timer() will return directly
regardless of whether the timer handler is running or not and the
worker could be rescheduled in the timer handler. As a result, the
UAF bug will happen. The racy situation is shown below:
(Thread 1) | (Thread 2)
snd_aicapcm_pcm_close() |
... | run_spu_dma() //worker
| mod_timer()
flush_work() |
del_timer() | aica_period_elapsed() //timer
kfree(dreamcastcard->channel) | schedule_work()
| run_spu_dma() //worker
... | dreamcastcard->channel-> //USE
In order to mitigate this bug, use timer_shutdown_sync() to shutdown
the timer and then use flush_work() to cancel the worker.
Fixes: 198de43d758c ("[ALSA] Add ALSA support for the SEGA Dreamcast PCM device")
Signed-off-by: Duoming Zhou <duoming@....edu.cn>
---
sound/sh/aica.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 320ac792c7f..bc68a3903f2 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -354,8 +354,8 @@ static int snd_aicapcm_pcm_close(struct snd_pcm_substream
*substream)
{
struct snd_card_aica *dreamcastcard = substream->pcm->private_data;
+ timer_shutdown_sync(&dreamcastcard->timer);
flush_work(&(dreamcastcard->spu_dma_work));
- del_timer(&dreamcastcard->timer);
dreamcastcard->substream = NULL;
kfree(dreamcastcard->channel);
spu_disable();
--
2.17.1
Powered by blists - more mailing lists