From: Greg Kroah-Hartman Date: Mon, 1 Apr 2024 08:36:59 +0000 (+0200) Subject: 5.15-stable patches X-Git-Tag: v6.7.12~82 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ef13261cd60ba9fed777d2a17b2090842f4ae9f3;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: alsa-sh-aica-reorder-cleanup-operations-to-avoid-uaf-bugs.patch --- diff --git a/queue-5.15/alsa-sh-aica-reorder-cleanup-operations-to-avoid-uaf-bugs.patch b/queue-5.15/alsa-sh-aica-reorder-cleanup-operations-to-avoid-uaf-bugs.patch new file mode 100644 index 00000000000..9119274b670 --- /dev/null +++ b/queue-5.15/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 +@@ -278,7 +278,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); + } + } + +@@ -290,6 +291,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? */ +@@ -350,12 +353,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(); +@@ -401,6 +411,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.15/series b/queue-5.15/series index 44edb1c16e8..33d30737a37 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -578,3 +578,4 @@ drm-i915-gt-reset-queue_priority_hint-on-parking.patch usb-cdc-wdm-close-race-between-read-and-workqueue.patch drm-amdgpu-use-drm_mode_copy.patch drm-amd-display-preserve-original-aspect-ratio-in-cr.patch +alsa-sh-aica-reorder-cleanup-operations-to-avoid-uaf-bugs.patch