From patchwork Fri Aug 26 20:50:08 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 9302057 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3A618607D8 for ; Fri, 26 Aug 2016 20:51:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2C1322955D for ; Fri, 26 Aug 2016 20:51:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 20EF52964C; Fri, 26 Aug 2016 20:51:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5F9FD2955D for ; Fri, 26 Aug 2016 20:51:23 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 9F8DD267163; Fri, 26 Aug 2016 22:51:22 +0200 (CEST) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id B960B266685; Fri, 26 Aug 2016 22:50:26 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id BBF8626666A; Fri, 26 Aug 2016 22:50:22 +0200 (CEST) Received: from smtp-proxy003.phy.lolipop.jp (smtp-proxy003.phy.lolipop.jp [157.7.104.44]) by alsa0.perex.cz (Postfix) with ESMTP id E488C266626 for ; Fri, 26 Aug 2016 22:50:14 +0200 (CEST) Received: from smtp-proxy003.phy.lolipop.lan (HELO smtp-proxy003.phy.lolipop.jp) (172.19.44.44) (smtp-auth username m12129643-o-takashi, mechanism plain) by smtp-proxy003.phy.lolipop.jp (qpsmtpd/0.82) with ESMTPA; Sat, 27 Aug 2016 05:50:11 +0900 Received: from 127.0.0.1 (127.0.0.1) by smtp-proxy003.phy.lolipop.jp (LOLIPOP-Fsecure); Sat, 27 Aug 2016 05:50:09 +0900 (JST) X-Virus-Status: clean(LOLIPOP-Fsecure) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de Date: Sat, 27 Aug 2016 05:50:08 +0900 Message-Id: <1472244609-31830-2-git-send-email-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1472244609-31830-1-git-send-email-o-takashi@sakamocchi.jp> References: <1472244609-31830-1-git-send-email-o-takashi@sakamocchi.jp> Cc: vaishali.thakkar@oracle.com, alsa-devel@alsa-project.org, stable@vger.kernel.org, ffado-devel@lists.sf.net Subject: [alsa-devel] [PATCH 1/2] ALSA: fireworks: accessing to user space outside spinlock X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 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: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP In hwdep interface of fireworks driver, accessing to user space is in a critical section with disabled local interrupt. Depending on architecture, accessing to user space can cause page fault exception. Then local processor stores machine status and handles the synchronous event. A handler corresponding to the event can call task scheduler to wait for preparing pages. In a case of usage of single core processor, the state to disable local interrupt is worse because it don't handle usual interrupts from hardware. This commit fixes this bug, performing the accessing outside spinlock. Reported-by: Vaishali Thakkar Cc: stable@vger.kernel.org Fixes: 555e8a8f7f14('ALSA: fireworks: Add command/response functionality into hwdep interface') Signed-off-by: Takashi Sakamoto --- sound/firewire/fireworks/fireworks_hwdep.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/sound/firewire/fireworks/fireworks_hwdep.c b/sound/firewire/fireworks/fireworks_hwdep.c index 33df865..b4c3f57 100644 --- a/sound/firewire/fireworks/fireworks_hwdep.c +++ b/sound/firewire/fireworks/fireworks_hwdep.c @@ -38,6 +38,7 @@ hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, long remained, buf += sizeof(type); /* write into buffer as many responses as possible */ + spin_lock_irq(&efw->lock); while (efw->resp_queues > 0) { t = (struct snd_efw_transaction *)(efw->pull_ptr); length = be32_to_cpu(t->length) * sizeof(__be32); @@ -52,9 +53,13 @@ hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, long remained, (unsigned int)(efw->pull_ptr - efw->resp_buf); till_end = min_t(unsigned int, length, till_end); + spin_unlock_irq(&efw->lock); + if (copy_to_user(buf, efw->pull_ptr, till_end)) return -EFAULT; + spin_lock_irq(&efw->lock); + efw->pull_ptr += till_end; if (efw->pull_ptr >= efw->resp_buf + snd_efw_resp_buf_size) @@ -69,6 +74,8 @@ hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, long remained, efw->resp_queues--; } + spin_unlock_irq(&efw->lock); + return count; } @@ -76,14 +83,17 @@ static long hwdep_read_locked(struct snd_efw *efw, char __user *buf, long count, loff_t *offset) { - union snd_firewire_event event; - - memset(&event, 0, sizeof(event)); + union snd_firewire_event event = {0}; event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; + + spin_lock_irq(&efw->lock); + event.lock_status.status = (efw->dev_lock_count > 0); efw->dev_lock_changed = false; + spin_unlock_irq(&efw->lock); + count = min_t(long, count, sizeof(event.lock_status)); if (copy_to_user(buf, &event, count)) @@ -111,13 +121,13 @@ hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, spin_lock_irq(&efw->lock); } + spin_unlock_irq(&efw->lock); + if (efw->dev_lock_changed) count = hwdep_read_locked(efw, buf, count, offset); else if (efw->resp_queues > 0) count = hwdep_read_resp_buf(efw, buf, count, offset); - spin_unlock_irq(&efw->lock); - return count; }