Headline
CVE-2022-1048: [PATCH 0/4] ALSA: pcm: Fix ioctl races
A use-after-free flaw was found in the Linux kernel’s sound subsystem in the way a user triggers concurrent calls of PCM hw_params. The hw_free ioctls or similar race condition happens inside ALSA PCM for other ioctls. This flaw allows a local user to crash or potentially escalate their privileges on the system.
* [PATCH 0/4] ALSA: pcm: Fix ioctl races @ 2022-03-22 17:07 Takashi Iwai 2022-03-22 17:07 ` [PATCH 1/4] ALSA: pcm: Fix races among concurrent hw_params and hw_free calls Takashi Iwai ` (4 more replies) 0 siblings, 5 replies; 9+ messages in thread From: Takashi Iwai @ 2022-03-22 17:07 UTC (permalink / raw) To: alsa-devel; +Cc: Hu Jiahui, linux-kernel
Hi,
this is a patch set to address the recently reported bug for the racy PCM ioctls. In short, the current ALSA PCM core doesn’t take enough care of concurrent ioctl calls, and the concurrent calls may result in a use-after-free. The reported problem was the concurrent hw_free calls, but there can be similar cases with other code paths like hw_params, prepare, etc, too.
The patch set introduces the new runtime->buffer_mutex for protecting those. The first patch is the fix for the reported issue (the races with hw_free), while the rest three are more hardening for the other similar executions.
[ Note that the patch 3 was slightly modified from the version I sent to distros list, as I noticed possible lockdep (false-positive) warnings. The behavior is almost same, just written differently. ]
thanks,
Takashi
===
Takashi Iwai (4): ALSA: pcm: Fix races among concurrent hw_params and hw_free calls ALSA: pcm: Fix races among concurrent read/write and buffer changes ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls ALSA: pcm: Fix races among concurrent prealloc proc writes
include/sound/pcm.h | 1 + sound/core/pcm.c | 2 + sound/core/pcm_lib.c | 4 ++ sound/core/pcm_memory.c | 11 ++±- sound/core/pcm_native.c | 93 ++++++++++++++++++++++++±--------------- 5 files changed, 71 insertions(+), 40 deletions(-)
– 2.31.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/4] ALSA: pcm: Fix races among concurrent hw_params and hw_free calls 2022-03-22 17:07 [PATCH 0/4] ALSA: pcm: Fix ioctl races Takashi Iwai @ 2022-03-22 17:07 ` Takashi Iwai 2022-03-22 17:07 ` [PATCH 2/4] ALSA: pcm: Fix races among concurrent read/write and buffer changes Takashi Iwai ` (3 subsequent siblings) 4 siblings, 0 replies; 9+ messages in thread From: Takashi Iwai @ 2022-03-22 17:07 UTC (permalink / raw) To: alsa-devel; +Cc: Hu Jiahui, linux-kernel
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 [email protected] Cc: [email protected] Signed-off-by: Takashi Iwai [email protected]
include/sound/pcm.h | 1 + sound/core/pcm.c | 2 ++ sound/core/pcm_native.c | 61 +++++++++++++++++++++++++±-------------- 3 files changed, 42 insertions(+), 22 deletions(-)
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 36da42cd0774…314f2779cab5 100644 — a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -401,6 +401,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; diff --git a/sound/core/pcm.c b/sound/core/pcm.c index ba4a987ed1c6…edd9849210f2 100644 — a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -969,6 +969,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, 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_pcm_substream *substream) } else { substream->runtime = NULL; }
mutex_destroy(&runtime->buffer_mutex); kfree(runtime); put_pid(substream->pid); substream->pid = NULL; diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index a056b3ef3c84…266895374b83 100644 — a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -685,33 +685,40 @@ static int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, 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;
} snd_pcm_stream_unlock_irq(substream); -#if IS_ENABLED(CONFIG_SND_PCM_OSS)break;
- if (!substream->oss.oss) -#endif
if (atomic\_read(&substream->mmap\_count))
return -EBADFD;
if (err)
goto unlock;
snd_pcm_sync_stop(substream, true);
@@ -799,16 +806,21 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, 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; }
@@ -848,26 +860,31 @@ static int do_hw_free(struct snd_pcm_substream *substream) 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;
} snd_pcm_stream_unlock_irq(substream); - if (atomic_read(&substream->mmap_count))break;
return -EBADFD;
- if (result)
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:goto unlock;
- mutex_unlock(&runtime->buffer_mutex); return result; }
– 2.31.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/4] ALSA: pcm: Fix races among concurrent read/write and buffer changes 2022-03-22 17:07 [PATCH 0/4] ALSA: pcm: Fix ioctl races Takashi Iwai 2022-03-22 17:07 ` [PATCH 1/4] ALSA: pcm: Fix races among concurrent hw_params and hw_free calls Takashi Iwai @ 2022-03-22 17:07 ` Takashi Iwai 2022-03-22 17:07 ` [PATCH 3/4] ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls Takashi Iwai ` (2 subsequent siblings) 4 siblings, 0 replies; 9+ messages in thread From: Takashi Iwai @ 2022-03-22 17:07 UTC (permalink / raw) To: alsa-devel; +Cc: Hu Jiahui, linux-kernel
In the current PCM design, the read/write syscalls (as well as the equivalent ioctls) are allowed before the PCM stream is running, that is, at PCM PREPARED state. Meanwhile, we also allow to re-issue hw_params and hw_free ioctl calls at the PREPARED state that may change or free the buffers, too. The problem is that there is no protection against those mix-ups.
This patch applies the previously introduced runtime->buffer_mutex to the read/write operations so that the concurrent hw_params or hw_free call can no longer interfere during the operation. The mutex is unlocked before scheduling, so we don’t take it too long.
Cc: [email protected] Signed-off-by: Takashi Iwai [email protected]
sound/core/pcm_lib.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index f2090025236b…a40a35e51fad 100644 — a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1906,9 +1906,11 @@ static int wait_for_avail(struct snd_pcm_substream *substream, if (avail >= runtime->twake) break; snd_pcm_stream_unlock_irq(substream);
mutex\_unlock(&runtime->buffer\_mutex); tout = schedule\_timeout(wait\_time);
mutex\_lock(&runtime->buffer\_mutex); snd\_pcm\_stream\_lock\_irq(substream); set\_current\_state(TASK\_INTERRUPTIBLE); switch (runtime->status->state) {
@@ -2219,6 +2221,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
nonblock = !!(substream->f\_flags & O\_NONBLOCK);
- mutex_lock(&runtime->buffer_mutex); snd_pcm_stream_lock_irq(substream); err = pcm_accessible_state(runtime); if (err < 0) @@ -2310,6 +2313,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream, if (xfer > 0 && err >= 0) snd_pcm_update_state(substream, runtime); snd_pcm_stream_unlock_irq(substream);
- mutex_unlock(&runtime->buffer_mutex); return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; } EXPORT_SYMBOL(__snd_pcm_lib_xfer); – 2.31.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/4] ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls 2022-03-22 17:07 [PATCH 0/4] ALSA: pcm: Fix ioctl races Takashi Iwai 2022-03-22 17:07 ` [PATCH 1/4] ALSA: pcm: Fix races among concurrent hw_params and hw_free calls Takashi Iwai 2022-03-22 17:07 ` [PATCH 2/4] ALSA: pcm: Fix races among concurrent read/write and buffer changes Takashi Iwai @ 2022-03-22 17:07 ` Takashi Iwai 2022-03-23 8:08 ` Amadeusz Sławiński 2022-03-22 17:07 ` [PATCH 4/4] ALSA: pcm: Fix races among concurrent prealloc proc writes Takashi Iwai 2022-03-22 17:14 ` [PATCH 0/4] ALSA: pcm: Fix ioctl races Jaroslav Kysela 4 siblings, 1 reply; 9+ messages in thread From: Takashi Iwai @ 2022-03-22 17:07 UTC (permalink / raw) To: alsa-devel; +Cc: Hu Jiahui, linux-kernel
Like the previous fixes to hw_params and hw_free ioctl races, we need to paper over the concurrent prepare ioctl calls against hw_params and hw_free, too.
This patch implements the locking with the existing runtime->buffer_mutex for prepare ioctls. Unlike the previous case for snd_pcm_hw_hw_params() and snd_pcm_hw_free(), snd_pcm_prepare() is performed to the linked streams, hence the lock can’t be applied simply on the top. For tracking the lock in each linked substream, we modify snd_pcm_action_group() slightly and apply the buffer_mutex for the case stream_lock=false (formerly there was no lock applied) there.
Cc: [email protected] Signed-off-by: Takashi Iwai [email protected]
sound/core/pcm_native.c | 32 +++++++++++++++++±------------- 1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 266895374b83…0e4fbf5fd87b 100644 — a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1190,15 +1190,17 @@ struct action_ops { static int snd_pcm_action_group(const struct action_ops *ops, struct snd_pcm_substream *substream, snd_pcm_state_t state, - bool do_lock)
bool stream\_lock)
{ struct snd_pcm_substream *s = NULL; struct snd_pcm_substream *s1; int res = 0, depth = 1;
snd\_pcm\_group\_for\_each\_entry(s, substream) {
- if (do_lock && s != substream) {
if (s->pcm->nonatomic)
if (s != substream) {
if (!stream\_lock)
mutex\_lock\_nested(&s->runtime->buffer\_mutex, depth);
else if (s->pcm->nonatomic) mutex\_lock\_nested(&s->self\_group.mutex, depth); else spin\_lock\_nested(&s->self\_group.lock, depth);
@@ -1226,18 +1228,18 @@ static int snd_pcm_action_group(const struct action_ops *ops, ops->post_action(s, state); } _unlock: - if (do_lock) {
/\* unlock streams \*/
snd\_pcm\_group\_for\_each\_entry(s1, substream) {
if (s1 != substream) {
if (s1->pcm->nonatomic)
mutex\_unlock(&s1->self\_group.mutex);
else
spin\_unlock(&s1->self\_group.lock);
}
if (s1 == s) /\* end \*/
break;
/* unlock streams */
snd_pcm_group_for_each_entry(s1, substream) {
if (s1 != substream) {
if (!stream\_lock)
mutex\_unlock(&s1->runtime->buffer\_mutex);
else if (s1->pcm->nonatomic)
mutex\_unlock(&s1->self\_group.mutex);
else
spin\_unlock(&s1->self\_group.lock); }
if (s1 == s) /\* end \*/
break;
} return res; } @@ -1367,10 +1369,12 @@ static int snd_pcm_action_nonatomic(const struct action_ops *ops,
/* Guarantee the group members won’t change during non-atomic action */ down_read(&snd_pcm_link_rwsem);
mutex_lock(&substream->runtime->buffer_mutex); if (snd_pcm_stream_linked(substream)) res = snd_pcm_action_group(ops, substream, state, false); else res = snd_pcm_action_single(ops, substream, state);
mutex_unlock(&substream->runtime->buffer_mutex); up_read(&snd_pcm_link_rwsem); return res; } – 2.31.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/4] ALSA: pcm: Fix races among concurrent prealloc proc writes 2022-03-22 17:07 [PATCH 0/4] ALSA: pcm: Fix ioctl races Takashi Iwai ` (2 preceding siblings …) 2022-03-22 17:07 ` [PATCH 3/4] ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls Takashi Iwai @ 2022-03-22 17:07 ` Takashi Iwai 2022-03-22 17:14 ` [PATCH 0/4] ALSA: pcm: Fix ioctl races Jaroslav Kysela 4 siblings, 0 replies; 9+ messages in thread From: Takashi Iwai @ 2022-03-22 17:07 UTC (permalink / raw) To: alsa-devel; +Cc: Hu Jiahui, linux-kernel
We have no protection against concurrent PCM buffer preallocation changes via proc files, and it may potentially lead to UAF or some weird problem. This patch applies the PCM open_mutex to the proc write operation for avoiding the racy proc writes and the PCM stream open (and further operations).
Cc: [email protected] Signed-off-by: Takashi Iwai [email protected]
sound/core/pcm_memory.c | 11 ++++++±— 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index b70ce3b69ab4…8848d2f3160d 100644 — a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -163,19 +163,20 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry, size_t size; struct snd_dma_buffer new_dmab;
- mutex_lock(&substream->pcm->open_mutex); if (substream->runtime) { buffer->error = -EBUSY; - return;
} if (!snd_info_get_line(buffer, line, sizeof(line))) { snd_info_get_str(str, line, sizeof(str)); size = simple_strtoul(str, NULL, 10) * 1024; if ((size != 0 && size < 8192) || size > substream->dma_max) { buffer->error = -EINVAL; - return;goto unlock;
goto unlock; } if (substream->dma\_buffer.bytes == size)
- return;
goto unlock; memset(&new\_dmab, 0, sizeof(new\_dmab)); new\_dmab.dev = substream->dma\_buffer.dev; if (size > 0) {
@@ -189,7 +190,7 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry, substream->pcm->card->number, substream->pcm->device, substream->stream ? ‘c’ : 'p’, substream->number, substream->pcm->name, size); - return;
goto unlock; } substream->buffer\_bytes\_max = size; } else {
@@ -201,6 +202,8 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry, } else { buffer->error = -EINVAL; } + unlock:
- mutex_unlock(&substream->pcm->open_mutex); }
static inline void preallocate_info_init(struct snd_pcm_substream *substream)
2.31.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/4] ALSA: pcm: Fix ioctl races 2022-03-22 17:07 [PATCH 0/4] ALSA: pcm: Fix ioctl races Takashi Iwai ` (3 preceding siblings …) 2022-03-22 17:07 ` [PATCH 4/4] ALSA: pcm: Fix races among concurrent prealloc proc writes Takashi Iwai @ 2022-03-22 17:14 ` Jaroslav Kysela 4 siblings, 0 replies; 9+ messages in thread From: Jaroslav Kysela @ 2022-03-22 17:14 UTC (permalink / raw) To: Takashi Iwai, alsa-devel; +Cc: Hu Jiahui, linux-kernel
On 22. 03. 22 18:07, Takashi Iwai wrote: > Hi,
this is a patch set to address the recently reported bug for the racy PCM ioctls. In short, the current ALSA PCM core doesn’t take enough care of concurrent ioctl calls, and the concurrent calls may result in a use-after-free. The reported problem was the concurrent hw_free calls, but there can be similar cases with other code paths like hw_params, prepare, etc, too.
The patch set introduces the new runtime->buffer_mutex for protecting those. The first patch is the fix for the reported issue (the races with hw_free), while the rest three are more hardening for the other similar executions. Thank you Takashi.
Reviewed-by: Jaroslav Kysela [email protected]
– Jaroslav Kysela [email protected] Linux Sound Maintainer; ALSA Project; Red Hat, Inc.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/4] ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls 2022-03-22 17:07 ` [PATCH 3/4] ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls Takashi Iwai @ 2022-03-23 8:08 ` Amadeusz Sławiński 2022-03-23 8:15 ` Takashi Iwai 0 siblings, 1 reply; 9+ messages in thread From: Amadeusz Sławiński @ 2022-03-23 8:08 UTC (permalink / raw) To: Takashi Iwai, alsa-devel; +Cc: Hu Jiahui, linux-kernel
On 3/22/2022 6:07 PM, Takashi Iwai wrote: > Like the previous fixes to hw_params and hw_free ioctl races, we need
to paper over the concurrent prepare ioctl calls against hw_params and hw_free, too.
This patch implements the locking with the existing runtime->buffer_mutex for prepare ioctls. Unlike the previous case for snd_pcm_hw_hw_params() and snd_pcm_hw_free(), snd_pcm_prepare() is performed to the linked streams, hence the lock can’t be applied simply on the top. For tracking the lock in each linked substream, we modify snd_pcm_action_group() slightly and apply the buffer_mutex for the case stream_lock=false (formerly there was no lock applied) there.
Cc: [email protected] Signed-off-by: Takashi Iwai [email protected]
sound/core/pcm_native.c | 32 +++++++++++++++++±------------- 1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 266895374b83…0e4fbf5fd87b 100644 — a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1190,15 +1190,17 @@ struct action_ops { static int snd_pcm_action_group(const struct action_ops *ops, struct snd_pcm_substream *substream, snd_pcm_state_t state,
bool do\_lock)
bool stream\_lock)
{ struct snd_pcm_substream *s = NULL; struct snd_pcm_substream *s1; int res = 0, depth = 1;
snd\_pcm\_group\_for\_each\_entry(s, substream) {
if (do\_lock && s != substream) {
if (s->pcm->nonatomic)
if (s != substream) {
if (!stream\_lock)
mutex\_lock\_nested(&s->runtime->buffer\_mutex, depth);
else if (s->pcm->nonatomic) mutex\_lock\_nested(&s->self\_group.mutex, depth); else spin\_lock\_nested(&s->self\_group.lock, depth);
Maybe if (!stream_lock) mutex_lock_nested(&s->runtime->buffer_mutex, depth); else snd_pcm_group_lock(&s->self_group, s->pcm->nonatomic); ?
> @@ -1226,18 +1228,18 @@ static int snd_pcm_action_group(const struct action_ops *ops,
ops->post\_action(s, state); }
_unlock:
- if (do_lock) {
/\* unlock streams \*/
snd\_pcm\_group\_for\_each\_entry(s1, substream) {
if (s1 != substream) {
if (s1->pcm->nonatomic)
mutex\_unlock(&s1->self\_group.mutex);
else
spin\_unlock(&s1->self\_group.lock);
}
if (s1 == s) /\* end \*/
break;
- /* unlock streams */
- snd_pcm_group_for_each_entry(s1, substream) {
if (s1 != substream) {
if (!stream\_lock)
mutex\_unlock(&s1->runtime->buffer\_mutex);
else if (s1->pcm->nonatomic)
mutex\_unlock(&s1->self\_group.mutex);
else
spin\_unlock(&s1->self\_group.lock);
And similarly to above, use snd_pcm_group_unlock() here?
> }
if (s1 == s) /\* end \*/
break; } return res;
} @@ -1367,10 +1369,12 @@ static int snd_pcm_action_nonatomic(const struct action_ops *ops,
/\* Guarantee the group members won't change during non-atomic action \*/ down\_read(&snd\_pcm\_link\_rwsem);
mutex_lock(&substream->runtime->buffer_mutex); if (snd_pcm_stream_linked(substream)) res = snd_pcm_action_group(ops, substream, state, false); else res = snd_pcm_action_single(ops, substream, state);
mutex_unlock(&substream->runtime->buffer_mutex); up_read(&snd_pcm_link_rwsem); return res; }
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/4] ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls 2022-03-23 8:08 ` Amadeusz Sławiński @ 2022-03-23 8:15 ` Takashi Iwai 2022-03-23 8:22 ` Takashi Iwai 0 siblings, 1 reply; 9+ messages in thread From: Takashi Iwai @ 2022-03-23 8:15 UTC (permalink / raw) To: Amadeusz SX2awiX4ski; +Cc: alsa-devel, Hu Jiahui, linux-kernel
On Wed, 23 Mar 2022 09:08:25 +0100, Amadeusz SX2awiX4ski wrote: >
On 3/22/2022 6:07 PM, Takashi Iwai wrote:
Like the previous fixes to hw_params and hw_free ioctl races, we need to paper over the concurrent prepare ioctl calls against hw_params and hw_free, too.
This patch implements the locking with the existing runtime->buffer_mutex for prepare ioctls. Unlike the previous case for snd_pcm_hw_hw_params() and snd_pcm_hw_free(), snd_pcm_prepare() is performed to the linked streams, hence the lock can’t be applied simply on the top. For tracking the lock in each linked substream, we modify snd_pcm_action_group() slightly and apply the buffer_mutex for the case stream_lock=false (formerly there was no lock applied) there.
Cc: [email protected] Signed-off-by: Takashi Iwai [email protected]
sound/core/pcm_native.c | 32 +++++++++++++++++±------------- 1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 266895374b83…0e4fbf5fd87b 100644 — a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1190,15 +1190,17 @@ struct action_ops { static int snd_pcm_action_group(const struct action_ops *ops, struct snd_pcm_substream *substream, snd_pcm_state_t state,
bool do\_lock)
{ struct snd_pcm_substream *s = NULL; struct snd_pcm_substream *s1; int res = 0, depth = 1; snd_pcm_group_for_each_entry(s, substream) {bool stream\_lock)
if (do\_lock && s != substream) {
if (s->pcm->nonatomic)
if (s != substream) {
if (!stream\_lock)
mutex\_lock\_nested(&s->runtime->buffer\_mutex, depth);
else if (s->pcm->nonatomic) mutex\_lock\_nested(&s->self\_group.mutex, depth); else spin\_lock\_nested(&s->self\_group.lock, depth);
Maybe if (!stream_lock) mutex_lock_nested(&s->runtime->buffer_mutex, depth); else snd_pcm_group_lock(&s->self_group, s->pcm->nonatomic); ? No, it must be nested locks with the given subclass. That’s why it has been the open code beforehand, too.
> > @@ -1226,18 +1228,18 @@ static int snd_pcm_action_group(const struct action_ops *ops,
ops->post\_action(s, state); }
_unlock:
- if (do_lock) {
/\* unlock streams \*/
snd\_pcm\_group\_for\_each\_entry(s1, substream) {
if (s1 != substream) {
if (s1->pcm->nonatomic)
mutex\_unlock(&s1->self\_group.mutex);
else
spin\_unlock(&s1->self\_group.lock);
}
if (s1 == s) /\* end \*/
break;
- /* unlock streams */
- snd_pcm_group_for_each_entry(s1, substream) {
if (s1 != substream) {
if (!stream\_lock)
mutex\_unlock(&s1->runtime->buffer\_mutex);
else if (s1->pcm->nonatomic)
mutex\_unlock(&s1->self\_group.mutex);
else
spin\_unlock(&s1->self\_group.lock);
And similarly to above, use snd_pcm_group_unlock() here? This side would be possible to use that macro but it’s still better to have the consistent call pattern.
thanks,
Takashi
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/4] ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls 2022-03-23 8:15 ` Takashi Iwai @ 2022-03-23 8:22 ` Takashi Iwai 0 siblings, 0 replies; 9+ messages in thread From: Takashi Iwai @ 2022-03-23 8:22 UTC (permalink / raw) To: Amadeusz SX2awiX4ski; +Cc: alsa-devel, Hu Jiahui, linux-kernel
On Wed, 23 Mar 2022 09:15:19 +0100, Takashi Iwai wrote: >
On Wed, 23 Mar 2022 09:08:25 +0100, Amadeusz SX2awiX4ski wrote:
On 3/22/2022 6:07 PM, Takashi Iwai wrote:
Like the previous fixes to hw_params and hw_free ioctl races, we need to paper over the concurrent prepare ioctl calls against hw_params and hw_free, too.
This patch implements the locking with the existing runtime->buffer_mutex for prepare ioctls. Unlike the previous case for snd_pcm_hw_hw_params() and snd_pcm_hw_free(), snd_pcm_prepare() is performed to the linked streams, hence the lock can’t be applied simply on the top. For tracking the lock in each linked substream, we modify snd_pcm_action_group() slightly and apply the buffer_mutex for the case stream_lock=false (formerly there was no lock applied) there.
Cc: [email protected] Signed-off-by: Takashi Iwai [email protected]
sound/core/pcm_native.c | 32 +++++++++++++++++±------------- 1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 266895374b83…0e4fbf5fd87b 100644 — a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1190,15 +1190,17 @@ struct action_ops { static int snd_pcm_action_group(const struct action_ops *ops, struct snd_pcm_substream *substream, snd_pcm_state_t state,
bool do\_lock)
{ struct snd_pcm_substream *s = NULL; struct snd_pcm_substream *s1; int res = 0, depth = 1; snd_pcm_group_for_each_entry(s, substream) {bool stream\_lock)
if (do\_lock && s != substream) {
if (s->pcm->nonatomic)
if (s != substream) {
if (!stream\_lock)
mutex\_lock\_nested(&s->runtime->buffer\_mutex, depth);
else if (s->pcm->nonatomic) mutex\_lock\_nested(&s->self\_group.mutex, depth); else spin\_lock\_nested(&s->self\_group.lock, depth);
Maybe if (!stream_lock) mutex_lock_nested(&s->runtime->buffer_mutex, depth); else snd_pcm_group_lock(&s->self_group, s->pcm->nonatomic); ?
No, it must be nested locks with the given subclass. FWIW, the reason is that lockdep would complain otherwise as if it were a deadlock. That is, this is a workaround for avoiding false lockdep warnings.
Takashi
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-03-23 8:22 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) – links below jump to the message on this page – 2022-03-22 17:07 [PATCH 0/4] ALSA: pcm: Fix ioctl races Takashi Iwai 2022-03-22 17:07 ` [PATCH 1/4] ALSA: pcm: Fix races among concurrent hw_params and hw_free calls Takashi Iwai 2022-03-22 17:07 ` [PATCH 2/4] ALSA: pcm: Fix races among concurrent read/write and buffer changes Takashi Iwai 2022-03-22 17:07 ` [PATCH 3/4] ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls Takashi Iwai 2022-03-23 8:08 ` Amadeusz Sławiński 2022-03-23 8:15 ` Takashi Iwai 2022-03-23 8:22 ` Takashi Iwai 2022-03-22 17:07 ` [PATCH 4/4] ALSA: pcm: Fix races among concurrent prealloc proc writes Takashi Iwai 2022-03-22 17:14 ` [PATCH 0/4] ALSA: pcm: Fix ioctl races Jaroslav Kysela
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).
Related news
A privilege escalation flaw was found in Podman. This flaw allows an attacker to publish a malicious image to a public registry. Once this image is downloaded by a potential victim, the vulnerability is triggered after a user runs the 'podman top' command. This action gives the attacker access to the host filesystem, leading to information disclosure or denial of service.
Insufficient capability checks could allow users with the moodle/site:uploadusers capability to delete users, without having the necessary moodle/user:delete capability.
A heap-use-after-free flaw was found in ImageMagick's RelinquishDCMInfo() function of dcm.c file. This vulnerability is triggered when an attacker passes a specially crafted DICOM image file to ImageMagick for conversion, potentially leading to information disclosure and a denial of service.
A NULL pointer dereference flaw was found in pesign's cms_set_pw_data() function of the cms_common.c file. The function fails to handle the NULL pwdata invocation from daemon.c, which leads to an explicit NULL dereference and crash on all attempts to daemonize pesign.
IBM UrbanCode Deploy (UCD) 7.1.1.2 uses weaker than expected cryptographic algorithms that could allow an attacker to decrypt highly sensitive information.
A flaw was found in the Linux kernel in linux/net/netfilter/nf_tables_api.c of the netfilter subsystem. This flaw allows a local user to cause an out-of-bounds write issue.
A use-after-free vulnerability was found in the Linux kernel in drivers/net/hamradio. This flaw allows a local attacker with a user privilege to cause a denial of service (DOS) when the mkiss or sixpack device is detached and reclaim resources early.
A vulnerability was found in the pfkey_register function in net/key/af_key.c in the Linux kernel. This flaw allows a local, unprivileged user to gain access to kernel memory, leading to a system crash or a leak of internal kernel information.
A cross-site scripting (XSS) vulnerability exists in the "contact us" plugin for Subrion CMS <= 4.2.1 version via "List of subjects".
Piano LED Visualizer is software that allows LED lights to light up as a person plays a piano connected to a computer. Version 1.3 and prior are vulnerable to a path traversal attack. The `os.path.join` call is unsafe for use with untrusted input. When the `os.path.join` call encounters an absolute path, it ignores all the parameters it has encountered till that point and starts working with the new absolute path. Since the "malicious" parameter represents an absolute path, the result of `os.path.join` ignores the static directory completely. Hence, untrusted input is passed via the `os.path.join` call to `flask.send_file` can lead to path traversal attacks. A patch with a fix is available on the `master` branch of the GitHub repository. This can also be fixed by preventing flow of untrusted data to the vulnerable `send_file` function. In case the application logic necessiates this behaviour, one can either use the `flask.safe_join` to join untrusted paths or replace `flask.send_file` ...
A vulnerability has been found in automad up to 1.10.9 and classified as problematic. This vulnerability affects the Dashboard. The manipulation of the argument title with the input Home</title><script>alert("home")</script><title> leads to a cross site scripting. The attack can be initiated remotely but requires an authentication. The exploit details have disclosed to the public and may be used.
Exclusive Threatpost research examines organizations’ top cloud security concerns, attitudes towards zero-trust and DevSecOps.
Buffer Over-read in GitHub repository bfabiszewski/libmobi prior to 0.11. This vulnerability is capable of arbitrary code execution.
SQL injection vulnerability in ARAX-UI Synonym Lookup functionality in GitHub repository rtxteam/rtx prior to checkpoint_2022-04-20 . This vulnerability is critical as it can lead to remote code execution and thus complete server takeover.
FacturaScripts prior to version 2022.06 is vulnerable to stored cross-site scripting via upload plugin functionality in zip format.
Solar appScreener through 3.10.4, when a valid license is not present, allows XXE and SSRF attacks via a crafted XML document.
zend-diactoros (and, by extension, Expressive), zend-http (and, by extension, Zend Framework MVC projects), and zend-feed (specifically, its PubSubHubbub sub-component) each contain a potential URL rewrite exploit. In each case, marshaling a request URI includes logic that introspects HTTP request headers that are specific to a given server-side URL rewrite mechanism. When these headers are present on systems not running the specific URL rewriting mechanism, the logic would still trigger, allowing a malicious client or proxy to emulate the headers to request arbitrary content.
### Impact Multiple tokens for password reset could be requested. All tokens could be used to change the password. This makes it possible for an attacker to take over the victims account if s/he gains access to the victims email account and finds unused password reset token in the emails within the time frame of two hours. ### Patches We recommend updating to the current version 5.7.9. You can get the update to 5.7.9 regularly via the Auto-Updater or directly via the download overview. https://www.shopware.com/en/changelog-sw5/#5-7-9 For older versions you can use the Security Plugin: https://store.shopware.com/en/swag575294366635f/shopware-security-plugin.html ### References https://docs.shopware.com/en/shopware-5-en/security-updates/security-update-04-2022
### Impact The CSRF tokens were not renewed after login and logout. An attacker could impersonate the victim if the attacker is able to use the same device as the victim used beforehand. ### Patches We recommend updating to the current version 5.7.9. You can get the update to 5.7.9 regularly via the Auto-Updater or directly via the download overview. https://www.shopware.com/en/changelog-sw5/#5-7-9 For older versions you can use the Security Plugin: https://store.shopware.com/en/swag575294366635f/shopware-security-plugin.html ### References https://docs.shopware.com/en/shopware-5-en/security-updates/security-update-04-2022
A POST based reflected Cross Site Scripting vulnerability on has been identified in Keycloak. When a malicious request is sent to the client registration endpoint, the error message is not properly escaped, allowing an attacker to execute malicious scripts into the user's browser. ### Acknowledgement Keycloak would like to thank Quentin TEXIER (Pentester at Opencyber) for reporting this issue.
### Impact Not-stored XSS in storefront. Request parameter were directly assigned to the template, so that malicious code could be send via an URL. ### Patches We recommend updating to the current version 5.7.9. You can get the update to 5.7.9 regularly via the Auto-Updater or directly via the download overview. https://www.shopware.com/en/changelog-sw5/#5-7-9 For older versions you can use the Security Plugin: https://store.shopware.com/en/swag575294366635f/shopware-security-plugin.html ### References https://docs.shopware.com/en/shopware-5-en/security-updates/security-update-04-2022
IBM InfoSphere Information Server 11.7 is vulnerable to cross-site scripting. This vulnerability allows users to embed arbitrary JavaScript code in the Web UI thus altering the intended functionality potentially leading to credentials disclosure within a trusted session. IBM X-Force ID: 218370.
IBM InfoSphere Information Server 11.7 is vulnerable to cross-site scripting. This vulnerability allows users to embed arbitrary JavaScript code in the Web UI thus altering the intended functionality potentially leading to credentials disclosure within a trusted session. IBM X-Force ID: 223720.
Mahara before 20.10.5, 21.04.4, 21.10.2, and 22.04.0 allows stored XSS when a particular Cascading Style Sheets (CSS) class for embedly is used, and JavaScript code is constructed to perform an action.
IBM InfoSphere Information Server 11.7 could allow an authenticated user to view information of higher privileged users and groups due to a privilege escalation vulnerability. IBM X-Force ID: 224426.
IBM InfoSphere Information Server 11.7 is vulnerable to cross-site scripting. This vulnerability allows users to embed arbitrary JavaScript code in the Web UI thus altering the intended functionality potentially leading to credentials disclosure within a trusted session. IBM X-Force ID: 211408.
In Mahara before 20.10.5, 21.04.4, 21.10.2, and 22.04.0, a site using Isolated Institutions is vulnerable if more than ten groups are used. They are all shown from page 2 of the group results list (rather than only being shown for the institution that the viewer is a member of).
IBM InfoSphere Information Server 11.7 is vulnerable to cross-site scripting. This vulnerability allows users to embed arbitrary JavaScript code in the Web UI thus altering the intended functionality potentially leading to credentials disclosure within a trusted session. IBM X-Force ID: 224440.
Shopware is an open source e-commerce software platform. Prior to version 5.7.9, Shopware is vulnerable to non-stored cross-site scripting in the storefront. This issue is fixed in version 5.7.9. Users of older versions may attempt to mitigate the vulnerability by using the Shopware security plugin.
A cross-site scripting (XSS) vulnerability in PHP MySQL Admin Panel Generator v1 allows attackers to execute arbitrary web scripts or HTML via a crafted payload injected at /edit-db.php.
NVIDIA Jetson Linux Driver Package contains a vulnerability in the Cboot module tegrabl_cbo.c, where insufficient validation of untrusted data may allow a local attacker to cause a memory buffer overflow, which may lead to code execution, loss of integrity, limited denial of service, and some impact to confidentiality.
IBM UrbanCode Deploy (UCD) 7.2.2.1 could allow an authenticated user with special permissions to obtain elevated privileges due to improper handling of permissions. IBM X-Force ID: 217955.
Linksys MR9600 devices before 2.0.5 allow attackers to read arbitrary files via a symbolic link to the root directory of a NAS SMB share.