Skip to contentSkip to conversation

ALSA: usb-audio: Kill timer properly at removal

PATCH In review Jeongjun Park 2 participants 5 messages Oct 7, 2025 – Oct 9, 2025

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ALSA: usb-audio: Kill timer properly at removal

From: Takashi Iwai <[email protected]>

[ Upstream commit 0718a78f6a9f04b88d0dc9616cc216b31c5f3cf1 ]

The USB-audio MIDI code initializes the timer, but in a rare case, the driver might be freed without the disconnect call. This leaves the timer in an active state while the assigned object is released via snd_usbmidi_free(), which ends up with a kernel warning when the debug configuration is enabled, as spotted by fuzzer.

For avoiding the problem, put timer_shutdown_sync() at snd_usbmidi_free(), so that the timer can be killed properly. While we're at it, replace the existing timer_delete_sync() at the disconnect callback with timer_shutdown_sync(), too.

---
 sound/usb/midi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sound/usb/midi.c +2 -1
index a792ada18863..c3de2b137435 100644
@@ -1530,6 +1530,7 @@ static void snd_usbmidi_free(struct snd_usb_midi *umidi)
 			snd_usbmidi_in_endpoint_delete(ep->in);
 	}
 	mutex_destroy(&umidi->mutex);
+	timer_shutdown_sync(&umidi->error_timer);
 	kfree(umidi);
 }
 
@@ -1553,7 +1554,7 @@ void snd_usbmidi_disconnect(struct list_head *p)
 	spin_unlock_irq(&umidi->disc_lock);
 	up_write(&umidi->disc_rwsem);
 
-	del_timer_sync(&umidi->error_timer);
+	timer_shutdown_sync(&umidi->error_timer);
 
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
 		struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i];

--

maintainer
#1 lore raw
Quoted 31 lines · Jeongjun Park

From: Takashi Iwai <[email protected]>

[ Upstream commit 0718a78f6a9f04b88d0dc9616cc216b31c5f3cf1 ]

The USB-audio MIDI code initializes the timer, but in a rare case, the driver might be freed without the disconnect call. This leaves the timer in an active state while the assigned object is released via snd_usbmidi_free(), which ends up with a kernel warning when the debug configuration is enabled, as spotted by fuzzer.

For avoiding the problem, put timer_shutdown_sync() at snd_usbmidi_free(), so that the timer can be killed properly. While we're at it, replace the existing timer_delete_sync() at the disconnect callback with timer_shutdown_sync(), too.

---
 sound/usb/midi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sound/usb/midi.c +0 -0
index a792ada18863..c3de2b137435 100644

sound/usb/midi.c static void snd_usbmidi_free(struct snd_usb_midi *umidi) · line 1533

Quoted 4 lines
sound/usb/midi.c +1 -0
@@ -1530,6 +1530,7 @@ static void snd_usbmidi_free(struct snd_usb_midi *umidi)
 			snd_usbmidi_in_endpoint_delete(ep->in);
 	}
 	mutex_destroy(&umidi->mutex);
+	timer_shutdown_sync(&umidi->error_timer);

This function is not in older kernel versions, you did not test this build :(

I've applied this to 6.6.y and newer, but for 6.1.y and older, please use the proper function.

thanks,

greg k-h

#2 lore raw

Hi Greg,

Quoted 41 lines · Greg KH
Quoted 31 lines · Jeongjun Park

From: Takashi Iwai <[email protected]>

[ Upstream commit 0718a78f6a9f04b88d0dc9616cc216b31c5f3cf1 ]

The USB-audio MIDI code initializes the timer, but in a rare case, the driver might be freed without the disconnect call. This leaves the timer in an active state while the assigned object is released via snd_usbmidi_free(), which ends up with a kernel warning when the debug configuration is enabled, as spotted by fuzzer.

For avoiding the problem, put timer_shutdown_sync() at snd_usbmidi_free(), so that the timer can be killed properly. While we're at it, replace the existing timer_delete_sync() at the disconnect callback with timer_shutdown_sync(), too.

---
 sound/usb/midi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sound/usb/midi.c +0 -0
index a792ada18863..c3de2b137435 100644

sound/usb/midi.c static void snd_usbmidi_free(struct snd_usb_midi *umidi) · line 1533

Quoted 4 lines
sound/usb/midi.c +1 -0
@@ -1530,6 +1530,7 @@ static void snd_usbmidi_free(struct snd_usb_midi *umidi)
                      snd_usbmidi_in_endpoint_delete(ep->in);
      }
      mutex_destroy(&umidi->mutex);
+     timer_shutdown_sync(&umidi->error_timer);

This function is not in older kernel versions, you did not test this build :(

Quoted 2 lines

I've applied this to 6.6.y and newer, but for 6.1.y and older, please use the proper function.

Sorry, I didn't realize that the timer_shutdown_sync() implementation commit wasn't backported to versions prior to 6.2.

But why wasn't this feature backported to previous versions? I understand that most drivers write separate patches for pre-6.2 versions that don't implement timer_shutdown_sync() to address this type of bug.

Is there some other, unavoidable reason I'm unaware of?

Quoted 4 lines

thanks,

greg k-h

Regards,
Jeongjun Park

maintainer
#3 lore raw
Quoted 47 lines · Jeongjun Park

Hi Greg,

Quoted 41 lines · Greg KH
Quoted 31 lines · Jeongjun Park

From: Takashi Iwai <[email protected]>

[ Upstream commit 0718a78f6a9f04b88d0dc9616cc216b31c5f3cf1 ]

The USB-audio MIDI code initializes the timer, but in a rare case, the driver might be freed without the disconnect call. This leaves the timer in an active state while the assigned object is released via snd_usbmidi_free(), which ends up with a kernel warning when the debug configuration is enabled, as spotted by fuzzer.

For avoiding the problem, put timer_shutdown_sync() at snd_usbmidi_free(), so that the timer can be killed properly. While we're at it, replace the existing timer_delete_sync() at the disconnect callback with timer_shutdown_sync(), too.

---
 sound/usb/midi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sound/usb/midi.c +0 -0
index a792ada18863..c3de2b137435 100644

sound/usb/midi.c static void snd_usbmidi_free(struct snd_usb_midi *umidi) · line 1533

Quoted 4 lines
sound/usb/midi.c +1 -0
@@ -1530,6 +1530,7 @@ static void snd_usbmidi_free(struct snd_usb_midi *umidi)
                      snd_usbmidi_in_endpoint_delete(ep->in);
      }
      mutex_destroy(&umidi->mutex);
+     timer_shutdown_sync(&umidi->error_timer);

This function is not in older kernel versions, you did not test this build :(

Quoted 2 lines

I've applied this to 6.6.y and newer, but for 6.1.y and older, please use the proper function.

Quoted 6 lines

Sorry, I didn't realize that the timer_shutdown_sync() implementation commit wasn't backported to versions prior to 6.2.

But why wasn't this feature backported to previous versions? I understand that most drivers write separate patches for pre-6.2 versions that don't implement timer_shutdown_sync() to address this type of bug.

Features are not backported to older kernels. If you want this fix in an older kernel, then you need to either backport that feature, or fix up the driver to use whatever was used before that function existed.

thanks,

greg k-h

#4 lore raw

Hi Greg,

Quoted 52 lines · Greg KH
Quoted 50 lines · Jeongjun Park

Hi Greg,

Quoted 41 lines · Greg KH
Quoted 31 lines · Jeongjun Park

From: Takashi Iwai <[email protected]>

[ Upstream commit 0718a78f6a9f04b88d0dc9616cc216b31c5f3cf1 ]

The USB-audio MIDI code initializes the timer, but in a rare case, the driver might be freed without the disconnect call. This leaves the timer in an active state while the assigned object is released via snd_usbmidi_free(), which ends up with a kernel warning when the debug configuration is enabled, as spotted by fuzzer.

For avoiding the problem, put timer_shutdown_sync() at snd_usbmidi_free(), so that the timer can be killed properly. While we're at it, replace the existing timer_delete_sync() at the disconnect callback with timer_shutdown_sync(), too.

---
 sound/usb/midi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sound/usb/midi.c +0 -0
index a792ada18863..c3de2b137435 100644

sound/usb/midi.c static void snd_usbmidi_free(struct snd_usb_midi *umidi) · line 1533

Quoted 4 lines
sound/usb/midi.c +1 -0
@@ -1530,6 +1530,7 @@ static void snd_usbmidi_free(struct snd_usb_midi *umidi)
                      snd_usbmidi_in_endpoint_delete(ep->in);
      }
      mutex_destroy(&umidi->mutex);
+     timer_shutdown_sync(&umidi->error_timer);

This function is not in older kernel versions, you did not test this build :(

Quoted 2 lines

I've applied this to 6.6.y and newer, but for 6.1.y and older, please use the proper function.

Sorry, I didn't realize that the timer_shutdown_sync() implementation commit wasn't backported to versions prior to 6.2.

Quoted 7 lines
Quoted 3 lines

But why wasn't this feature backported to previous versions? I understand that most drivers write separate patches for pre-6.2 versions that don't implement timer_shutdown_sync() to address this type of bug.

Features are not backported to older kernels. If you want this fix in an older kernel, then you need to either backport that feature, or fix up the driver to use whatever was used before that function existed.

I could write a separate patch to fix this bug, but I'm not happy that great features like timer_shutdown_sync() haven't been backported.

So, I'll try to backport the "timers: Provide timer_shutdown[_sync]()" patch series sometime soon.

Quoted 4 lines

thanks,

greg k-h

Regards,
Jeongjun Park