From patchwork Tue Mar 22 17:07:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 553759 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B5FC2C433F5 for ; Tue, 22 Mar 2022 17:09:16 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 04A3E1754; Tue, 22 Mar 2022 18:08:25 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 04A3E1754 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647968955; bh=nsCjBKWO3dGoxyBjYCc34SQRlEMZfaMK2/nmphP0QFU=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=qSem029c7g/KCkvVJtbHCGY9NnB7UvD6ghVyMrETUycaMvIXnkZtXXytwclTZ++VC aqYovVg1ARMhe34mSJYMaMsRBk2io8n4tOot98pKAyUW6tAn72uT/DVjYxYpJEzwN2 ZW9KeuJeLhkOUbReQeA7dV+FWr/jhi+x1DLrHpSU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 79126F800FD; Tue, 22 Mar 2022 18:07:55 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0D5B5F804C1; Tue, 22 Mar 2022 18:07:54 +0100 (CET) Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id CEF99F800FD for ; Tue, 22 Mar 2022 18:07:47 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CEF99F800FD Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.b="axLGYK+2"; dkim=permerror (0-bit key) header.d=suse.de header.i=@suse.de header.b="aX3VigDl" Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 275341F388; Tue, 22 Mar 2022 17:07:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1647968867; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6fbhaIjiu6I6EYFCJgaK9dNKTeI2PHW3Jz9RETaj5Jk=; b=axLGYK+2eJqTAJT6AHwmEIH2U+zTkwMYlcdhFT7LRom+FJXzPKxvwg+RaCCZc503Re/r5C kq9E+oxOaRFihY8MoEqPkouhqiqpetEgtorCvY2jvEeu1zPgOom4ShlSk3Rr4XRQ/JFAP7 2yze0edDeIIrOxb3xK53QZHsc6NwDPo= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1647968867; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6fbhaIjiu6I6EYFCJgaK9dNKTeI2PHW3Jz9RETaj5Jk=; b=aX3VigDl4w5EpjgURghWRhJ2jtP/06Qj1oO4MCdBmYw+Eawp0xU3uOmfyup3bVh2hYpgUf apeQK+8RRo1jHkCg== Received: from alsa1.nue.suse.com (alsa1.suse.de [10.160.4.42]) by relay2.suse.de (Postfix) with ESMTP id 14899A3B88; Tue, 22 Mar 2022 17:07:47 +0000 (UTC) From: Takashi Iwai To: alsa-devel@alsa-project.org Subject: [PATCH 1/4] ALSA: pcm: Fix races among concurrent hw_params and hw_free calls Date: Tue, 22 Mar 2022 18:07:17 +0100 Message-Id: <20220322170720.3529-2-tiwai@suse.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220322170720.3529-1-tiwai@suse.de> References: <20220322170720.3529-1-tiwai@suse.de> MIME-Version: 1.0 Cc: Hu Jiahui , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" 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 Cc: Signed-off-by: Takashi Iwai --- 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; + 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); @@ -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; + 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; } From patchwork Tue Mar 22 17:07:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 553481 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ED74CC433EF for ; Tue, 22 Mar 2022 17:09:35 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 916DF1755; Tue, 22 Mar 2022 18:08:43 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 916DF1755 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647968973; bh=JL/k4Ka8fzJXduoKYXRgWCPLM/E0X+aSAyMZSIdD67w=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=vVcrQanQGRre6ew8qqM7tisbpzc3jqymSrrfz4d4K2n3cyDMO1zE48BFR/x5LbHu4 h+Vet9ugb3qJPYxCXXMlowrAY2FFBrbgU4go9nuLesyFmKaU2lxUMZK0EhAp+DYVZU fVI2LU1h/1Aq1IE+q/NlxBA8pmws193VZXOONuUY= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 480B6F804C1; Tue, 22 Mar 2022 18:07:57 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id BED84F80517; Tue, 22 Mar 2022 18:07:55 +0100 (CET) Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 9A622F8012A for ; Tue, 22 Mar 2022 18:07:47 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 9A622F8012A Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.b="lpqB+3ia"; dkim=permerror (0-bit key) header.d=suse.de header.i=@suse.de header.b="DZNpQcmb" Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 2B6DF1F38C; Tue, 22 Mar 2022 17:07:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1647968867; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7BHpLrva0gn3z4ug3sivlVXdf446dwWnsWltmnc0TZg=; b=lpqB+3ia31feVNsJ+xBeXoPm6qiplwLJhmVWhDZV/IyaXPbcHw3SGJXSzRSs4AC4A/GUng pBBP5SQ+ligtAPpdNJZTRXrE3fhB8LOcXqKJ7LFW4xGGBNLbjQpvNsX2O/aL9VemqGMYlB 53hv0qnsSQn2sro/BM4Y8R47P1laEwE= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1647968867; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7BHpLrva0gn3z4ug3sivlVXdf446dwWnsWltmnc0TZg=; b=DZNpQcmbWVN9G8MQ1OCIhMSCIW7VkpTffNB6yrufNEyRTH9rnv6dvK62Km/q4i3NvKX5TL dXqcSVcCEbXCNUDA== Received: from alsa1.nue.suse.com (alsa1.suse.de [10.160.4.42]) by relay2.suse.de (Postfix) with ESMTP id 25492A3B87; Tue, 22 Mar 2022 17:07:47 +0000 (UTC) From: Takashi Iwai To: alsa-devel@alsa-project.org Subject: [PATCH 2/4] ALSA: pcm: Fix races among concurrent read/write and buffer changes Date: Tue, 22 Mar 2022 18:07:18 +0100 Message-Id: <20220322170720.3529-3-tiwai@suse.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220322170720.3529-1-tiwai@suse.de> References: <20220322170720.3529-1-tiwai@suse.de> MIME-Version: 1.0 Cc: Hu Jiahui , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" 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: Signed-off-by: Takashi Iwai --- 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); From patchwork Tue Mar 22 17:07:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 553758 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 17EDBC433EF for ; Tue, 22 Mar 2022 17:09:52 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 2459E1746; Tue, 22 Mar 2022 18:09:00 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 2459E1746 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647968990; bh=8qle0TCC7KetuGvNnXKvDZIJZE065J65JBk6IwB9Es0=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=F5OKPu5loiu86/7V6PgC5tuy+okvhjrz5tU/tsiJ2j37pj9lw7BQvIa8uSBQvDeCN jAMgOtLbtVq9JepCqRb5t/eN1jdF5ABjQ8EmPb6m29A+y5OEiVkCgYZ0+YKqfPUeSF FLeDoiH0QM7xIg+nqV72QXNAeHGCDxuHZMd6jXdw= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id D19DBF8051A; Tue, 22 Mar 2022 18:07:57 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id CE14DF804C1; Tue, 22 Mar 2022 18:07:55 +0100 (CET) Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id BF9E2F8032D for ; Tue, 22 Mar 2022 18:07:47 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz BF9E2F8032D Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.b="Vw95QBvC"; dkim=permerror (0-bit key) header.d=suse.de header.i=@suse.de header.b="OU5aFBrD" Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id 3AB67210F0; Tue, 22 Mar 2022 17:07:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1647968867; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OKjFtB5KBr9W4w3NflnR7TkFxvAb0C5HMxfUzYIzr7s=; b=Vw95QBvC7cbTiU9SNUtLQSonYr3TkhQcan8iNTv8RiCH8N1dR+YThU56V5EDKHoqkvvrUO ZzvOcAW8EFpXpuZUKdhywBM/+IHGdAZM+/2uurakRCxllv4CKA5qHde1H122A1vQsT1pdO W0wKG48wPmQeihrQTEG9036FwahmFNk= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1647968867; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OKjFtB5KBr9W4w3NflnR7TkFxvAb0C5HMxfUzYIzr7s=; b=OU5aFBrDmu/SozBe6LOmSsOl+7vDH57qPQHFE/j9z8rXUuMYXfJbFMfrYXrZUo6aRgnhzl wdUl6cLEyeF+L9DQ== Received: from alsa1.nue.suse.com (alsa1.suse.de [10.160.4.42]) by relay2.suse.de (Postfix) with ESMTP id 29758A3B89; Tue, 22 Mar 2022 17:07:47 +0000 (UTC) From: Takashi Iwai To: alsa-devel@alsa-project.org Subject: [PATCH 3/4] ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls Date: Tue, 22 Mar 2022 18:07:19 +0100 Message-Id: <20220322170720.3529-4-tiwai@suse.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220322170720.3529-1-tiwai@suse.de> References: <20220322170720.3529-1-tiwai@suse.de> MIME-Version: 1.0 Cc: Hu Jiahui , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" 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: Signed-off-by: Takashi Iwai --- 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; } From patchwork Tue Mar 22 17:07:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 553480 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7AE7AC433EF for ; Tue, 22 Mar 2022 17:10:06 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id BE52F174B; Tue, 22 Mar 2022 18:09:14 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz BE52F174B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1647969004; bh=KAormVgH8Kif3qqCfNO5+GOjtb3ughnVbLlzmt4Q9CI=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=miFUhFyS+7OszMSC/jEgky3YUxLJDdW8AR8/L1+RPMAuZbUR6P7T7MPQP7eNvfxGU DCUQwaJw2zX7rCfQoGRUvUOKEZ4WCjhrN6/wUdXBPRZ77oXuzDtitM1d+oJ6EkO32z c4U5wOOCxT0znMJMjlNmwwfRkgWwFLVcXqUcrbcI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 8300EF8051D; Tue, 22 Mar 2022 18:08:00 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 07CF6F8051D; Tue, 22 Mar 2022 18:07:58 +0100 (CET) Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id B6FAAF804B2 for ; Tue, 22 Mar 2022 18:07:47 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz B6FAAF804B2 Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.b="zkL58OMq"; dkim=permerror (0-bit key) header.d=suse.de header.i=@suse.de header.b="OVOtNP13" Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id 3F0E5210F1; Tue, 22 Mar 2022 17:07:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1647968867; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+CYXBkEmUaFG3FfKkSPLLXjGyKZ1eQzGvz99I1XhLxQ=; b=zkL58OMq5m9rO+mLy98V1NI+YcCjw1sPmH4arSaidEYt8b3J5LHZLPI5xNWbPK5OK/XHGS YKojgiwsW6+AM0WTiSUzUctuvpFi2ogMBvAtSIEMjI485eFC7XYJ4AU+RsBSltuJY7b9PO aWKS4yTdvUmMa8ldC+Wz56/+mhwp1Xg= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1647968867; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+CYXBkEmUaFG3FfKkSPLLXjGyKZ1eQzGvz99I1XhLxQ=; b=OVOtNP13gEiVstfwWb2gabKAA+rWqAJDUALsnyA4f0dE5OpRRbkr8cLGA9FcJXEKvFfMNq /QqEQubfoFJbDrDQ== Received: from alsa1.nue.suse.com (alsa1.suse.de [10.160.4.42]) by relay2.suse.de (Postfix) with ESMTP id 388C5A3B87; Tue, 22 Mar 2022 17:07:47 +0000 (UTC) From: Takashi Iwai To: alsa-devel@alsa-project.org Subject: [PATCH 4/4] ALSA: pcm: Fix races among concurrent prealloc proc writes Date: Tue, 22 Mar 2022 18:07:20 +0100 Message-Id: <20220322170720.3529-5-tiwai@suse.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220322170720.3529-1-tiwai@suse.de> References: <20220322170720.3529-1-tiwai@suse.de> MIME-Version: 1.0 Cc: Hu Jiahui , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" 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: Signed-off-by: Takashi Iwai --- 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; + goto unlock; } 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; } 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)