summaryrefslogtreecommitdiffstats
path: root/sound/firewire
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2021-10-27 14:55:27 +0200
committerTakashi Iwai <tiwai@suse.de>2021-10-28 09:10:33 +0200
commitd593f78e3b53891692162d7b4e68f341c5869295 (patch)
tree4ec7fa428c5f6abf59a234167a035ff911678c9c /sound/firewire
parentALSA: hda/realtek: Add a quirk for HP OMEN 15 mute LED (diff)
downloadlinux-d593f78e3b53891692162d7b4e68f341c5869295.tar.xz
linux-d593f78e3b53891692162d7b4e68f341c5869295.zip
ALSA: firewire-motu: fix null pointer dereference when polling hwdep character device
ALSA firewire-motu driver recently got support for event notification via ALSA HwDep interface for register DSP models. However, when polling ALSA HwDep cdev, the driver can cause null pointer dereference for the other models due to accessing to unallocated memory or uninitialized memory. This commit fixes the bug by check the type of model before accessing to the memory. Reported-by: kernel test robot <lkp@intel.com> Suggested-by: Takashi Iwai <tiwai@suse.de> Fixes: 634ec0b2906e ("ALSA: firewire-motu: notify event for parameter change in register DSP model") Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Link: https://lore.kernel.org/r/20211027125529.54295-2-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire')
-rw-r--r--sound/firewire/motu/motu-hwdep.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sound/firewire/motu/motu-hwdep.c b/sound/firewire/motu/motu-hwdep.c
index 9c2e457ce692..a900fc0e7644 100644
--- a/sound/firewire/motu/motu-hwdep.c
+++ b/sound/firewire/motu/motu-hwdep.c
@@ -16,6 +16,14 @@
#include "motu.h"
+static bool has_dsp_event(struct snd_motu *motu)
+{
+ if (motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP)
+ return (snd_motu_register_dsp_message_parser_count_event(motu) > 0);
+ else
+ return false;
+}
+
static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
loff_t *offset)
{
@@ -25,8 +33,7 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
spin_lock_irq(&motu->lock);
- while (!motu->dev_lock_changed && motu->msg == 0 &&
- snd_motu_register_dsp_message_parser_count_event(motu) == 0) {
+ while (!motu->dev_lock_changed && motu->msg == 0 && !has_dsp_event(motu)) {
prepare_to_wait(&motu->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
spin_unlock_irq(&motu->lock);
schedule();
@@ -55,7 +62,7 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
count = min_t(long, count, sizeof(event));
if (copy_to_user(buf, &event, count))
return -EFAULT;
- } else if (snd_motu_register_dsp_message_parser_count_event(motu) > 0) {
+ } else if (has_dsp_event(motu)) {
size_t consumed = 0;
u32 __user *ptr;
u32 ev;
@@ -94,8 +101,7 @@ static __poll_t hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
poll_wait(file, &motu->hwdep_wait, wait);
spin_lock_irq(&motu->lock);
- if (motu->dev_lock_changed || motu->msg ||
- snd_motu_register_dsp_message_parser_count_event(motu) > 0)
+ if (motu->dev_lock_changed || motu->msg || has_dsp_event(motu))
events = EPOLLIN | EPOLLRDNORM;
else
events = 0;