lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
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

Powered by Openwall GNU/*/Linux Powered by OpenVZ