From: <gregkh@linuxfoundation.org>
To: tiwai@suse.de, dvyukov@google.com, gregkh@linuxfoundation.org
Cc: <stable@vger.kernel.org>, <stable-commits@vger.kernel.org>
Subject: Patch "ALSA: timer: Fix link corruption due to double start or stop" has been added to the 3.14-stable tree
Date: Sun, 14 Feb 2016 11:45:59 -0800 [thread overview]
Message-ID: <1455479159216190@kroah.com> (raw)
This is a note to let you know that I've just added the patch titled
ALSA: timer: Fix link corruption due to double start or stop
to the 3.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch
and it can be found in the queue-3.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.
>From f784beb75ce82f4136f8a0960d3ee872f7109e09 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Sat, 30 Jan 2016 23:09:08 +0100
Subject: ALSA: timer: Fix link corruption due to double start or stop
From: Takashi Iwai <tiwai@suse.de>
commit f784beb75ce82f4136f8a0960d3ee872f7109e09 upstream.
Although ALSA timer code got hardening for races, it still causes
use-after-free error. This is however rather a corrupted linked list,
not actually the concurrent accesses. Namely, when timer start is
triggered twice, list_add_tail() is called twice, too. This ends
up with the link corruption and triggers KASAN error.
The simplest fix would be replacing list_add_tail() with
list_move_tail(), but fundamentally it's the problem that we don't
check the double start/stop correctly. So, the right fix here is to
add the proper checks to snd_timer_start() and snd_timer_stop() (and
their variants).
BugLink: http://lkml.kernel.org/r/CACT4Y+ZyPRoMQjmawbvmCEDrkBD2BQuH7R09=eOkf5ESK8kJAw@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/core/timer.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -444,6 +444,10 @@ static int snd_timer_start_slave(struct
unsigned long flags;
spin_lock_irqsave(&slave_active_lock, flags);
+ if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
+ spin_unlock_irqrestore(&slave_active_lock, flags);
+ return -EBUSY;
+ }
timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
if (timeri->master && timeri->timer) {
spin_lock(&timeri->timer->lock);
@@ -468,18 +472,26 @@ int snd_timer_start(struct snd_timer_ins
return -EINVAL;
if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
result = snd_timer_start_slave(timeri);
- snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
+ if (result >= 0)
+ snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
return result;
}
timer = timeri->timer;
if (timer == NULL)
return -EINVAL;
spin_lock_irqsave(&timer->lock, flags);
+ if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
+ SNDRV_TIMER_IFLG_START)) {
+ result = -EBUSY;
+ goto unlock;
+ }
timeri->ticks = timeri->cticks = ticks;
timeri->pticks = 0;
result = snd_timer_start1(timer, timeri, ticks);
+ unlock:
spin_unlock_irqrestore(&timer->lock, flags);
- snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
+ if (result >= 0)
+ snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
return result;
}
@@ -495,6 +507,10 @@ static int _snd_timer_stop(struct snd_ti
if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
if (!keep_flag) {
spin_lock_irqsave(&slave_active_lock, flags);
+ if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) {
+ spin_unlock_irqrestore(&slave_active_lock, flags);
+ return -EBUSY;
+ }
timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
list_del_init(&timeri->ack_list);
list_del_init(&timeri->active_list);
@@ -506,6 +522,11 @@ static int _snd_timer_stop(struct snd_ti
if (!timer)
return -EINVAL;
spin_lock_irqsave(&timer->lock, flags);
+ if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
+ SNDRV_TIMER_IFLG_START))) {
+ spin_unlock_irqrestore(&timer->lock, flags);
+ return -EBUSY;
+ }
list_del_init(&timeri->ack_list);
list_del_init(&timeri->active_list);
if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&
@@ -571,10 +592,15 @@ int snd_timer_continue(struct snd_timer_
if (! timer)
return -EINVAL;
spin_lock_irqsave(&timer->lock, flags);
+ if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
+ result = -EBUSY;
+ goto unlock;
+ }
if (!timeri->cticks)
timeri->cticks = 1;
timeri->pticks = 0;
result = snd_timer_start1(timer, timeri, timer->sticks);
+ unlock:
spin_unlock_irqrestore(&timer->lock, flags);
snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE);
return result;
Patches currently in stable-queue which might be from tiwai@suse.de are
queue-3.14/alsa-seq-fix-race-at-closing-in-virmidi-driver.patch
queue-3.14/alsa-rawmidi-remove-kernel-warning-for-null-user-space-buffer-check.patch
queue-3.14/alsa-hda-fix-static-checker-warning-in-patch_hdmi.c.patch
queue-3.14/alsa-seq-fix-lockdep-warnings-due-to-double-mutex-locks.patch
queue-3.14/alsa-usb-audio-fix-teac-ud-501-ud-503-nt-503-usb-delay.patch
queue-3.14/alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch
queue-3.14/alsa-compress-disable-get_codec_caps-ioctl-for-some-architectures.patch
queue-3.14/alsa-hda-fix-speaker-output-from-vaio-aio-machines.patch
queue-3.14/alsa-dummy-implement-timer-backend-switching-more-safely.patch
queue-3.14/alsa-dummy-disable-switching-timer-backend-via-sysfs.patch
queue-3.14/alsa-seq-fix-incorrect-sanity-check-at-snd_seq_oss_synth_cleanup.patch
queue-3.14/alsa-seq-fix-yet-another-races-among-alsa-timer-accesses.patch
queue-3.14/alsa-usb-audio-avoid-freeing-umidi-object-twice.patch
queue-3.14/alsa-hda-add-fixup-for-mac-mini-7-1-model.patch
queue-3.14/alsa-timer-fix-leftover-link-at-closing.patch
queue-3.14/alsa-rawmidi-fix-race-at-copying-updating-the-position.patch
queue-3.14/alsa-pcm-fix-potential-deadlock-in-oss-emulation.patch
queue-3.14/alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch
reply other threads:[~2016-02-14 19:46 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1455479159216190@kroah.com \
--to=gregkh@linuxfoundation.org \
--cc=dvyukov@google.com \
--cc=stable-commits@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=tiwai@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox