[PATCH] ALSA: seq: oss: Skip events until fully initialized
From: Takashi Iwai
Date: Fri Oct 16 2026 - 12:26:24 EST
When an OSS sequencer device is opened, it creates a sequencer port,
then further initializes the internal states like a timer instance,
etc. Since the sequencer port is published, an event can be already
delivered, and this may hit unexpected event handling, which can
eventually cause a NULL dereference (like the timer start/stop event
triggered before the timer initialization).
For avoiding such a race, introduce a simple guard and skips the event
processing until the port is fully initialized.
At releasing the device, in turn, clear this guard, so that any input
events will be discarded during the teardown.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
---
sound/core/seq/oss/seq_oss_device.h | 1 +
sound/core/seq/oss/seq_oss_event.c | 3 +++
sound/core/seq/oss/seq_oss_init.c | 2 ++
3 files changed, 6 insertions(+)
diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h
index 935cf3df0b30..571186db4fa5 100644
--- a/sound/core/seq/oss/seq_oss_device.h
+++ b/sound/core/seq/oss/seq_oss_device.h
@@ -72,6 +72,7 @@ struct seq_oss_devinfo {
int cseq; /* sequencer client number */
int port; /* sequencer port number */
int queue; /* sequencer queue number */
+ bool initialized;
struct snd_seq_addr addr; /* address of this device */
diff --git a/sound/core/seq/oss/seq_oss_event.c b/sound/core/seq/oss/seq_oss_event.c
index 3c2cfaea94d1..cf493f6c983b 100644
--- a/sound/core/seq/oss/seq_oss_event.c
+++ b/sound/core/seq/oss/seq_oss_event.c
@@ -425,6 +425,9 @@ snd_seq_oss_event_input(struct snd_seq_event *ev, int direct, void *private_data
struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private_data;
union evrec *rec;
+ if (!dp || !smp_load_acquire(&dp->initialized))
+ return 0; /* ignored */
+
if (ev->type != SNDRV_SEQ_EVENT_ECHO)
return snd_seq_oss_midi_input(ev, direct, private_data);
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index 6586e07431c3..6474a76a3cce 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -258,6 +258,7 @@ snd_seq_oss_open(struct file *file, int level)
client_table[dp->index] = dp;
num_clients++;
+ smp_store_release(&dp->initialized, true);
return 0;
@@ -403,6 +404,7 @@ snd_seq_oss_release(struct seq_oss_devinfo *dp)
client_table[dp->index] = NULL;
num_clients--;
+ smp_store_release(&dp->initialized, false);
snd_seq_oss_reset(dp);
--
2.55.0