Convert some checks in snd_emu10k1_sample_new() back into assertions (as they were prior to da3cec35dd (ALSA: Kill snd_assert() in sound/pci/*, 2008-08-08)), and move them into the low-level memory access functions they protect. Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@xxxxxx> --- Side note: this eliminates the memory leaks in the now gone error paths. I don't think it was actually possible to trigger these even before the foregoing cleanups. But if it were, it would allow a user with access to the audio device a scope-limited DoS attack on it. This would be only a very minor security hole, given that on modern systems it would merely enable the current seat owner to be a nuisance to their successor, by making a reboot necessary. --- sound/pci/emu10k1/emu10k1_patch.c | 4 ---- sound/pci/emu10k1/memory.c | 6 ++++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sound/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c index 47d69a0e44bc..55bb60d31fe4 100644 --- a/sound/pci/emu10k1/emu10k1_patch.c +++ b/sound/pci/emu10k1/emu10k1_patch.c @@ -65,17 +65,13 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, size = BLANK_HEAD_SIZE; if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) size *= 2; - if (offset + size > blocksize) - return -EINVAL; snd_emu10k1_synth_bzero(emu, sp->block, offset, size); offset += size; /* copy provided samples */ size = sp->v.size; if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) size *= 2; - if (offset + size > blocksize) - return -EINVAL; if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) { snd_emu10k1_synth_free(emu, sp->block); sp->block = NULL; diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index 20b07117574b..fc9444404151 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c @@ -574,6 +574,9 @@ int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk void *ptr; struct snd_emu10k1_memblk *p = (struct snd_emu10k1_memblk *)blk; + if (snd_BUG_ON(offset + size > p->mem.size)) + return -EFAULT; + offset += blk->offset & (PAGE_SIZE - 1); end_offset = offset + size; page = get_aligned_page(offset); @@ -604,6 +607,9 @@ int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_me void *ptr; struct snd_emu10k1_memblk *p = (struct snd_emu10k1_memblk *)blk; + if (snd_BUG_ON(offset + size > p->mem.size)) + return -EFAULT; + offset += blk->offset & (PAGE_SIZE - 1); end_offset = offset + size; page = get_aligned_page(offset); -- 2.44.0.701.g2cf7baacf3.dirty