From: Greg Kroah-Hartman Date: Mon, 1 Apr 2024 08:36:36 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v6.7.12~84 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d14c5834bcceed1fd69e4f7cd8184cffb6a63e7b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: alsa-sh-aica-reorder-cleanup-operations-to-avoid-uaf-bugs.patch --- diff --git a/queue-5.4/alsa-sh-aica-reorder-cleanup-operations-to-avoid-uaf-bugs.patch b/queue-5.4/alsa-sh-aica-reorder-cleanup-operations-to-avoid-uaf-bugs.patch new file mode 100644 index 00000000000..7b19df40310 --- /dev/null +++ b/queue-5.4/alsa-sh-aica-reorder-cleanup-operations-to-avoid-uaf-bugs.patch @@ -0,0 +1,95 @@ +From 051e0840ffa8ab25554d6b14b62c9ab9e4901457 Mon Sep 17 00:00:00 2001 +From: Duoming Zhou +Date: Tue, 26 Mar 2024 17:42:38 +0800 +Subject: ALSA: sh: aica: reorder cleanup operations to avoid UAF bugs + +From: Duoming Zhou + +commit 051e0840ffa8ab25554d6b14b62c9ab9e4901457 upstream. + +The dreamcastcard->timer could schedule the spu_dma_work and the +spu_dma_work could also arm the dreamcastcard->timer. + +When the snd_pcm_substream is closing, the aica_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 and other possible corner cases, +call mod_timer() conditionally in run_spu_dma(), then implement +PCM sync_stop op to cancel both the timer and worker. The sync_stop +op will be called from PCM core appropriately when needed. + +Fixes: 198de43d758c ("[ALSA] Add ALSA support for the SEGA Dreamcast PCM device") +Suggested-by: Takashi Iwai +Signed-off-by: Duoming Zhou +Message-ID: <20240326094238.95442-1-duoming@zju.edu.cn> +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/sh/aica.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +--- a/sound/sh/aica.c ++++ b/sound/sh/aica.c +@@ -279,7 +279,8 @@ static void run_spu_dma(struct work_stru + dreamcastcard->clicks++; + if (unlikely(dreamcastcard->clicks >= AICA_PERIOD_NUMBER)) + dreamcastcard->clicks %= AICA_PERIOD_NUMBER; +- mod_timer(&dreamcastcard->timer, jiffies + 1); ++ if (snd_pcm_running(dreamcastcard->substream)) ++ mod_timer(&dreamcastcard->timer, jiffies + 1); + } + } + +@@ -291,6 +292,8 @@ static void aica_period_elapsed(struct t + /*timer function - so cannot sleep */ + int play_period; + struct snd_pcm_runtime *runtime; ++ if (!snd_pcm_running(substream)) ++ return; + runtime = substream->runtime; + dreamcastcard = substream->pcm->private_data; + /* Have we played out an additional period? */ +@@ -351,12 +354,19 @@ static int snd_aicapcm_pcm_open(struct s + return 0; + } + ++static int snd_aicapcm_pcm_sync_stop(struct snd_pcm_substream *substream) ++{ ++ struct snd_card_aica *dreamcastcard = substream->pcm->private_data; ++ ++ del_timer_sync(&dreamcastcard->timer); ++ cancel_work_sync(&dreamcastcard->spu_dma_work); ++ return 0; ++} ++ + static int snd_aicapcm_pcm_close(struct snd_pcm_substream + *substream) + { + struct snd_card_aica *dreamcastcard = substream->pcm->private_data; +- flush_work(&(dreamcastcard->spu_dma_work)); +- del_timer(&dreamcastcard->timer); + dreamcastcard->substream = NULL; + kfree(dreamcastcard->channel); + spu_disable(); +@@ -422,6 +432,7 @@ static const struct snd_pcm_ops snd_aica + .prepare = snd_aicapcm_pcm_prepare, + .trigger = snd_aicapcm_pcm_trigger, + .pointer = snd_aicapcm_pcm_pointer, ++ .sync_stop = snd_aicapcm_pcm_sync_stop, + }; + + /* TO DO: set up to handle more than one pcm instance */ diff --git a/queue-5.4/series b/queue-5.4/series index 4a6a8624c14..a7f2dddfe88 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -115,3 +115,4 @@ exec-fix-nommu-linux_binprm-exec-in-transfer_args_to_stack.patch mmc-core-initialize-mmc_blk_ioc_data.patch mmc-core-avoid-negative-index-with-array-access.patch usb-cdc-wdm-close-race-between-read-and-workqueue.patch +alsa-sh-aica-reorder-cleanup-operations-to-avoid-uaf-bugs.patch