sound/oss: remove offset from load_patch callbacks

Was: [PATCH] sound/oss/midi_synth: prevent underflow, use of
uninitialized value, and signedness issue

The offset passed to midi_synth_load_patch() can be essentially
arbitrary.  If it's greater than the header length, this will result in
a copy_from_user(dst, src, negative_val).  While this will just return
-EFAULT on x86, on other architectures this may cause memory corruption.
Additionally, the length field of the sysex_info structure may not be
initialized prior to its use.  Finally, a signed comparison may result
in an unintentionally large loop.

On suggestion by Takashi Iwai, version two removes the offset argument
from the load_patch callbacks entirely, which also resolves similar
issues in opl3.  Compile tested only.

v3 adjusts comments and hopefully gets copy offsets right.

Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
static void seq_chn_voice_event(unsigned char *event_rec)
{
#define dev event_rec[1]
#define cmd event_rec[2]
#define chn event_rec[3]
#define note event_rec[4]
#define parm event_rec[5]

	int voice = -1;

	if ((int) dev > max_synthdev || synth_devs[dev] == NULL)
		return;
	if (!(synth_open_mask & (1 << dev)))
		return;
	if (!synth_devs[dev])
		return;

	if (seq_mode == SEQ_2)
	{
		if (synth_devs[dev]->alloc_voice)
			voice = find_voice(dev, chn, note);

		if (cmd == MIDI_NOTEON && parm == 0)
		{
			cmd = MIDI_NOTEOFF;
			parm = 64;
		}
	}

	switch (cmd)
	{
		case MIDI_NOTEON:
			if (note > 127 && note != 255)	/* Not a seq2 feature */
				return;

			if (voice == -1 && seq_mode == SEQ_2 && synth_devs[dev]->alloc_voice)
			{
				/* Internal synthesizer (FM, GUS, etc) */
				voice = alloc_voice(dev, chn, note);
			}
			if (voice == -1)
				voice = chn;

			if (seq_mode == SEQ_2 && (int) dev < num_synths)
			{
				/*
				 * The MIDI channel 10 is a percussive channel. Use the note
				 * number to select the proper patch (128 to 255) to play.
				 */

				if (chn == 9)
				{
					synth_devs[dev]->set_instr(dev, voice, 128 + note);
					synth_devs[dev]->chn_info[chn].pgm_num = 128 + note;
				}
				synth_devs[dev]->setup_voice(dev, voice, chn);
			}
			synth_devs[dev]->start_note(dev, voice, note, parm);
			break;

		case MIDI_NOTEOFF:
			if (voice == -1)
				voice = chn;
			synth_devs[dev]->kill_note(dev, voice, note, parm);
			break;

		case MIDI_KEY_PRESSURE:
			if (voice == -1)
				voice = chn;
			synth_devs[dev]->aftertouch(dev, voice, parm);
			break;

		default:;
	}
#undef dev
#undef cmd
#undef chn
#undef note
#undef parm
}

static void seq_chn_voice_event(unsigned char *event_rec)
{
#define dev event_rec[1]
#define cmd event_rec[2]
#define chn event_rec[3]
#define note event_rec[4]
#define parm event_rec[5]

	int voice = -1;

	if ((int) dev > max_synthdev || synth_devs[dev] == NULL)
		return;
	if (!(synth_open_mask & (1 << dev)))
		return;
	if (!synth_devs[dev])
		return;

	if (seq_mode == SEQ_2)
	{
		if (synth_devs[dev]->alloc_voice)
			voice = find_voice(dev, chn, note);

		if (cmd == MIDI_NOTEON && parm == 0)
		{
			cmd = MIDI_NOTEOFF;
			parm = 64;
		}
	}

	switch (cmd)
	{
		case MIDI_NOTEON:
			if (note > 127 && note != 255)	/* Not a seq2 feature */
				return;

			if (voice == -1 && seq_mode == SEQ_2 && synth_devs[dev]->alloc_voice)
			{
				/* Internal synthesizer (FM, GUS, etc) */
				voice = alloc_voice(dev, chn, note);
			}
			if (voice == -1)
				voice = chn;

			if (seq_mode == SEQ_2 && (int) dev < num_synths)
			{
				/*
				 * The MIDI channel 10 is a percussive channel. Use the note
				 * number to select the proper patch (128 to 255) to play.
				 */

				if (chn == 9)
				{
					synth_devs[dev]->set_instr(dev, voice, 128 + note);
					synth_devs[dev]->chn_info[chn].pgm_num = 128 + note;
				}
				synth_devs[dev]->setup_voice(dev, voice, chn);
			}
			synth_devs[dev]->start_note(dev, voice, note, parm);
			break;

		case MIDI_NOTEOFF:
			if (voice == -1)
				voice = chn;
			synth_devs[dev]->kill_note(dev, voice, note, parm);
			break;

		case MIDI_KEY_PRESSURE:
			if (voice == -1)
				voice = chn;
			synth_devs[dev]->aftertouch(dev, voice, parm);
			break;

		default:;
	}
#undef dev
#undef cmd
#undef chn
#undef note
#undef parm
}
