ALSA: hda: Fix potential deadlock at codec unbinding
authorTakashi Iwai <tiwai@suse.de>
Tue, 16 Nov 2021 07:24:59 +0000 (08:24 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Jan 2022 10:04:05 +0000 (11:04 +0100)
commitec085da3437ba5f8752be304de214183222c38e7
tree46fc2a5bb189cc5fe05ff3c3d049b3ea6f128c8e
parent1b378f59bc86b39aa6594877405f6aaf96cd05fe
ALSA: hda: Fix potential deadlock at codec unbinding

[ Upstream commit 7206998f578d5553989bc01ea2e544b622e79539 ]

When a codec is unbound dynamically via sysfs while its stream is in
use, we may face a potential deadlock at the proc remove or a UAF.
This happens since the hda_pcm is managed by a linked list, as it
handles the hda_pcm object release via kref.

When a PCM is opened at the unbinding time, the release of hda_pcm
gets delayed and it ends up with the close of the PCM stream releasing
the associated hda_pcm object of its own.  The hda_pcm destructor
contains the PCM device release that includes the removal of procfs
entries.  And, this removal has the sync of the close of all in-use
files -- which would never finish because it's called from the PCM
file descriptor itself, i.e. it's trying to shoot its foot.

For addressing the deadlock above, this patch changes the way to
manage and release the hda_pcm object.  The kref of hda_pcm is
dropped, and instead a simple refcount is introduced in hda_codec for
keeping the track of the active PCM streams, and at each PCM open and
close, this refcount is adjusted accordingly.  At unbinding, the
driver calls snd_device_disconnect() for each PCM stream, then
synchronizes with the refcount finish, and finally releases the object
resources.

Fixes: bbbc7e8502c9 ("ALSA: hda - Allocate hda_pcm objects dynamically")
Link: https://lore.kernel.org/r/20211116072459.18930-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/sound/hda_codec.h
sound/pci/hda/hda_bind.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_local.h