mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-13 09:15:02 +08:00
ALSA: emux: improve patch ioctl data validation
[ Upstream commit 89b32ccb12
]
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>
This commit is contained in:
parent
39173b04ab
commit
7a18293fd8
@ -701,7 +701,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 */
|
||||||
sf = sflist->currsf;
|
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))
|
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 */
|
||||||
@ -744,7 +747,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;
|
||||||
@ -957,10 +960,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;
|
||||||
|
Loading…
Reference in New Issue
Block a user