[PATCH] ALSA: firewire-motu: fix invalid memory access when operating hwdep character device

Takashi Sakamoto o-takashi at sakamocchi.jp
Thu Oct 21 16:11:08 CEST 2021


Hi,

On Wed, Oct 20, 2021 at 07:40:46AM +0200, Takashi Iwai wrote:
> On Wed, 20 Oct 2021 06:25:55 +0200,
> Takashi Sakamoto wrote:
> > 
> > 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.
> > 
> > Fixes: 634ec0b2906e ("ALSA: firewire-motu: notify event for parameter change in register DSP model")
> > Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
> 
> Wouldn't it be simpler to add the flag check in
> snd_motu_register_dsp_message_parser_count_event() and return 0 if
> SND_MOTU_SPEC_REGISTER_DSP isn't set there?

Indeed. It's simpler than my patch.

When posted, I considered about pre-condition in context of design by
contract. I programmed motu-register-dsp-message-parser.c so that
callers of extern functions should guarantee the target is register
DSP models.

> > +// NOTE: Take care of page fault due to accessing to userspace.
> > +static long copy_dsp_event_to_user(struct snd_motu *motu, char __user *buf, long count,
> > +				   struct snd_firewire_event_motu_register_dsp_change *event)
> > +{
> > +	if (motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP) {
> > +		size_t consumed = 0;
> > +		u32 __user *ptr;
> > +		u32 ev;
> > +
> > +		// Header is filled later.
> > +		consumed += sizeof(*event);
> > +
> > +		while (consumed < count &&
> > +		       snd_motu_register_dsp_message_parser_copy_event(motu, &ev)) {
> > +			ptr = (u32 __user *)(buf + consumed);
> > +			if (put_user(ev, ptr))
> > +				return -EFAULT;
> > +			consumed += sizeof(ev);
> > +		}
> > +
> > +		event->type = SNDRV_FIREWIRE_EVENT_MOTU_REGISTER_DSP_CHANGE;
> > +		event->count = (consumed - sizeof(*event)) / 4;
> > +		if (copy_to_user(buf, &event, sizeof(*event)))

The second argument should have been 'event'...

Anyway I'll use a bit more time to consider about what is better to fix the
bug.


Thanks

Takashi Sakamoto


More information about the Alsa-devel mailing list