| From 0ca11237ceb7521c934c43c2eef2d97a393331a6 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sat, 6 Apr 2024 08:48:20 +0200 |
| Subject: ALSA: emux: improve patch ioctl data validation |
| |
| From: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> |
| |
| [ 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: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> |
| Message-ID: <20240406064830.1029573-8-oswald.buddenhagen@gmx.de> |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| sound/synth/emux/soundfont.c | 17 +++++++++++------ |
| 1 file changed, 11 insertions(+), 6 deletions(-) |
| |
| diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c |
| index 16f00097cb95a..eed47e4830248 100644 |
| --- a/sound/synth/emux/soundfont.c |
| +++ b/sound/synth/emux/soundfont.c |
| @@ -701,7 +701,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 */ |
| sf = sflist->currsf; |
| @@ -711,12 +710,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 */ |
| @@ -744,7 +747,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; |
| @@ -957,10 +960,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; |
| -- |
| 2.43.0 |
| |