diff options
author | Oswald Buddenhagen <oswald.buddenhagen@gmx.de> | 2024-04-06 08:48:20 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2024-04-07 08:35:48 +0200 |
commit | 89b32ccb12ae67e630c6453d778ec30a592a212f (patch) | |
tree | 0ee1cdd4df3370d4bfb10fb982ef091d0380629f /sound/synth | |
parent | de67aab120d4d5ba7d9e94ee5b25464ae0d1bd0e (diff) |
ALSA: emux: improve patch ioctl data validation
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>
Diffstat (limited to 'sound/synth')
-rw-r--r-- | sound/synth/emux/soundfont.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c index 6d6f0102ed5b..4edc693da8e7 100644 --- a/sound/synth/emux/soundfont.c +++ b/sound/synth/emux/soundfont.c @@ -716,7 +716,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; @@ -726,12 +725,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 */ @@ -774,7 +777,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; @@ -986,10 +989,12 @@ load_guspatch(struct snd_sf_list *sflist, const char __user *data, long count) } 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; |