Commit 7884bca8 authored by Oswald Buddenhagen's avatar Oswald Buddenhagen Committed by Zheng Yejian
Browse files

ALSA: emux: improve patch ioctl data validation

stable inclusion
from stable-v4.19.317
commit 40d7def67841343c10f8642a41031fecbb248bab
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAGEP7
CVE: CVE-2024-42097

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



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

[ Upstream commit 89b32ccb12ae67e630c6453d778ec30a592a212f ]

In load_data(), make the validation of and skipping over the main info
block match that in load_guspatch().

In load_guspatch(), add checking that the specified patch length matches
the actually supplied data, like load_data() already did.

Signed-off-by: default avatarOswald Buddenhagen <oswald.buddenhagen@gmx.de>
Message-ID: <20240406064830.1029573-8-oswald.buddenhagen@gmx.de>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarZheng Yejian <zhengyejian1@huawei.com>
parent 9a994eff
Loading
Loading
Loading
Loading
+11 −6
Original line number Original line Diff line number Diff line
@@ -710,7 +710,6 @@ load_data(struct snd_sf_list *sflist, const void __user *data, long count)
	struct snd_soundfont *sf;
	struct snd_soundfont *sf;
	struct soundfont_sample_info sample_info;
	struct soundfont_sample_info sample_info;
	struct snd_sf_sample *sp;
	struct snd_sf_sample *sp;
	long off;


	/* patch must be opened */
	/* patch must be opened */
	if ((sf = sflist->currsf) == NULL)
	if ((sf = sflist->currsf) == NULL)
@@ -719,12 +718,16 @@ load_data(struct snd_sf_list *sflist, const void __user *data, long count)
	if (is_special_type(sf->type))
	if (is_special_type(sf->type))
		return -EINVAL;
		return -EINVAL;


	if (count < (long)sizeof(sample_info)) {
		return -EINVAL;
	}
	if (copy_from_user(&sample_info, data, sizeof(sample_info)))
	if (copy_from_user(&sample_info, data, sizeof(sample_info)))
		return -EFAULT;
		return -EFAULT;
	data += sizeof(sample_info);
	count -= sizeof(sample_info);


	off = sizeof(sample_info);
	// SoundFont uses S16LE samples.

	if (sample_info.size * 2 != count)
	if (sample_info.size != (count-off)/2)
		return -EINVAL;
		return -EINVAL;


	/* Check for dup */
	/* Check for dup */
@@ -751,7 +754,7 @@ load_data(struct snd_sf_list *sflist, const void __user *data, long count)
		int  rc;
		int  rc;
		rc = sflist->callback.sample_new
		rc = sflist->callback.sample_new
			(sflist->callback.private_data, sp, sflist->memhdr,
			(sflist->callback.private_data, sp, sflist->memhdr,
			 data + off, count - off);
			 data, count);
		if (rc < 0) {
		if (rc < 0) {
			sf_sample_delete(sflist, sf, sp);
			sf_sample_delete(sflist, sf, sp);
			return rc;
			return rc;
@@ -962,10 +965,12 @@ load_guspatch(struct snd_sf_list *sflist, const char __user *data,
	}
	}
	if (copy_from_user(&patch, data, sizeof(patch)))
	if (copy_from_user(&patch, data, sizeof(patch)))
		return -EFAULT;
		return -EFAULT;
	
	count -= sizeof(patch);
	count -= sizeof(patch);
	data += sizeof(patch);
	data += sizeof(patch);


	if ((patch.len << (patch.mode & WAVE_16_BITS ? 1 : 0)) != count)
		return -EINVAL;

	sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL);
	sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL);
	if (sf == NULL)
	if (sf == NULL)
		return -ENOMEM;
		return -ENOMEM;