From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794361579; b=fb/qKobEQo8gI2n6dWee06947ekuULK89hP9C5c4T9nLYskFm+IvExoWtpEpcQ1wz7eY oWgsVkTqslOnK6uT/9H7uIZtJxFHn3/9mQVLzKdec7J3o6CNpBO78vjfTI6RNcOq+ymLX K1+hiRJExpvjiODvF+m9qp3yqpotVNdgeysq5KJBceV9fyHnW7ozIcMXAH7aGIHKxypci 4VkvbAJPU2n71EtCoKgy3EBg2sAFQA305lyWzLM8DJKuxAz9PqZwsg0/EzakytkqpJF+I Kl9AixNSKW3O4Lp33nbC/lqdQnobm+PZhsP6Npl/VUXEnxdpL2GeZJq/6P4t15KMzyw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794361579; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:MIME-Version:Content-Transfer-Encoding; bh=wkysfnGSQ64wgej+x2Wcn8wpvF1A0GWzt50mAUlrv8w=; b=cCxNTONgKZ31mnqOH/JrcHaPZSXsLjmV2CmB6bOgKDOgubMb2AvO/0CWLveVRxJ65cSg sKKCZ0IYnEGGzR0Snnl225kkMfvHOIflA6B2LahBxvUxmRhtlZdf7i74i+7BXd38rk8r1 jPTfHSE+JoS+ZZS7G3bYred4AV+AiGt5Pgyblnhpajbt8oiFFopOdjQgwf46rvrsPfiTj uuX6RNOQ+SL9fBTcoiUg+cbvcv4CL+T1QraH6AK/qRaakbuYWf5+GI1CfLlh9a1sQEgqt KPIkk9HrzDNxRO/3CMBfI+UMpmPPdv0b8MbtdxHWUucqxotH9xmFJILM5BJK0FUT6OA== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b="L714K/kB"; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 14C2C606A32A for ; Wed, 11 Nov 2026 01:46:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=L714K/kB Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6FBFE1F0093C; Wed, 11 Nov 2026 01:46:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1794361578; bh=wkysfnGSQ64wgej+x2Wcn8wpvF1A0GWzt50mAUlrv8w=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=L714K/kBzMN0fmJlKAn0BZQ0MMr3cNnN8MyqRTXBjihaV+oToB2A27PvRhZOyb0KX VgrzB1Ih3QWA0/F2Nm8VwYcTciSZT6H6jV9AFzQgiHpbu1O3PPmR7cVZOWGxDMCl7P IT30/lpwb9+ieD/QJ8OfUPxYVgjkqmdrDyW7bCiUvDr46e7VU5lCRp3yokc5hbsmne DZcmLtybYyOGnKhE1LeKk+MDZHeT8C4TMqsaxx/qWZvS9smJfDfjyqI8BECcCUnP8+ WCoLGVUn1sqXIh3jzCGbAuZMLYa/rLHy4gQFrbMuh9ZIrIT8AGMhAgv0DgpHf4d/ql A48X968dXivtw== From: Sasha Levin To: stable@vger.kernel.org Cc: Oswald Buddenhagen , Takashi Iwai , Sasha Levin Subject: [PATCH 6.6.y 2/4] ALSA: emux: centralize & improve patch info validation Date: Tue, 10 Nov 2026 20:46:14 -0500 Message-ID: <20261111014442.403245-2-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261111014442.403245-1-sashal@kernel.org> References: <20261107053715-failed-6.6-8a5d87c2ba30@kernel.org> <20261111014442.403245-1-sashal@kernel.org> X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Oswald Buddenhagen [ Upstream commit de67aab120d4d5ba7d9e94ee5b25464ae0d1bd0e ] This does several closely related things: - Move the code from the drivers into the SoundFont loader, which de-duplicates it. - Sort of explain the weird "recalculate address offset" feature. Note that I don't think it actually makes any sense - the calling user space code should do that. The background is certainly that the source data (the SoundFont format) uses pointers into a single wave block (and the API allows doing the same for on-board ROM), but the API expects the wave data from user space to be pre-chopped into individual patches anyway. - Make sure that the specified offsets actually lie within the supplied wave data. Note that we don't validate ROM offsets, so one can play back anything within the sound card's address space. - In load_guspatch(), don't call the sample_new callback anymore when the patch size is zero, as was already the case in load_data(). The callbacks would instantly return in that case anyway; these checks are now removed. Signed-off-by: Oswald Buddenhagen Message-ID: <20240406064830.1029573-7-oswald.buddenhagen@gmx.de> Signed-off-by: Takashi Iwai Stable-dep-of: 8a5d87c2ba30 ("ALSA: emux: Stop voices before freeing zones in all cases") Signed-off-by: Sasha Levin --- sound/isa/sb/emu8000_patch.c | 13 ----------- sound/pci/emu10k1/emu10k1_patch.c | 16 ------------- sound/synth/emux/soundfont.c | 37 ++++++++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c index 8c1e7f2bfc34a..ab4f988f080dc 100644 --- a/sound/isa/sb/emu8000_patch.c +++ b/sound/isa/sb/emu8000_patch.c @@ -148,13 +148,6 @@ snd_emu8000_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, if (snd_BUG_ON(!sp)) return -EINVAL; - if (sp->v.size == 0) - return 0; - - /* be sure loop points start < end */ - if (sp->v.loopstart > sp->v.loopend) - swap(sp->v.loopstart, sp->v.loopend); - /* compute true data size to be loaded */ truesize = sp->v.size; if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) @@ -177,12 +170,6 @@ snd_emu8000_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, return -EFAULT; } - /* recalculate address offset */ - sp->v.end -= sp->v.start; - sp->v.loopstart -= sp->v.start; - sp->v.loopend -= sp->v.start; - sp->v.start = 0; - /* dram position (in word) -- mem_offset is byte */ dram_offset = EMU8000_DRAM_OFFSET + (sp->block->offset >> 1); dram_start = dram_offset; diff --git a/sound/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c index 49214c2268084..47d69a0e44bc6 100644 --- a/sound/pci/emu10k1/emu10k1_patch.c +++ b/sound/pci/emu10k1/emu10k1_patch.c @@ -35,28 +35,12 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, if (snd_BUG_ON(!sp || !hdr)) return -EINVAL; - if (sp->v.size == 0) { - dev_dbg(emu->card->dev, - "emu: rom font for sample %d\n", sp->v.sample); - return 0; - } - if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP | SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) { /* should instead return -ENOTSUPP; but compatibility */ printk(KERN_WARNING "Emu10k1 wavetable patch %d with unsupported loop feature\n", sp->v.sample); } - /* recalculate address offset */ - sp->v.end -= sp->v.start; - sp->v.loopstart -= sp->v.start; - sp->v.loopend -= sp->v.start; - sp->v.start = 0; - - /* be sure loop points start < end */ - if (sp->v.loopstart >= sp->v.loopend) - swap(sp->v.loopstart, sp->v.loopend); - /* compute true data size to be loaded */ truesize = sp->v.size + BLANK_HEAD_SIZE; if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c index eed47e4830248..c8775c21bc6f2 100644 --- a/sound/synth/emux/soundfont.c +++ b/sound/synth/emux/soundfont.c @@ -689,6 +689,21 @@ find_sample(struct snd_soundfont *sf, int sample_id) } +static int +validate_sample_info(struct soundfont_sample_info *si) +{ + if (si->end < 0 || si->end > si->size) + return -EINVAL; + if (si->loopstart < 0 || si->loopstart > si->end) + return -EINVAL; + if (si->loopend < 0 || si->loopend > si->end) + return -EINVAL; + /* be sure loop points start < end */ + if (si->loopstart > si->loopend) + swap(si->loopstart, si->loopend); + return 0; +} + /* * Load sample information, this can include data to be loaded onto * the soundcard. It can also just be a pointer into soundcard ROM. @@ -730,6 +745,21 @@ load_data(struct snd_sf_list *sflist, const void __user *data, long count) return -EINVAL; } + if (sample_info.size > 0) { + if (sample_info.start < 0) + return -EINVAL; + + // Here we "rebase out" the start address, because the + // real start is the start of the provided sample data. + sample_info.end -= sample_info.start; + sample_info.loopstart -= sample_info.start; + sample_info.loopend -= sample_info.start; + sample_info.start = 0; + + if (validate_sample_info(&sample_info) < 0) + return -EINVAL; + } + /* Allocate a new sample structure */ sp = sf_sample_new(sflist, sf); if (!sp) @@ -980,6 +1010,11 @@ load_guspatch(struct snd_sf_list *sflist, const char __user *data, smp->v.loopend = patch.loop_end; smp->v.size = patch.len; + if (validate_sample_info(&smp->v) < 0) { + sf_sample_delete(sflist, sf, smp); + return -EINVAL; + } + /* set up mode flags */ smp->v.mode_flags = 0; if (!(patch.mode & WAVE_16_BITS)) @@ -1017,7 +1052,7 @@ load_guspatch(struct snd_sf_list *sflist, const char __user *data, /* * load wave data */ - if (sflist->callback.sample_new) { + if (smp->v.size > 0 && sflist->callback.sample_new) { rc = sflist->callback.sample_new (sflist->callback.private_data, smp, sflist->memhdr, data, count); -- 2.53.0