From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: akpm@linux-foundation.org, "Dmitry Vyukov" <dvyukov@google.com>,
"Takashi Iwai" <tiwai@suse.de>
Subject: [PATCH 3.2 38/67] ALSA: rawmidi: Fix race at copying & updating the position
Date: Tue, 23 Feb 2016 21:42:03 +0000 [thread overview]
Message-ID: <lsq.1456263723.398745018@decadent.org.uk> (raw)
In-Reply-To: <lsq.1456263722.390955919@decadent.org.uk>
3.2.78-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
commit 81f577542af15640cbcb6ef68baa4caa610cbbfc upstream.
The rawmidi read and write functions manage runtime stream status
such as runtime->appl_ptr and runtime->avail. These point where to
copy the new data and how many bytes have been copied (or to be
read). The problem is that rawmidi read/write call copy_from_user()
or copy_to_user(), and the runtime spinlock is temporarily unlocked
and relocked while copying user-space. Since the current code
advances and updates the runtime status after the spin unlock/relock,
the copy and the update may be asynchronous, and eventually
runtime->avail might go to a negative value when many concurrent
accesses are done. This may lead to memory corruption in the end.
For fixing this race, in this patch, the status update code is
performed in the same lock before the temporary unlock. Also, the
spinlock is now taken more widely in snd_rawmidi_kernel_read1() for
protecting more properly during the whole operation.
BugLink: http://lkml.kernel.org/r/CACT4Y+b-dCmNf1GpgPKfDO0ih+uZCL2JV4__j-r1kdhPLSgQCQ@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
sound/core/rawmidi.c | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -934,31 +934,36 @@ static long snd_rawmidi_kernel_read1(str
unsigned long flags;
long result = 0, count1;
struct snd_rawmidi_runtime *runtime = substream->runtime;
+ unsigned long appl_ptr;
+ spin_lock_irqsave(&runtime->lock, flags);
while (count > 0 && runtime->avail) {
count1 = runtime->buffer_size - runtime->appl_ptr;
if (count1 > count)
count1 = count;
- spin_lock_irqsave(&runtime->lock, flags);
if (count1 > (int)runtime->avail)
count1 = runtime->avail;
+
+ /* update runtime->appl_ptr before unlocking for userbuf */
+ appl_ptr = runtime->appl_ptr;
+ runtime->appl_ptr += count1;
+ runtime->appl_ptr %= runtime->buffer_size;
+ runtime->avail -= count1;
+
if (kernelbuf)
- memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1);
+ memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1);
if (userbuf) {
spin_unlock_irqrestore(&runtime->lock, flags);
if (copy_to_user(userbuf + result,
- runtime->buffer + runtime->appl_ptr, count1)) {
+ runtime->buffer + appl_ptr, count1)) {
return result > 0 ? result : -EFAULT;
}
spin_lock_irqsave(&runtime->lock, flags);
}
- runtime->appl_ptr += count1;
- runtime->appl_ptr %= runtime->buffer_size;
- runtime->avail -= count1;
- spin_unlock_irqrestore(&runtime->lock, flags);
result += count1;
count -= count1;
}
+ spin_unlock_irqrestore(&runtime->lock, flags);
return result;
}
@@ -1207,6 +1212,7 @@ static long snd_rawmidi_kernel_write1(st
unsigned long flags;
long count1, result;
struct snd_rawmidi_runtime *runtime = substream->runtime;
+ unsigned long appl_ptr;
if (!kernelbuf && !userbuf)
return -EINVAL;
@@ -1227,12 +1233,19 @@ static long snd_rawmidi_kernel_write1(st
count1 = count;
if (count1 > (long)runtime->avail)
count1 = runtime->avail;
+
+ /* update runtime->appl_ptr before unlocking for userbuf */
+ appl_ptr = runtime->appl_ptr;
+ runtime->appl_ptr += count1;
+ runtime->appl_ptr %= runtime->buffer_size;
+ runtime->avail -= count1;
+
if (kernelbuf)
- memcpy(runtime->buffer + runtime->appl_ptr,
+ memcpy(runtime->buffer + appl_ptr,
kernelbuf + result, count1);
else if (userbuf) {
spin_unlock_irqrestore(&runtime->lock, flags);
- if (copy_from_user(runtime->buffer + runtime->appl_ptr,
+ if (copy_from_user(runtime->buffer + appl_ptr,
userbuf + result, count1)) {
spin_lock_irqsave(&runtime->lock, flags);
result = result > 0 ? result : -EFAULT;
@@ -1240,9 +1253,6 @@ static long snd_rawmidi_kernel_write1(st
}
spin_lock_irqsave(&runtime->lock, flags);
}
- runtime->appl_ptr += count1;
- runtime->appl_ptr %= runtime->buffer_size;
- runtime->avail -= count1;
result += count1;
count -= count1;
}
next prev parent reply other threads:[~2016-02-23 22:01 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-23 21:42 [PATCH 3.2 00/67] 3.2.78-rc1 review Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 09/67] pptp: fix illegal memory access caused by multiple bind()s Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 16/67] ALSA: seq: Degrade the error message for too many opens Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 19/67] libata: disable forced PORTS_IMPL for >= AHCI 1.3 Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 26/67] ALSA: dummy: Disable switching timer backend via sysfs Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 36/67] libata: fix sff host state machine locking while polling Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 42/67] xhci: Fix list corruption in urb dequeue at host removal Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 57/67] ALSA: timer: Fix race at concurrent reads Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 56/67] ALSA: timer: Fix race between stop and interrupt Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 33/67] ALSA: pcm: Fix potential deadlock in OSS emulation Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 04/67] posix-timers: Handle relative timers with CONFIG_TIME_LOW_RES proper Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 58/67] ahci: Intel DNV device IDs SATA Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 60/67] btrfs: properly set the termination value of ctx->pos in readdir Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 11/67] USB: cp210x: add ID for IAI USB to RS485 adaptor Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 61/67] ALSA: usb-audio: avoid freeing umidi object twice Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 06/67] usb: cdc-acm: send zero packet for intel 7260 modem Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 51/67] klist: fix starting point removed bug in klist iterators Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 34/67] ALSA: seq: Fix yet another races among ALSA timer accesses Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 23/67] SCSI: fix crashes in sd and sr runtime PM Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 67/67] sched: fix __sched_setscheduler() vs load balancing race Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 50/67] crypto: algif_skcipher - Do not dereference ctx without socket lock Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 44/67] ALSA: timer: Fix leftover link at closing Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 43/67] [media] tda1004x: only update the frontend properties if locked Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 10/67] sctp: allow setting SCTP_SACK_IMMEDIATELY by the application Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 02/67] hrtimer: Handle remaining time proper for TIME_LOW_RES Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 25/67] crypto: shash - Fix has_key setting Ben Hutchings
2016-02-23 21:42 ` Ben Hutchings [this message]
2016-02-23 21:42 ` [PATCH 3.2 27/67] drm/vmwgfx: respect 'nomodeset' Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 63/67] unix: correctly track in-flight fds in sending process user_struct Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 49/67] crypto: user - lock crypto_alg_list on alg dump Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 07/67] cdc-acm:exclude Samsung phone 04e8:685d Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 08/67] af_unix: fix struct pid memory leak Ben Hutchings
2016-02-23 22:07 ` Rainer Weikusat
2016-02-24 21:24 ` Ben Hutchings
2016-02-25 7:26 ` Willy Tarreau
2016-02-23 21:42 ` [PATCH 3.2 18/67] PCI/AER: Flush workqueue on device remove to avoid use-after-free Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 28/67] x86/mm/pat: Avoid truncation when converting cpa->numpages to address Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 39/67] ALSA: seq: Fix lockdep warnings due to double mutex locks Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 46/67] scsi_dh_rdac: always retry MODE SELECT on command lock violation Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 14/67] USB: serial: option: Adding support for Telit LE922 Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 32/67] ALSA: rawmidi: Remove kernel WARNING for NULL user-space buffer check Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 48/67] ocfs2/dlm: clear refmap bit of recovery lock while doing local recovery cleanup Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 59/67] ARM: 8519/1: ICST: try other dividends than 1 Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 47/67] mm, vmstat: fix wrong WQ sleep when memory reclaim doesn't make any progress Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 65/67] iw_cxgb3: Fix incorrectly returning error on success Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 01/67] KVM: vmx: fix MPX detection Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 62/67] unix: properly account for FDs passed over unix sockets Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 31/67] ALSA: seq: Fix race at closing in virmidi driver Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 21/67] rfkill: fix rfkill_fop_read wait_event usage Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 15/67] ALSA: seq: Fix incorrect sanity check at snd_seq_oss_synth_cleanup() Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 45/67] [media] saa7134-alsa: Only frees registered sound cards Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 55/67] sctp: translate network order to host order when users get a hmacid Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 24/67] tty: Fix unsafe ldisc reference via ioctl(TIOCGETD) Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 22/67] perf annotate browser: Fix behaviour of Shift-Tab with nothing focussed Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 30/67] intel_scu_ipcutil: underflow in scu_reg_access() Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 17/67] USB: serial: ftdi_sio: add support for Yaesu SCU-18 cable Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 03/67] timerfd: Handle relative timers with CONFIG_TIME_LOW_RES proper Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 05/67] itimers: " Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 52/67] ALSA: dummy: Implement timer backend switching more safely Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 13/67] USB: serial: visor: fix crash on detecting device without write_urbs Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 20/67] virtio_pci: fix use after free on release Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 29/67] crypto: algif_hash - wait for crypto_ahash_init() to complete Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 54/67] ARM: 8517/1: ICST: avoid arithmetic overflow in icst_hz() Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 64/67] pipe: limit the per-user amount of pages allocated in pipes Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 37/67] ALSA: rawmidi: Make snd_rawmidi_transmit() race-free Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 53/67] ALSA: timer: Fix wrong instance passed to slave callbacks Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 35/67] ALSA: timer: Fix link corruption due to double start or stop Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 66/67] pipe: Fix buffer offset after partially failed read Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 41/67] usb: xhci: apply XHCI_PME_STUCK_QUIRK to Intel Broxton-M platforms Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 40/67] Revert "xhci: don't finish a TD if we get a short-transfer event mid TD" Ben Hutchings
2016-02-23 21:42 ` [PATCH 3.2 12/67] USB: visor: fix null-deref at probe Ben Hutchings
2016-02-24 0:48 ` [PATCH 3.2 00/67] 3.2.78-rc1 review Ben Hutchings
2016-02-24 2:48 ` Guenter Roeck
2016-02-24 14:41 ` Ben Hutchings
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=lsq.1456263723.398745018@decadent.org.uk \
--to=ben@decadent.org.uk \
--cc=akpm@linux-foundation.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
all inboxes | Powered by JetHome®