From: Willy Tarreau <w@1wt.eu>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Dmitry Vyukov <dvyukov@google.com>, Takashi Iwai <tiwai@suse.de>,
Ben Hutchings <ben@decadent.org.uk>, Willy Tarreau <w@1wt.eu>
Subject: [PATCH 2.6.32 40/55] ALSA: pcm: Fix potential deadlock in OSS emulation
Date: Fri, 04 Mar 2016 16:30:40 +0100 [thread overview]
Message-ID: <20160304153002.462158072@1wt.eu> (raw)
In-Reply-To: <148ee355b419e9976ca727513a1405c8@local>
2.6.32-longterm review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
commit b248371628aad599a48540962f6b85a21a8a0c3f upstream.
There are potential deadlocks in PCM OSS emulation code while
accessing read/write and mmap concurrently. This comes from the
infamous mmap_sem usage in copy_from/to_user(). Namely,
snd_pcm_oss_write() ->
&runtime->oss.params_lock ->
copy_to_user() ->
&mm->mmap_sem
mmap() ->
&mm->mmap_sem ->
snd_pcm_oss_mmap() ->
&runtime->oss.params_lock
Since we can't avoid taking params_lock from mmap code path, use
trylock variant and aborts with -EAGAIN as a workaround of this AB/BA
deadlock.
BugLink: http://lkml.kernel.org/r/CACT4Y+bVrBKDG0G2_AcUgUQa+X91VKTeS4v+wN7BSHwHtqn3kQ@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Willy Tarreau <w@1wt.eu>
---
sound/core/oss/pcm_oss.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index d9c9635..07a249e 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -826,7 +826,8 @@ static int choose_rate(struct snd_pcm_substream *substream,
return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL);
}
-static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
+static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
+ bool trylock)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_pcm_hw_params *params, *sparams;
@@ -839,7 +840,10 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
struct snd_mask sformat_mask;
struct snd_mask mask;
- if (mutex_lock_interruptible(&runtime->oss.params_lock))
+ if (trylock) {
+ if (!(mutex_trylock(&runtime->oss.params_lock)))
+ return -EAGAIN;
+ } else if (mutex_lock_interruptible(&runtime->oss.params_lock))
return -EINTR;
sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL);
params = kmalloc(sizeof(*params), GFP_KERNEL);
@@ -1079,7 +1083,7 @@ static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_fil
if (asubstream == NULL)
asubstream = substream;
if (substream->runtime->oss.params) {
- err = snd_pcm_oss_change_params(substream);
+ err = snd_pcm_oss_change_params(substream, false);
if (err < 0)
return err;
}
@@ -1118,7 +1122,7 @@ static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream)
return 0;
runtime = substream->runtime;
if (runtime->oss.params) {
- err = snd_pcm_oss_change_params(substream);
+ err = snd_pcm_oss_change_params(substream, false);
if (err < 0)
return err;
}
@@ -2149,7 +2153,7 @@ static int snd_pcm_oss_get_space(struct snd_pcm_oss_file *pcm_oss_file, int stre
runtime = substream->runtime;
if (runtime->oss.params &&
- (err = snd_pcm_oss_change_params(substream)) < 0)
+ (err = snd_pcm_oss_change_params(substream, false)) < 0)
return err;
info.fragsize = runtime->oss.period_bytes;
@@ -2770,7 +2774,12 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area)
return -EIO;
if (runtime->oss.params) {
- if ((err = snd_pcm_oss_change_params(substream)) < 0)
+ /* use mutex_trylock() for params_lock for avoiding a deadlock
+ * between mmap_sem and params_lock taken by
+ * copy_from/to_user() in snd_pcm_oss_write/read()
+ */
+ err = snd_pcm_oss_change_params(substream, true);
+ if (err < 0)
return err;
}
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
--
1.7.12.2.21.g234cd45.dirty
next prev parent reply other threads:[~2016-03-04 16:03 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <148ee355b419e9976ca727513a1405c8@local>
2016-03-04 15:30 ` [PATCH 2.6.32 00/55] 2.6.32.71-longterm review Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 01/55] usb: serial: visor: fix crash on detecting device without write_urbs Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 02/55] usbvision fix overflow of interfaces array Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 03/55] USB: visor: fix null-deref at probe Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 04/55] sctp: Prevent soft lockup when sctp_accept() is called during a timeout event Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 05/55] sctp: translate network order to host order when users get a hmacid Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 06/55] tty: Fix unsafe ldisc reference via ioctl(TIOCGETD) Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 07/55] x86/mm: Add barriers and document switch_mm()-vs-flush synchronization Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 08/55] x86/mm: Improve switch_mm() barrier comments Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 10/55] sparc64: fix incorrect sign extension in sys_sparc64_personality Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 11/55] locks: fix unlock when fcntl_setlk races with a close Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 12/55] l2tp: fix another panic in pppol2tp Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 13/55] vfs: make AIO use the proper rw_verify_area() area helpers Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 14/55] readv/writev: do the same MAX_RW_COUNT truncation that read/write does Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 15/55] pipe: Fix buffer offset after partially failed read Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 16/55] af_unix: fix struct pid memory leak Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 17/55] PCI/AER: Flush workqueue on device remove to avoid use-after-free Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 18/55] libata: disable forced PORTS_IMPL for >= AHCI 1.3 Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 19/55] rfkill: fix rfkill_fop_read wait_event usage Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 20/55] SCSI: fix crashes in sd and sr runtime PM Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 21/55] tda1004x: only update the frontend properties if locked Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 22/55] saa7134-alsa: Only frees registered sound cards Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 23/55] scsi_dh_rdac: always retry MODE SELECT on command lock violation Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 24/55] ocfs2/dlm: clear refmap bit of recovery lock while doing local recovery cleanup Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 25/55] udf: Promote some debugging messages to udf_error Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 26/55] udf: limit the maximum number of indirect extents in a row Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 27/55] udf: Prevent buffer overrun with multi-byte characters Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 28/55] udf: Check output buffer length when converting name to CS0 Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 29/55] ocfs2/dlm: ignore cleaning the migration mle that is inuse Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 30/55] ALSA: dummy: Disable switching timer backend via sysfs Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 31/55] ALSA: timer: Harden slave timer list handling Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 32/55] ALSA: hrtimer: Fix stall by hrtimer_cancel() Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 33/55] ALSA: pcm: Fix snd_pcm_hw_params struct copy in compat mode Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 34/55] ALSA: seq: Fix snd_seq_call_port_info_ioctl " Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 35/55] ALSA: control: Avoid kernel warnings from tlv ioctl with numid 0 Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 36/55] ALSA: seq: Fix incorrect sanity check at snd_seq_oss_synth_cleanup() Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 37/55] ALSA: seq: Degrade the error message for too many opens Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 38/55] ALSA: seq: Fix race at closing in virmidi driver Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 39/55] ALSA: rawmidi: Remove kernel WARNING for NULL user-space buffer check Willy Tarreau
2016-03-04 15:30 ` Willy Tarreau [this message]
2016-03-04 15:30 ` [PATCH 2.6.32 41/55] ALSA: seq: Fix yet another races among ALSA timer accesses Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 42/55] ALSA: timer: Fix link corruption due to double start or stop Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 43/55] ALSA: rawmidi: Make snd_rawmidi_transmit() race-free Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 44/55] ALSA: rawmidi: Fix race at copying & updating the position Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 45/55] ALSA: seq: Fix lockdep warnings due to double mutex locks Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 46/55] ALSA: timer: Fix double unlink of active_list Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 47/55] ALSA: timer: Fix leftover link at closing Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 48/55] ALSA: timer: Fix race among timer ioctls Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 49/55] ALSA: timer: Fix wrong instance passed to slave callbacks Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 50/55] ALSA: timer: Fix race at concurrent reads Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 51/55] ALSA: usb-audio: avoid freeing umidi object twice Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 52/55] ALSA: seq: Fix missing NULL check at remove_events ioctl Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 53/55] ALSA: seq: Fix race at timer setup and close Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 54/55] RDMA/cxgb3: Dont free skbs on NET_XMIT_* indications from LLD Willy Tarreau
2016-03-04 15:30 ` [PATCH 2.6.32 55/55] iw_cxgb3: Fix incorrectly returning error on success Willy Tarreau
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=20160304153002.462158072@1wt.eu \
--to=w@1wt.eu \
--cc=ben@decadent.org.uk \
--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