Skip to content

Commit

Permalink
ALSA: rawmidi: Avoid racy info ioctl via ctl device
Browse files Browse the repository at this point in the history
The rawmidi also allows to obtaining the information via ioctl of ctl
API.  It means that user can issue an ioctl to the rawmidi device even
when it's being removed as long as the control device is present.
Although the code has some protection via the global register_mutex,
its range is limited to the search of the corresponding rawmidi
object, and the mutex is already unlocked at accessing the rawmidi
object.  This may lead to a use-after-free.

For avoiding it, this patch widens the application of register_mutex
to the whole snd_rawmidi_info_select() function.  We have another
mutex per rawmidi object, but this operation isn't very hot path, so
it shouldn't matter from the performance POV.

Cc: <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
tiwai committed Dec 14, 2017
1 parent 2b4584d commit c1cfd90
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions sound/core/rawmidi.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,15 +579,14 @@ static int snd_rawmidi_info_user(struct snd_rawmidi_substream *substream,
return 0;
}

int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info)
static int __snd_rawmidi_info_select(struct snd_card *card,
struct snd_rawmidi_info *info)
{
struct snd_rawmidi *rmidi;
struct snd_rawmidi_str *pstr;
struct snd_rawmidi_substream *substream;

mutex_lock(&register_mutex);
rmidi = snd_rawmidi_search(card, info->device);
mutex_unlock(&register_mutex);
if (!rmidi)
return -ENXIO;
if (info->stream < 0 || info->stream > 1)
Expand All @@ -603,6 +602,16 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info
}
return -ENXIO;
}

int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info)
{
int ret;

mutex_lock(&register_mutex);
ret = __snd_rawmidi_info_select(card, info);
mutex_unlock(&register_mutex);
return ret;
}
EXPORT_SYMBOL(snd_rawmidi_info_select);

static int snd_rawmidi_info_select_user(struct snd_card *card,
Expand Down

0 comments on commit c1cfd90

Please sign in to comment.