From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Dmitry Vyukov <dvyukov@google.com>,
Takashi Iwai <tiwai@suse.de>
Subject: [PATCH 3.14 42/76] ALSA: seq: Fix yet another races among ALSA timer accesses
Date: Sun, 14 Feb 2016 14:23:09 -0800 [thread overview]
Message-ID: <20160214222220.398269630@linuxfoundation.org> (raw)
In-Reply-To: <20160214222218.658495779@linuxfoundation.org>
3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
commit 2cdc7b636d55cbcf42e1e6c8accd85e62d3e9ae8 upstream.
ALSA sequencer may open/close and control ALSA timer instance
dynamically either via sequencer events or direct ioctls. These are
done mostly asynchronously, and it may call still some timer action
like snd_timer_start() while another is calling snd_timer_close().
Since the instance gets removed by snd_timer_close(), it may lead to
a use-after-free.
This patch tries to address such a race by protecting each
snd_timer_*() call via the existing spinlock and also by avoiding the
access to timer during close call.
BugLink: http://lkml.kernel.org/r/CACT4Y+Z6RzW5MBr-HUdV-8zwg71WQfKTdPpYGvOeS7v4cyurNQ@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/seq/seq_timer.c | 87 ++++++++++++++++++++++++++++++++++-----------
1 file changed, 67 insertions(+), 20 deletions(-)
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -92,6 +92,9 @@ void snd_seq_timer_delete(struct snd_seq
void snd_seq_timer_defaults(struct snd_seq_timer * tmr)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&tmr->lock, flags);
/* setup defaults */
tmr->ppq = 96; /* 96 PPQ */
tmr->tempo = 500000; /* 120 BPM */
@@ -107,21 +110,25 @@ void snd_seq_timer_defaults(struct snd_s
tmr->preferred_resolution = seq_default_timer_resolution;
tmr->skew = tmr->skew_base = SKEW_BASE;
+ spin_unlock_irqrestore(&tmr->lock, flags);
}
-void snd_seq_timer_reset(struct snd_seq_timer * tmr)
+static void seq_timer_reset(struct snd_seq_timer *tmr)
{
- unsigned long flags;
-
- spin_lock_irqsave(&tmr->lock, flags);
-
/* reset time & songposition */
tmr->cur_time.tv_sec = 0;
tmr->cur_time.tv_nsec = 0;
tmr->tick.cur_tick = 0;
tmr->tick.fraction = 0;
+}
+
+void snd_seq_timer_reset(struct snd_seq_timer *tmr)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&tmr->lock, flags);
+ seq_timer_reset(tmr);
spin_unlock_irqrestore(&tmr->lock, flags);
}
@@ -140,8 +147,11 @@ static void snd_seq_timer_interrupt(stru
tmr = q->timer;
if (tmr == NULL)
return;
- if (!tmr->running)
+ spin_lock_irqsave(&tmr->lock, flags);
+ if (!tmr->running) {
+ spin_unlock_irqrestore(&tmr->lock, flags);
return;
+ }
resolution *= ticks;
if (tmr->skew != tmr->skew_base) {
@@ -150,8 +160,6 @@ static void snd_seq_timer_interrupt(stru
(((resolution & 0xffff) * tmr->skew) >> 16);
}
- spin_lock_irqsave(&tmr->lock, flags);
-
/* update timer */
snd_seq_inc_time_nsec(&tmr->cur_time, resolution);
@@ -298,26 +306,30 @@ int snd_seq_timer_open(struct snd_seq_qu
t->callback = snd_seq_timer_interrupt;
t->callback_data = q;
t->flags |= SNDRV_TIMER_IFLG_AUTO;
+ spin_lock_irq(&tmr->lock);
tmr->timeri = t;
+ spin_unlock_irq(&tmr->lock);
return 0;
}
int snd_seq_timer_close(struct snd_seq_queue *q)
{
struct snd_seq_timer *tmr;
+ struct snd_timer_instance *t;
tmr = q->timer;
if (snd_BUG_ON(!tmr))
return -EINVAL;
- if (tmr->timeri) {
- snd_timer_stop(tmr->timeri);
- snd_timer_close(tmr->timeri);
- tmr->timeri = NULL;
- }
+ spin_lock_irq(&tmr->lock);
+ t = tmr->timeri;
+ tmr->timeri = NULL;
+ spin_unlock_irq(&tmr->lock);
+ if (t)
+ snd_timer_close(t);
return 0;
}
-int snd_seq_timer_stop(struct snd_seq_timer * tmr)
+static int seq_timer_stop(struct snd_seq_timer *tmr)
{
if (! tmr->timeri)
return -EINVAL;
@@ -328,6 +340,17 @@ int snd_seq_timer_stop(struct snd_seq_ti
return 0;
}
+int snd_seq_timer_stop(struct snd_seq_timer *tmr)
+{
+ unsigned long flags;
+ int err;
+
+ spin_lock_irqsave(&tmr->lock, flags);
+ err = seq_timer_stop(tmr);
+ spin_unlock_irqrestore(&tmr->lock, flags);
+ return err;
+}
+
static int initialize_timer(struct snd_seq_timer *tmr)
{
struct snd_timer *t;
@@ -360,13 +383,13 @@ static int initialize_timer(struct snd_s
return 0;
}
-int snd_seq_timer_start(struct snd_seq_timer * tmr)
+static int seq_timer_start(struct snd_seq_timer *tmr)
{
if (! tmr->timeri)
return -EINVAL;
if (tmr->running)
- snd_seq_timer_stop(tmr);
- snd_seq_timer_reset(tmr);
+ seq_timer_stop(tmr);
+ seq_timer_reset(tmr);
if (initialize_timer(tmr) < 0)
return -EINVAL;
snd_timer_start(tmr->timeri, tmr->ticks);
@@ -375,14 +398,25 @@ int snd_seq_timer_start(struct snd_seq_t
return 0;
}
-int snd_seq_timer_continue(struct snd_seq_timer * tmr)
+int snd_seq_timer_start(struct snd_seq_timer *tmr)
+{
+ unsigned long flags;
+ int err;
+
+ spin_lock_irqsave(&tmr->lock, flags);
+ err = seq_timer_start(tmr);
+ spin_unlock_irqrestore(&tmr->lock, flags);
+ return err;
+}
+
+static int seq_timer_continue(struct snd_seq_timer *tmr)
{
if (! tmr->timeri)
return -EINVAL;
if (tmr->running)
return -EBUSY;
if (! tmr->initialized) {
- snd_seq_timer_reset(tmr);
+ seq_timer_reset(tmr);
if (initialize_timer(tmr) < 0)
return -EINVAL;
}
@@ -392,11 +426,24 @@ int snd_seq_timer_continue(struct snd_se
return 0;
}
+int snd_seq_timer_continue(struct snd_seq_timer *tmr)
+{
+ unsigned long flags;
+ int err;
+
+ spin_lock_irqsave(&tmr->lock, flags);
+ err = seq_timer_continue(tmr);
+ spin_unlock_irqrestore(&tmr->lock, flags);
+ return err;
+}
+
/* return current 'real' time. use timeofday() to get better granularity. */
snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
{
snd_seq_real_time_t cur_time;
+ unsigned long flags;
+ spin_lock_irqsave(&tmr->lock, flags);
cur_time = tmr->cur_time;
if (tmr->running) {
struct timeval tm;
@@ -412,7 +459,7 @@ snd_seq_real_time_t snd_seq_timer_get_cu
}
snd_seq_sanity_real_time(&cur_time);
}
-
+ spin_unlock_irqrestore(&tmr->lock, flags);
return cur_time;
}
next prev parent reply other threads:[~2016-02-14 23:24 UTC|newest]
Thread overview: 81+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-14 22:22 [PATCH 3.14 00/76] 3.14.61-stable review Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 01/76] xhci: fix placement of call to usb_disabled() Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 02/76] recordmcount: Fix endianness handling bug for nop_mcount Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 03/76] crypto: algif_hash - Only export and import on sockets with data Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 04/76] dm btree: fix leak of bufio-backed block in btree_split_sibling error path Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 05/76] drivers/base/memory.c: prohibit offlining of memory blocks with missing sections Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 06/76] HID: usbhid: fix recursive deadlock Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 07/76] proc: actually make proc_fd_permission() thread-friendly Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 08/76] remoteproc: avoid stack overflow in debugfs file Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 09/76] fat: fix fake_offset handling on error path Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 10/76] kernel/signal.c: unexport sigsuspend() Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 11/76] ocfs2: fix SGID not inherited issue Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 12/76] ocfs2/dlm: ignore cleaning the migration mle that is inuse Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 13/76] ocfs2/dlm: clear refmap bit of recovery lock while doing local recovery cleanup Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 14/76] sh64: fix __NR_fgetxattr Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 15/76] Revert "dm mpath: fix stalls when handling invalid ioctls" Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 16/76] spi: atmel: Fix DMA-setup for transfers with more than 8 bits per word Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 17/76] spi: ti-qspi: Fix data corruption seen on r/w stress test Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 18/76] spi: fix parent-device reference leak Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 19/76] wlcore/wl12xx: spi: fix oops on firmware load Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 20/76] wlcore/wl12xx: spi: fix NULL pointer dereference (Oops) Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 21/76] vTPM: fix memory allocation flag for rtce buffer at kernel boot Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 22/76] mtd: mtdpart: fix add_mtd_partitions error path Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 23/76] PCI: Fix minimum allocation address overwrite Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 24/76] tracing: Fix setting of start_index in find_next() Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 25/76] jbd2: Fix unreclaimed pages after truncate in data=journal mode Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 26/76] [PATCH] fix calculation of meta_bg descriptor backups Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 27/76] parisc: Drop unused MADV_xxxK_PAGES flags from asm/mman.h Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 28/76] parisc: Fix syscall restarts Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 29/76] parisc: Fix __ARCH_SI_PREAMBLE_SIZE Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 30/76] [media] v4l2-compat-ioctl32: fix alignment for ARM64 Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 31/76] [media] media: vb2 dma-contig: Fully cache synchronise buffers in prepare and finish Greg Kroah-Hartman
2016-02-14 22:22 ` [PATCH 3.14 32/76] fix sysvfs symlinks Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 33/76] ALSA: usb-audio: Fix TEAC UD-501/UD-503/NT-503 usb delay Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 34/76] ALSA: usb-audio: avoid freeing umidi object twice Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 35/76] ALSA: compress: Disable GET_CODEC_CAPS ioctl for some architectures Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 36/76] ALSA: dummy: Disable switching timer backend via sysfs Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 37/76] ALSA: seq: Fix incorrect sanity check at snd_seq_oss_synth_cleanup() Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 38/76] ALSA: rawmidi: Remove kernel WARNING for NULL user-space buffer check Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 39/76] ALSA: rawmidi: Fix race at copying & updating the position Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 40/76] ALSA: pcm: Fix potential deadlock in OSS emulation Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 41/76] ASoC: dpcm: fix the BE state on hw_free Greg Kroah-Hartman
2016-02-14 22:23 ` Greg Kroah-Hartman [this message]
2016-02-14 22:23 ` [PATCH 3.14 43/76] ALSA: seq: Fix race at closing in virmidi driver Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 44/76] ALSA: seq: Fix lockdep warnings due to double mutex locks Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 45/76] ALSA: timer: Code cleanup Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 46/76] ALSA: timer: Fix leftover link at closing Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 47/76] ALSA: timer: Fix link corruption due to double start or stop Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 48/76] ALSA: timer: Fix wrong instance passed to slave callbacks Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 49/76] ALSA: timer: Fix race between stop and interrupt Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 50/76] ALSA: hda - Add fixup for Mac Mini 7,1 model Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 51/76] ALSA: hda - Fix static checker warning in patch_hdmi.c Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 52/76] ALSA: hda - Fix speaker output from VAIO AiO machines Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 53/76] ALSA: dummy: Implement timer backend switching more safely Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 54/76] [media] saa7134-alsa: Only frees registered sound cards Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 55/76] USB: serial: visor: fix crash on detecting device without write_urbs Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 56/76] USB: visor: fix null-deref at probe Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 57/76] usb: hub: do not clear BOS field during reset device Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 58/76] USB: serial: ftdi_sio: add support for Yaesu SCU-18 cable Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 59/76] USB: cp210x: add ID for IAI USB to RS485 adaptor Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 60/76] USB: serial: option: Adding support for Telit LE922 Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 61/76] USB: option: fix Cinterion AHxx enumeration Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 62/76] tty: Fix GPF in flush_to_ldisc() Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 63/76] tty: Fix unsafe ldisc reference via ioctl(TIOCGETD) Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 64/76] xhci: fix usb2 resume timing and races Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 65/76] ext4: Fix handling of extended tv_sec Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 66/76] crypto: af_alg - Disallow bind/setkey/... after accept(2) Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 67/76] crypto: af_alg - Fix socket double-free when accept fails Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 68/76] AHCI: Fix softreset failed issue of Port Multiplier Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 69/76] libata: disable forced PORTS_IMPL for >= AHCI 1.3 Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 70/76] ahci: Intel DNV device IDs SATA Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 71/76] crypto: algif_hash - wait for crypto_ahash_init() to complete Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 72/76] EVM: Use crypto_memneq() for digest comparisons Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 73/76] crypto: user - lock crypto_alg_list on alg dump Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 74/76] FS-Cache: Increase reference of parent after registering, netfs success Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 75/76] FS-Cache: Dont override netfss primary_index if registering failed Greg Kroah-Hartman
2016-02-14 22:23 ` [PATCH 3.14 76/76] binfmt_elf: Dont clobber passed executables file header Greg Kroah-Hartman
2016-02-15 15:47 ` [PATCH 3.14 00/76] 3.14.61-stable review Guenter Roeck
2016-02-17 20:39 ` Greg Kroah-Hartman
2016-02-15 17:07 ` Shuah Khan
2016-02-17 20:38 ` Greg Kroah-Hartman
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=20160214222220.398269630@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=dvyukov@google.com \
--cc=linux-kernel@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;
as well as URLs for NNTP newsgroup(s).