lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <TYCP286MB1188FEE149369A32D90DCE288A21A@TYCP286MB1188.JPNP286.PROD.OUTLOOK.COM>
Date:   Sun, 25 Jun 2023 15:35:48 +0000
From:   YE Chengfeng <cyeaa@...nect.ust.hk>
To:     "perex@...ex.cz" <perex@...ex.cz>,
        "tiwai@...e.com" <tiwai@...e.com>,
        "yunjunlee@...omium.org" <yunjunlee@...omium.org>
CC:     "alsa-devel@...a-project.org" <alsa-devel@...a-project.org>,
        "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: [PATCH] ALSA: dummy: Fix &dpcm->lock deadlock issues

The timer dummy_systimer_callback is executed under softirq
context, thus other process context code requiring the same lock
should disable interrupt. Otherwise there would be potential
deadlock issues when the code executing under process context
(i.e., dummy_systimer_pointer, dummy_systimer_start,
dummy_systimer_stop) is preempted by the timer while holding
the lock.

Deadlock scenario:
dummy_systimer_pointer
    -> spin_lock(&dpcm->lock);
        <timer interrupt>
        -> dummy_systimer_callback
        -> spin_lock_irqsave(&dpcm->lock, flags);

Fix the potential deadlock by using spin_lock_irqsave.

Signed-off-by: Chengfeng Ye <cyeaa@...nect.ust.hk>
---
 sound/drivers/dummy.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 9c17b49a2ae1..04fb4f17e05c 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -268,19 +268,23 @@ static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm)
 static int dummy_systimer_start(struct snd_pcm_substream *substream)
 {
 	struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
-	spin_lock(&dpcm->lock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&dpcm->lock, flags);
 	dpcm->base_time = jiffies;
 	dummy_systimer_rearm(dpcm);
-	spin_unlock(&dpcm->lock);
+	spin_unlock_irqrestore(&dpcm->lock, flags);
 	return 0;
 }
 
 static int dummy_systimer_stop(struct snd_pcm_substream *substream)
 {
 	struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
-	spin_lock(&dpcm->lock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&dpcm->lock, flags);
 	del_timer(&dpcm->timer);
-	spin_unlock(&dpcm->lock);
+	spin_unlock_irqrestore(&dpcm->lock, flags);
 	return 0;
 }
 
@@ -320,11 +324,12 @@ dummy_systimer_pointer(struct snd_pcm_substream *substream)
 {
 	struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
 	snd_pcm_uframes_t pos;
+	unsigned long flags;
 
-	spin_lock(&dpcm->lock);
+	spin_lock_irqsave(&dpcm->lock, flags);
 	dummy_systimer_update(dpcm);
 	pos = dpcm->frac_pos / HZ;
-	spin_unlock(&dpcm->lock);
+	spin_unlock_irqrestore(&dpcm->lock, flags);
 	return pos;
 }
 
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ