Commit 36c6f4a6 authored by Takashi Iwai's avatar Takashi Iwai Committed by Gu Bowen
Browse files

ALSA: seq: oss: Fix races at processing SysEx messages

stable inclusion
from stable-v6.6.70
commit d2392b79d8af3714ea8878b71c66dc49d3110f44
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBID2T
CVE: CVE-2024-57893

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=d2392b79d8af3714ea8878b71c66dc49d3110f44



--------------------------------

commit 0179488ca992d79908b8e26b9213f1554fc5bacc upstream.

OSS sequencer handles the SysEx messages split in 6 bytes packets, and
ALSA sequencer OSS layer tries to combine those.  It stores the data
in the internal buffer and this access is racy as of now, which may
lead to the out-of-bounds access.

As a temporary band-aid fix, introduce a mutex for serializing the
process of the SysEx message packets.

Reported-by: default avatarKun Hu <huk23@m.fudan.edu.cn>
Closes: https://lore.kernel.org/2B7E93E4-B13A-4AE4-8E87-306A8EE9BBB7@m.fudan.edu.cn
Cc: <stable@vger.kernel.org>
Link: https://patch.msgid.link/20241230110543.32454-1-tiwai@suse.de


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Conflicts:
	sound/core/seq/oss/seq_oss_synth.c
[Commit 54da6a09("locking: Introduce __cleanup() based
infrastructure") not merged, The guard() function is not introduced.]
Signed-off-by: default avatarGu Bowen <gubowen5@huawei.com>
parent da51139d
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ static struct seq_oss_synth midi_synth_dev = {
};

static DEFINE_SPINLOCK(register_lock);
static DEFINE_MUTEX(sysex_mutex);

/*
 * prototypes
@@ -504,16 +505,20 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
	unsigned char *dest;
	struct seq_oss_synth_sysex *sysex;
	struct seq_oss_synthinfo *info;
	int err = -EINVAL;

	info = snd_seq_oss_synth_info(dp, dev);
	if (!info)
		return -ENXIO;

	mutex_lock(&sysex_mutex);
	sysex = info->sysex;
	if (sysex == NULL) {
		sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
		if (sysex == NULL)
			return -ENOMEM;
		if (sysex == NULL) {
			err = -ENOMEM;
			goto unlock_sysex;
		}
		info->sysex = sysex;
	}

@@ -538,19 +543,25 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
		if (sysex->skip) {
			sysex->skip = 0;
			sysex->len = 0;
			return -EINVAL; /* skip */
			err = -EINVAL; /* skip */
			goto unlock_sysex;
		}
		/* copy the data to event record and send it */
		ev->flags = SNDRV_SEQ_EVENT_LENGTH_VARIABLE;
		if (snd_seq_oss_synth_addr(dp, dev, ev))
			return -EINVAL;
		if (snd_seq_oss_synth_addr(dp, dev, ev)) {
			err = -EINVAL;
			goto unlock_sysex;
		}
		ev->data.ext.len = sysex->len;
		ev->data.ext.ptr = sysex->buf;
		sysex->len = 0;
		mutex_unlock(&sysex_mutex);
		return 0;
	}

	return -EINVAL; /* skip */
unlock_sysex:
	mutex_unlock(&sysex_mutex);
	return err; /* skip */
}

/*