ALSA: hda: Fix potential race at unregistration and unsol events
authorTakashi Iwai <tiwai@suse.de>
Mon, 19 Jun 2017 15:49:48 +0000 (17:49 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 20 Jun 2017 05:53:57 +0000 (07:53 +0200)
When the codec device is unregistered / freed, it may release the
resource while being used in an unsolicited event like the jack
detection work.  This leads to use-after-free.

The fix here is to unregister the device at first, i.e. removing the
codec from the list, then flushing the pending works to assure that
all unsol events are gone.  After this point, we're free from
accessing the codec via unsol events, thus can release the resources
gracefully.

The issue was spotted originally by Intel CI, but it couldn't be
reproduced reliably by its nature.  So let's hope this fix really
addresses the whole issues.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=196045
Reported-by: Martin Peres <martin.peres@free.fr>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/hda/hdac_bus.c
sound/hda/hdac_device.c

index 0e81ea89a5965a49a80e52c6405d9a456cc9decf..714a51721a313cef9e47309662b778e5c5b3c55b 100644 (file)
@@ -212,5 +212,6 @@ void snd_hdac_bus_remove_device(struct hdac_bus *bus,
        bus->caddr_tbl[codec->addr] = NULL;
        clear_bit(codec->addr, &bus->codec_powered);
        bus->num_codecs--;
+       flush_work(&bus->unsol_work);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_bus_remove_device);
index 03c9872c31cfe4a2a723d3e4bb0f4896b313dc32..19deb306facb7c771f6bd3a2cf0ea3f1f7c57131 100644 (file)
@@ -159,6 +159,7 @@ void snd_hdac_device_unregister(struct hdac_device *codec)
        if (device_is_registered(&codec->dev)) {
                hda_widget_sysfs_exit(codec);
                device_del(&codec->dev);
+               snd_hdac_bus_remove_device(codec->bus, codec);
        }
 }
 EXPORT_SYMBOL_GPL(snd_hdac_device_unregister);