[PATCH] ALSA: emux: Skip events until fully initialized

From: Takashi Iwai

Date: Fri Oct 16 2026 - 12:23:22 EST


The emux synth creates a sequencer port and then continues
initializing the port attributes. It allows the port receiving
already input events even though the synth stuff hasn't been fully
initialized. Similarly, upon the releasing, it clears up the voices,
etc, then detaches the port. This may leave some pending voices
before the detaching.

For addressing such races, introduce a simple guard to skip the event
processing in the premature or teardown phases.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Cc: <stable@xxxxxxxxxxxxxxx>
Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
---
include/sound/emux_synth.h | 1 +
sound/synth/emux/emux_oss.c | 4 ++++
sound/synth/emux/emux_seq.c | 3 +++
3 files changed, 8 insertions(+)

diff --git a/include/sound/emux_synth.h b/include/sound/emux_synth.h
index 2c0a976e00ab..29b15576e9e6 100644
--- a/include/sound/emux_synth.h
+++ b/include/sound/emux_synth.h
@@ -128,6 +128,7 @@ struct snd_emux_port {
struct snd_emux *emu;

char port_mode; /* operation mode */
+ bool ready; /* ready for processing input? */
int volume_atten; /* emuX raw attenuation */
unsigned long drum_flags; /* drum bitmaps */
int ctrls[EMUX_MD_END]; /* control parameters */
diff --git a/sound/synth/emux/emux_oss.c b/sound/synth/emux/emux_oss.c
index 30e353e7323d..9c3d02e65f53 100644
--- a/sound/synth/emux/emux_oss.c
+++ b/sound/synth/emux/emux_oss.c
@@ -129,6 +129,7 @@ snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
reset_port_mode(p, arg->seq_mode);

snd_emux_reset_port(p);
+ WRITE_ONCE(p->ready, true);
return 0;
}

@@ -182,6 +183,7 @@ snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg)
if (snd_BUG_ON(!emu))
return -ENXIO;

+ WRITE_ONCE(p->ready, false);
snd_emux_sounds_off_all(p);
snd_soundfont_close_check(emu->sflist, SF_CLIENT_NO(p->chset.port));
snd_seq_event_port_detach(p->chset.client, p->chset.port);
@@ -304,6 +306,8 @@ snd_emux_event_oss_input(struct snd_seq_event *ev, int direct, void *private_dat
p = private_data;
if (snd_BUG_ON(!p))
return -EINVAL;
+ if (!READ_ONCE(p->ready))
+ return 0;
emu = p->emu;
if (snd_BUG_ON(!emu))
return -EINVAL;
diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c
index 01ad5b12b680..1f1518506031 100644
--- a/sound/synth/emux/emux_seq.c
+++ b/sound/synth/emux/emux_seq.c
@@ -96,6 +96,7 @@ snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index)
snd_emux_init_port(p);
emu->ports[i] = p->chset.port;
emu->portptrs[i] = p;
+ WRITE_ONCE(p->ready, true);
}

return 0;
@@ -239,6 +240,8 @@ snd_emux_event_input(struct snd_seq_event *ev, int direct, void *private_data,
port = private_data;
if (snd_BUG_ON(!port || !ev))
return -EINVAL;
+ if (!READ_ONCE(port->ready))
+ return 0;

snd_midi_process_event(&emux_ops, ev, &port->chset);

--
2.55.0