Commit f4d2eb4f 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-v5.10.221
commit d23982ea9aa438f35a8c8a6305943e98a8db90f6
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=d23982ea9aa438f35a8c8a6305943e98a8db90f6



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

[ 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>
Fixes: 1da177e4 ("Linux-2.6.12-rc2")
Signed-off-by: default avatarZheng Yejian <zhengyejian1@huawei.com>
parent aa5390b9
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -697,7 +697,6 @@ load_data(struct snd_sf_list *sflist, const void __user *data, long count)
	struct snd_soundfont *sf;
	struct soundfont_sample_info sample_info;
	struct snd_sf_sample *sp;
	long off;

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

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

	off = sizeof(sample_info);

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

	/* Check for dup */
@@ -738,7 +741,7 @@ load_data(struct snd_sf_list *sflist, const void __user *data, long count)
		int  rc;
		rc = sflist->callback.sample_new
			(sflist->callback.private_data, sp, sflist->memhdr,
			 data + off, count - off);
			 data, count);
		if (rc < 0) {
			sf_sample_delete(sflist, sf, sp);
			return rc;
@@ -951,10 +954,12 @@ load_guspatch(struct snd_sf_list *sflist, const char __user *data,
	}
	if (copy_from_user(&patch, data, sizeof(patch)))
		return -EFAULT;
	
	count -= 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);
	if (sf == NULL)
		return -ENOMEM;