Skip to content

Commit

Permalink
sound: rawmidi: fix MIDI device O_APPEND error handling
Browse files Browse the repository at this point in the history
Commit 9a1b64c in 2.6.30 broke the
error handling code in rawmidi_open_priv().

If only the output substream of a RawMIDI device has been opened and
if this device is then opened with O_RDWR | O_APPEND and if the
initialization of the input substream fails (either because of low
memory or because the device driver's open callback fails), then the
runtime structure of the already open output substream will be freed
and all following writes through the first handle will cause
snd_rawmidi_write() to use the NULL runtime pointer.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Cc: <stable@kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Clemens Ladisch authored and Takashi Iwai committed Nov 10, 2009
1 parent 16fb109 commit b7fe750
Showing 1 changed file with 7 additions and 12 deletions.
19 changes: 7 additions & 12 deletions sound/core/rawmidi.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,10 @@ static int open_substream(struct snd_rawmidi *rmidi,
if (err < 0)
return err;
err = substream->ops->open(substream);
if (err < 0)
if (err < 0) {
snd_rawmidi_runtime_free(substream);
return err;
}
substream->opened = 1;
substream->active_sensing = 0;
if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
Expand All @@ -300,41 +302,34 @@ static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode,
SNDRV_RAWMIDI_STREAM_INPUT,
mode, &sinput);
if (err < 0)
goto __error;
return err;
}
if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) {
err = assign_substream(rmidi, subdevice,
SNDRV_RAWMIDI_STREAM_OUTPUT,
mode, &soutput);
if (err < 0)
goto __error;
return err;
}

if (sinput) {
err = open_substream(rmidi, sinput, mode);
if (err < 0)
goto __error;
return err;
}
if (soutput) {
err = open_substream(rmidi, soutput, mode);
if (err < 0) {
if (sinput)
close_substream(rmidi, sinput, 0);
goto __error;
return err;
}
}

rfile->rmidi = rmidi;
rfile->input = sinput;
rfile->output = soutput;
return 0;

__error:
if (sinput && sinput->runtime)
snd_rawmidi_runtime_free(sinput);
if (soutput && soutput->runtime)
snd_rawmidi_runtime_free(soutput);
return err;
}

/* called from sound/core/seq/seq_midi.c */
Expand Down

0 comments on commit b7fe750

Please sign in to comment.