From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Hu Jiahui <kirin.say@gmail.com>,
Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>
Subject: [PATCH 5.15 13/37] ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
Date: Fri, 25 Mar 2022 16:14:14 +0100 [thread overview]
Message-ID: <20220325150420.313873846@linuxfoundation.org> (raw)
In-Reply-To: <20220325150419.931802116@linuxfoundation.org>
From: Takashi Iwai <tiwai@suse.de>
commit 92ee3c60ec9fe64404dc035e7c41277d74aa26cb upstream.
Currently we have neither proper check nor protection against the
concurrent calls of PCM hw_params and hw_free ioctls, which may result
in a UAF. Since the existing PCM stream lock can't be used for
protecting the whole ioctl operations, we need a new mutex to protect
those racy calls.
This patch introduced a new mutex, runtime->buffer_mutex, and applies
it to both hw_params and hw_free ioctl code paths. Along with it, the
both functions are slightly modified (the mmap_count check is moved
into the state-check block) for code simplicity.
Reported-by: Hu Jiahui <kirin.say@gmail.com>
Cc: <stable@vger.kernel.org>
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20220322170720.3529-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/sound/pcm.h | 1
sound/core/pcm.c | 2 +
sound/core/pcm_native.c | 61 ++++++++++++++++++++++++++++++------------------
3 files changed, 42 insertions(+), 22 deletions(-)
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -398,6 +398,7 @@ struct snd_pcm_runtime {
wait_queue_head_t tsleep; /* transfer sleep */
struct fasync_struct *fasync;
bool stop_operating; /* sync_stop will be called */
+ struct mutex buffer_mutex; /* protect for buffer changes */
/* -- private section -- */
void *private_data;
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -969,6 +969,7 @@ int snd_pcm_attach_substream(struct snd_
init_waitqueue_head(&runtime->tsleep);
runtime->status->state = SNDRV_PCM_STATE_OPEN;
+ mutex_init(&runtime->buffer_mutex);
substream->runtime = runtime;
substream->private_data = pcm->private_data;
@@ -1002,6 +1003,7 @@ void snd_pcm_detach_substream(struct snd
} else {
substream->runtime = NULL;
}
+ mutex_destroy(&runtime->buffer_mutex);
kfree(runtime);
put_pid(substream->pid);
substream->pid = NULL;
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -672,33 +672,40 @@ static int snd_pcm_hw_params_choose(stru
return 0;
}
+#if IS_ENABLED(CONFIG_SND_PCM_OSS)
+#define is_oss_stream(substream) ((substream)->oss.oss)
+#else
+#define is_oss_stream(substream) false
+#endif
+
static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_pcm_runtime *runtime;
- int err, usecs;
+ int err = 0, usecs;
unsigned int bits;
snd_pcm_uframes_t frames;
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
runtime = substream->runtime;
+ mutex_lock(&runtime->buffer_mutex);
snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) {
case SNDRV_PCM_STATE_OPEN:
case SNDRV_PCM_STATE_SETUP:
case SNDRV_PCM_STATE_PREPARED:
+ if (!is_oss_stream(substream) &&
+ atomic_read(&substream->mmap_count))
+ err = -EBADFD;
break;
default:
- snd_pcm_stream_unlock_irq(substream);
- return -EBADFD;
+ err = -EBADFD;
+ break;
}
snd_pcm_stream_unlock_irq(substream);
-#if IS_ENABLED(CONFIG_SND_PCM_OSS)
- if (!substream->oss.oss)
-#endif
- if (atomic_read(&substream->mmap_count))
- return -EBADFD;
+ if (err)
+ goto unlock;
snd_pcm_sync_stop(substream, true);
@@ -786,16 +793,21 @@ static int snd_pcm_hw_params(struct snd_
if (usecs >= 0)
cpu_latency_qos_add_request(&substream->latency_pm_qos_req,
usecs);
- return 0;
+ err = 0;
_error:
- /* hardware might be unusable from this time,
- so we force application to retry to set
- the correct hardware parameter settings */
- snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
- if (substream->ops->hw_free != NULL)
- substream->ops->hw_free(substream);
- if (substream->managed_buffer_alloc)
- snd_pcm_lib_free_pages(substream);
+ if (err) {
+ /* hardware might be unusable from this time,
+ * so we force application to retry to set
+ * the correct hardware parameter settings
+ */
+ snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
+ if (substream->ops->hw_free != NULL)
+ substream->ops->hw_free(substream);
+ if (substream->managed_buffer_alloc)
+ snd_pcm_lib_free_pages(substream);
+ }
+ unlock:
+ mutex_unlock(&runtime->buffer_mutex);
return err;
}
@@ -835,26 +847,31 @@ static int do_hw_free(struct snd_pcm_sub
static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime;
- int result;
+ int result = 0;
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
runtime = substream->runtime;
+ mutex_lock(&runtime->buffer_mutex);
snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) {
case SNDRV_PCM_STATE_SETUP:
case SNDRV_PCM_STATE_PREPARED:
+ if (atomic_read(&substream->mmap_count))
+ result = -EBADFD;
break;
default:
- snd_pcm_stream_unlock_irq(substream);
- return -EBADFD;
+ result = -EBADFD;
+ break;
}
snd_pcm_stream_unlock_irq(substream);
- if (atomic_read(&substream->mmap_count))
- return -EBADFD;
+ if (result)
+ goto unlock;
result = do_hw_free(substream);
snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
cpu_latency_qos_remove_request(&substream->latency_pm_qos_req);
+ unlock:
+ mutex_unlock(&runtime->buffer_mutex);
return result;
}
next prev parent reply other threads:[~2022-03-25 15:17 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-25 15:14 [PATCH 5.15 00/37] 5.15.32-rc1 review Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 01/37] nfc: st21nfca: Fix potential buffer overflows in EVT_TRANSACTION Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 02/37] net: ipv6: fix skb_over_panic in __ip6_append_data Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 03/37] tpm: Fix error handling in async work Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 04/37] Bluetooth: btusb: Add another Realtek 8761BU Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 05/37] llc: fix netdevice reference leaks in llc_ui_bind() Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 06/37] ASoC: sti: Fix deadlock via snd_pcm_stop_xrun() call Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 07/37] ALSA: oss: Fix PCM OSS buffer allocation overflow Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 08/37] ALSA: usb-audio: add mapping for new Corsair Virtuoso SE Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 09/37] ALSA: hda/realtek: Add quirk for Clevo NP70PNJ Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 10/37] ALSA: hda/realtek: Add quirk for Clevo NP50PNJ Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 11/37] ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc671 Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 12/37] ALSA: hda/realtek: Add quirk for ASUS GA402 Greg Kroah-Hartman
2022-03-25 15:14 ` Greg Kroah-Hartman [this message]
2022-03-25 15:14 ` [PATCH 5.15 14/37] ALSA: pcm: Fix races among concurrent read/write and buffer changes Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 15/37] ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 16/37] ALSA: pcm: Fix races among concurrent prealloc proc writes Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 17/37] ALSA: pcm: Add stream lock during PCM reset ioctl operations Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 18/37] ALSA: usb-audio: Add mute TLV for playback volumes on RODE NT-USB Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 19/37] ALSA: cmipci: Restore aux vol on suspend/resume Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 20/37] ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 21/37] drivers: net: xgene: Fix regression in CRC stripping Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 22/37] netfilter: nf_tables: initialize registers in nft_do_chain() Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 23/37] netfilter: nf_tables: validate registers coming from userspace Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 24/37] ACPI / x86: Work around broken XSDT on Advantech DAC-BJ01 board Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 25/37] ACPI: battery: Add device HID and quirk for Microsoft Surface Go 3 Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 26/37] ACPI: video: Force backlight native for Clevo NL5xRU and NL5xNU Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 27/37] crypto: qat - disable registration of algorithms Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 28/37] Bluetooth: btusb: Add one more Bluetooth part for the Realtek RTL8852AE Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 29/37] Revert "ath: add support for special 0x0 regulatory domain" Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 30/37] drm/virtio: Ensure that objs is not NULL in virtio_gpu_array_put_free() Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 31/37] rcu: Dont deboost before reporting expedited quiescent state Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 32/37] uaccess: fix integer overflow on access_ok() Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 33/37] mac80211: fix potential double free on mesh join Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 34/37] tpm: use try_get_ops() in tpm-space.c Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 35/37] wcn36xx: Differentiate wcn3660 from wcn3620 Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 36/37] m68k: fix access_ok for coldfire Greg Kroah-Hartman
2022-03-25 15:14 ` [PATCH 5.15 37/37] nds32: fix access_ok() checks in get/put_user Greg Kroah-Hartman
2022-03-25 18:52 ` [PATCH 5.15 00/37] 5.15.32-rc1 review Fox Chen
2022-03-25 23:14 ` Florian Fainelli
2022-03-25 23:23 ` Shuah Khan
2022-03-26 6:40 ` Naresh Kamboju
2022-03-26 6:41 ` Ron Economos
2022-03-26 12:18 ` Bagas Sanjaya
2022-03-26 13:59 ` Sudip Mukherjee
2022-03-27 0:52 ` Guenter Roeck
2022-03-28 14:24 ` Jon Hunter
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=20220325150420.313873846@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=kirin.say@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=perex@perex.cz \
--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).