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=1793827134; b=Qg79vwJjyp9+LPRYOezZqDv75T9K432Tr8G+Nb7aehnRpXVUG/A/E0zeE50Qc6SAexbJ cN+Er9Ky22QS1/Mf+4Vp8cwRXx0U4AP2XrGaueSZBmh4LojQl149FYWxTKfEdEaYmTe4K zO6ESe5ITWS509XhWOZHmXaJykT99vbtLt7df+s+CKOhad1dRTuDD0BTYYOzocUoIZ/IE OSCUdGB04olPgCJbruxUrcDp0XSP4x/1XJY7Xdae76spwF2ObH+uWEJW2bXorMMF3Bwvs XlIOOs2Ym/JxLnh1dcf/vL4NNE5U3BNd9kA8zjzlUbfeoc1Pw3q3Wxf+iMGQn6AMV0w== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793827134; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=8Mzj53nENEgVTE/hh5MqW6jTH3kgVlHOHyvZlQHgsGU=; b=MdcZUI3GCNDFUhpGOwmPFMcG+wVZr8Eb6PfARnIWRP42xJTnPL5FVe+hs4bAxvxINtfK ZMnbTp5ohEi4PDt6vvoUrEpbG//XsNyY2oSqv9QyePZmO6F9TzLVg78XwQWnAEGvlZDHS ToEnAyhM5jz5x72DA1YzQQZi84qsIwB5BgZyOIbUQGdIiGWbBcqu51GO7NjU4VJjLiVve GZRuHMAFLJxbkK2CfXeX4Z/iiU1ssEk26wQWnU5u5MawrSRjx38YFqV9/n8H7pmOvunS3 TGMM49gEPGkM0Q0Kg7uEjJyVphtf3nmxKZtLveE/GfejnPc9379hj3MVmvPnAfPHSdA== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=Nf8dbItD; 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 143DA606A871; Wed, 4 Nov 2026 21:18:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key, unprotected) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=Nf8dbItD Received: by smtp.kernel.org (Postfix) with ESMTPSA id A2CC51F000C1; Wed, 4 Nov 2026 21:18:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1793827133; bh=8Mzj53nENEgVTE/hh5MqW6jTH3kgVlHOHyvZlQHgsGU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Nf8dbItDYNuV1dpBzcnJ/8PscVlrIl3YbTBplW5UPaTaC9VlcT4j9b3zyXcq9LHXY vVTRWudfRQiDo5FyXLIyDXvNychBJdwsokY9je9WW/EOAMqErL7xX7PIhPdIfSK0Nt yXnioGYmhaP5+HZOBkRczL8TT8G0gdDIZU+fViUE= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Sung Byeongchan , Takashi Iwai Subject: [PATCH 7.3 207/547] ALSA: pcmtest: handle multiple wraps in random capture fill Date: Wed, 4 Nov 2026 16:06:31 -0500 Message-ID: <20261104211044.026248840@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261104211038.406938024@linuxfoundation.org> References: <20261104211038.406938024@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: patches@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 7.3-stable review patch. If anyone has any objections, please let me know. ------------------ From: Sung Byeongchan commit 6541871e8e63e721733cd120af4d9cd22c5ef62f upstream. The random capture helpers assume that the data generated for one timer tick wraps the DMA ring at most once. However, b_rw describes 200 ms of audio because the timer runs at 5 Hz, so it can be several times larger than a small ring. For 48 kHz, S16_LE, four-channel capture with a 512-frame buffer, the DMA ring is 4096 bytes while one tick generates 76800 bytes. After filling the 4096-byte tail, the existing code issues a second 72704-byte write from the ring base, writing 68608 bytes beyond the ring. Both interleaved and non-interleaved capture are affected. KASAN reports the first write into the adjacent free page as a use-after-free in the random-byte generator. The underlying defect is an out-of-bounds write from the live DMA ring, not a stale DMA allocation. Split each random write repeatedly at the interleaved ring or per-channel block boundary. Keep the hardware-pointer update exactly once after the complete logical write. The issue reproduced on three of three clean boots. With this change, the same vulnerable geometry completed six times without a sanitizer finding. Boundary, pattern-fill, no-timer, open/close, and module-reload controls also completed normally. snd-pcmtest is a test driver, and selecting random fill requires an administrator-controlled module parameter. The written values come from the kernel random generator; no privilege escalation or attacker-controlled write primitive was demonstrated. Fixes: 315a3d57c64c ("ALSA: Implement the new Virtual PCM Test Driver") Cc: stable@vger.kernel.org Assisted-by: OpenAI Codex Signed-off-by: Sung Byeongchan Link: https://patch.msgid.link/20261003101854.1423146-1-tjdqudcks0424@naver.com Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/drivers/pcmtest.c | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) --- a/sound/drivers/pcmtest.c +++ b/sound/drivers/pcmtest.c @@ -280,39 +280,35 @@ static void fill_block_pattern(struct pc fill_block_pattern_n(v_iter, runtime); } +static void fill_random_block(char *buf, size_t buf_size, size_t pos, + size_t count) +{ + while (count) { + size_t chunk = min(count, buf_size - pos); + + get_random_bytes(buf + pos, chunk); + count -= chunk; + pos = 0; + } +} + static void fill_block_rand_n(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime) { unsigned int channels = runtime->channels; - // Remaining space in all channel buffers - size_t bytes_remain = runtime->dma_bytes - v_iter->buf_pos; + size_t pos = v_iter->buf_pos / channels; unsigned int i; - for (i = 0; i < channels; i++) { - if (v_iter->b_rw <= bytes_remain) { - //b_rw - count of bytes must be written for all channels at each timer tick - get_random_bytes(runtime->dma_area + buf_pos_n(v_iter, channels, i), - v_iter->b_rw / channels); - } else { - // Write to the end of buffer and start from the beginning of it - get_random_bytes(runtime->dma_area + buf_pos_n(v_iter, channels, i), - bytes_remain / channels); - get_random_bytes(runtime->dma_area + v_iter->chan_block * i, - (v_iter->b_rw - bytes_remain) / channels); - } - } + for (i = 0; i < channels; i++) + fill_random_block(runtime->dma_area + v_iter->chan_block * i, + v_iter->chan_block, pos, + v_iter->b_rw / channels); inc_buf_pos(v_iter, v_iter->b_rw, runtime->dma_bytes); } static void fill_block_rand_i(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runtime *runtime) { - size_t in_cur_block = runtime->dma_bytes - v_iter->buf_pos; - - if (v_iter->b_rw <= in_cur_block) { - get_random_bytes(&runtime->dma_area[v_iter->buf_pos], v_iter->b_rw); - } else { - get_random_bytes(&runtime->dma_area[v_iter->buf_pos], in_cur_block); - get_random_bytes(runtime->dma_area, v_iter->b_rw - in_cur_block); - } + fill_random_block(runtime->dma_area, runtime->dma_bytes, + v_iter->buf_pos, v_iter->b_rw); inc_buf_pos(v_iter, v_iter->b_rw, runtime->dma_bytes); }