| From 632a966a592952ed3cdd7ef9751b9a24421f9a8c Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sat, 16 May 2020 08:25:56 +0200 |
| Subject: ALSA: hda: Fix potential race in unsol event handler |
| |
| From: Takashi Iwai <tiwai@suse.de> |
| |
| [ Upstream commit c637fa151259c0f74665fde7cba5b7eac1417ae5 ] |
| |
| The unsol event handling code has a loop retrieving the read/write |
| indices and the arrays without locking while the append to the array |
| may happen concurrently. This may lead to some inconsistency. |
| Although there hasn't been any proof of this bad results, it's still |
| safer to protect the racy accesses. |
| |
| This patch adds the spinlock protection around the unsol handling loop |
| for addressing it. Here we take bus->reg_lock as the writer side |
| snd_hdac_bus_queue_event() is also protected by that lock. |
| |
| Link: https://lore.kernel.org/r/20200516062556.30951-1-tiwai@suse.de |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| sound/hda/hdac_bus.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| diff --git a/sound/hda/hdac_bus.c b/sound/hda/hdac_bus.c |
| index 714a51721a313..ab9236e4c157e 100644 |
| --- a/sound/hda/hdac_bus.c |
| +++ b/sound/hda/hdac_bus.c |
| @@ -155,6 +155,7 @@ static void process_unsol_events(struct work_struct *work) |
| struct hdac_driver *drv; |
| unsigned int rp, caddr, res; |
| |
| + spin_lock_irq(&bus->reg_lock); |
| while (bus->unsol_rp != bus->unsol_wp) { |
| rp = (bus->unsol_rp + 1) % HDA_UNSOL_QUEUE_SIZE; |
| bus->unsol_rp = rp; |
| @@ -166,10 +167,13 @@ static void process_unsol_events(struct work_struct *work) |
| codec = bus->caddr_tbl[caddr & 0x0f]; |
| if (!codec || !codec->dev.driver) |
| continue; |
| + spin_unlock_irq(&bus->reg_lock); |
| drv = drv_to_hdac_driver(codec->dev.driver); |
| if (drv->unsol_event) |
| drv->unsol_event(codec, res); |
| + spin_lock_irq(&bus->reg_lock); |
| } |
| + spin_unlock_irq(&bus->reg_lock); |
| } |
| |
| /** |
| -- |
| 2.25.1 |
| |