Takashi Iwai 20bbd4
From 3e7e04b747adea36f349715d9f0998eeebf15d72 Mon Sep 17 00:00:00 2001
Takashi Iwai 20bbd4
From: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 20bbd4
Date: Tue, 23 Aug 2022 09:27:17 +0200
Takashi Iwai 20bbd4
Subject: [PATCH] ALSA: seq: Fix data-race at module auto-loading
Takashi Iwai 20bbd4
Git-commit: 3e7e04b747adea36f349715d9f0998eeebf15d72
Takashi Iwai 20bbd4
Patch-mainline: v6.0-rc4
Takashi Iwai 20bbd4
References: git-fixes
Takashi Iwai 20bbd4
Takashi Iwai 20bbd4
It's been reported that there is a possible data-race accessing to the
Takashi Iwai 20bbd4
global card_requested[] array at ALSA sequencer core, which is used
Takashi Iwai 20bbd4
for determining whether to call request_module() for the card or not.
Takashi Iwai 20bbd4
This data race itself is almost harmless, as it might end up with one
Takashi Iwai 20bbd4
extra request_module() call for the already loaded module at most.
Takashi Iwai 20bbd4
But it's still better to fix.
Takashi Iwai 20bbd4
Takashi Iwai 20bbd4
This patch addresses the possible data race of card_requested[] and
Takashi Iwai 20bbd4
client_requested[] arrays by replacing them with bitmask.
Takashi Iwai 20bbd4
It's an atomic operation and can work without locks.
Takashi Iwai 20bbd4
Takashi Iwai 20bbd4
Reported-by: Abhishek Shah <abhishek.shah@columbia.edu>
Takashi Iwai 20bbd4
Cc: <stable@vger.kernel.org>
Takashi Iwai 20bbd4
Link: https://lore.kernel.org/r/CAEHB24_ay6YzARpA1zgCsE7=H9CSJJzux618E=Ka4h0YdKn=qA@mail.gmail.com
Takashi Iwai 20bbd4
Link: https://lore.kernel.org/r/20220823072717.1706-2-tiwai@suse.de
Takashi Iwai 20bbd4
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 20bbd4
Takashi Iwai 20bbd4
---
Takashi Iwai 20bbd4
 sound/core/seq/seq_clientmgr.c | 12 +++++-------
Takashi Iwai 20bbd4
 1 file changed, 5 insertions(+), 7 deletions(-)
Takashi Iwai 20bbd4
Takashi Iwai 20bbd4
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
Takashi Iwai 20bbd4
index 2e9d695d336c..2d707afa1ef1 100644
Takashi Iwai 20bbd4
--- a/sound/core/seq/seq_clientmgr.c
Takashi Iwai 20bbd4
+++ b/sound/core/seq/seq_clientmgr.c
Takashi Iwai 20bbd4
@@ -121,13 +121,13 @@ struct snd_seq_client *snd_seq_client_use_ptr(int clientid)
Takashi Iwai 20bbd4
 	spin_unlock_irqrestore(&clients_lock, flags);
Takashi Iwai 20bbd4
 #ifdef CONFIG_MODULES
Takashi Iwai 20bbd4
 	if (!in_interrupt()) {
Takashi Iwai 20bbd4
-		static char client_requested[SNDRV_SEQ_GLOBAL_CLIENTS];
Takashi Iwai 20bbd4
-		static char card_requested[SNDRV_CARDS];
Takashi Iwai 20bbd4
+		static DECLARE_BITMAP(client_requested, SNDRV_SEQ_GLOBAL_CLIENTS);
Takashi Iwai 20bbd4
+		static DECLARE_BITMAP(card_requested, SNDRV_CARDS);
Takashi Iwai 20bbd4
+
Takashi Iwai 20bbd4
 		if (clientid < SNDRV_SEQ_GLOBAL_CLIENTS) {
Takashi Iwai 20bbd4
 			int idx;
Takashi Iwai 20bbd4
 			
Takashi Iwai 20bbd4
-			if (!client_requested[clientid]) {
Takashi Iwai 20bbd4
-				client_requested[clientid] = 1;
Takashi Iwai 20bbd4
+			if (!test_and_set_bit(clientid, client_requested)) {
Takashi Iwai 20bbd4
 				for (idx = 0; idx < 15; idx++) {
Takashi Iwai 20bbd4
 					if (seq_client_load[idx] < 0)
Takashi Iwai 20bbd4
 						break;
Takashi Iwai 20bbd4
@@ -142,10 +142,8 @@ struct snd_seq_client *snd_seq_client_use_ptr(int clientid)
Takashi Iwai 20bbd4
 			int card = (clientid - SNDRV_SEQ_GLOBAL_CLIENTS) /
Takashi Iwai 20bbd4
 				SNDRV_SEQ_CLIENTS_PER_CARD;
Takashi Iwai 20bbd4
 			if (card < snd_ecards_limit) {
Takashi Iwai 20bbd4
-				if (! card_requested[card]) {
Takashi Iwai 20bbd4
-					card_requested[card] = 1;
Takashi Iwai 20bbd4
+				if (!test_and_set_bit(card, card_requested))
Takashi Iwai 20bbd4
 					snd_request_card(card);
Takashi Iwai 20bbd4
-				}
Takashi Iwai 20bbd4
 				snd_seq_device_load_drivers();
Takashi Iwai 20bbd4
 			}
Takashi Iwai 20bbd4
 		}
Takashi Iwai 20bbd4
-- 
Takashi Iwai 20bbd4
2.35.3
Takashi Iwai 20bbd4