summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@gmx.de>2024-04-06 08:48:20 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-07-05 09:00:32 +0200
commit40d7def67841343c10f8642a41031fecbb248bab (patch)
tree73bdd7b2d2c946f4a4c47b42f8a8b2f5da75e0ec
parent2b085521be5292016097b5e7ca81b26be3f7098d (diff)
ALSA: emux: improve patch ioctl data validation
[ 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>
-rw-r--r--sound/synth/emux/soundfont.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
index 31a4ea94830e..235b16af6083 100644
--- a/sound/synth/emux/soundfont.c
+++ b/sound/synth/emux/soundfont.c
@@ -710,7 +710,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)
@@ -719,12 +718,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 */
@@ -751,7 +754,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;
@@ -962,10 +965,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;