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=1794061480; b=461TWXVVQ97Q1S1v3fguk0uuCqg0j7KyUkDJe+XJjdH845Mb2c9v64c/8/sYKoOkzyGw K2ee81k8N7XHm2PsPTNxXqw6Qxg19uyBo5ANC23YLFS02o+Z7TWt+7n5PWnHwY7xq3KTV KgD11oYWAa+xJWGNV3wtoJRQNyDUQUdhagaRDsnzm/kBVupn5P1ltvXbVsNyiMmw6Z08p Oi+sOScokSRknBogtgoBPF2La6yCAgjlxQlnn0zrDusGdDbhrMpzkfCf2wnTNbm7DyQwb k/2xckvo/3l9Pee+1XZLVeaXAqxDbwiValcnFv4r1hSr6haG5geTEkCi2ER4kzjIJ1A== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794061480; 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=kZeauFbO5EslmVUVVuVCJOwsSx+vygnXPzqMov0/gec=; b=kYI+ckfKThtxgfkKOK7gzqntglnfdkwiKODf/kPp2Fl1TvM0zOVc7Ocu6JJS2bBb+BE1 ReiQqjjXrTavA2yh4HH0WNRpkViFZhAhlIQDpIifn0uVJXsks9V7gvv4y1Bop4PTB7Xeo /Aop7h7oM3yPkv/JfBHCdbyaIaHNtkb9Ce52oCzcvlD25I07dNRovhCFqIKJ0+remmDVT Gel2y1PbWqQybBimqz5cNLX/VfOgyXTXVQSkM2unwkoAW/bzQNb1qggZD3XZpRinsG7Cw 2L5W2+wYL7ohgDPOcYZYIYGSdAw9qmOfBdIdufW6HP28BaYJDrrjZfxh1gYU393p/YA== 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=E14ECMzi; 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 121A0606A326; Sat, 7 Nov 2026 14:24:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=E14ECMzi Received: by smtp.kernel.org (Postfix) with ESMTPSA id AA89E1F0089F; Sat, 7 Nov 2026 14:24:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794061479; bh=kZeauFbO5EslmVUVVuVCJOwsSx+vygnXPzqMov0/gec=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=E14ECMzi+f44/Ucz5p41B4rfUsvk318s9h5J868AOHjnXi75+/UCNU624DJs64Yp6 louc4d0FYshJU0t3NuzkDRf4BC+AiEFwf6l6EOnraqamvHNxpcfkoz1xY8F/x4fRqg GSrCJDkTMM/DxcpFqdftwDWOPFQdX+jMHOppsQuw= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Michael Kelley , Kameron Carr , Wei Liu Subject: [PATCH 6.12 0577/1536] Drivers: hv: vmbus: Bounds check the shared ring buffer indices Date: Sat, 7 Nov 2026 08:43:13 -0500 Message-ID: <20261107135013.766626076@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261107134957.653319350@linuxfoundation.org> References: <20261107134957.653319350@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore 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 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Kameron Carr commit 1d287c17cc5bfd6386fe0770999be410b248d021 upstream. In a CoCo VM the host is untrusted. Since the VMBus ring buffer read and write indices live in shared memory, the guest has to treat both as potentially malicious. hv_ringbuffer_write() copies into the ring at write_index with no bounds checking, so the host can make the guest write packet data at any offset up to 4 GiB past the start of the ring buffer. read_index matters too: the available space derived from both indices is the only bound on how much is copied, and an out-of-range index can make it far larger than the ring. The fix is to validate both indices before use and to use the validated snapshot instead of re-accessing. For invalid indices, hv_ringbuffer_write() logs and returns -EIO. One re-read of write_index is left unchecked in this patch: hv_get_ring_bufferindices() fetches it again for the prev_indices trailer. The value is only returned to the host and is not used as an offset or length for indexing. Since this is not a security issue, it is addressed later in the series. Open-coding the bytes available arithmetic keeps the fix free of prerequisites; a later patch refactors it into a helper function. Fixes: 3e7ee4902fe6 ("Staging: hv: add the Hyper-V virtual bus") Cc: stable@vger.kernel.org # 5.15.x Reviewed-by: Michael Kelley Signed-off-by: Kameron Carr Signed-off-by: Wei Liu Signed-off-by: Greg Kroah-Hartman --- drivers/hv/ring_buffer.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -69,15 +69,6 @@ static void hv_signal_on_write(u32 old_w } } -/* Get the next write location for the specified ring buffer. */ -static inline u32 -hv_get_next_write_location(struct hv_ring_buffer_info *ring_info) -{ - u32 next = ring_info->ring_buffer->write_index; - - return next; -} - /* Set the next write location for the specified ring buffer. */ static inline void hv_set_next_write_location(struct hv_ring_buffer_info *ring_info, @@ -281,6 +272,7 @@ int hv_ringbuffer_write(struct vmbus_cha u32 totalbytes_towrite = sizeof(u64); u32 next_write_location; u32 old_write; + u32 read_index; u64 prev_indices; unsigned long flags; struct hv_ring_buffer_info *outring_info = &channel->outbound; @@ -295,7 +287,20 @@ int hv_ringbuffer_write(struct vmbus_cha spin_lock_irqsave(&outring_info->ring_lock, flags); - bytes_avail_towrite = hv_get_bytes_to_write(outring_info); + read_index = READ_ONCE(outring_info->ring_buffer->read_index); + old_write = READ_ONCE(outring_info->ring_buffer->write_index); + if (unlikely(read_index >= outring_info->ring_datasize || + old_write >= outring_info->ring_datasize)) { + spin_unlock_irqrestore(&outring_info->ring_lock, flags); + pr_err_ratelimited("outbound ring indices out of range: relid %u read %u write %u size %u\n", + channel->offermsg.child_relid, read_index, + old_write, outring_info->ring_datasize); + return -EIO; + } + + bytes_avail_towrite = old_write >= read_index ? + outring_info->ring_datasize - (old_write - read_index) : + read_index - old_write; /* * If there is only room for the packet, assume it is full. @@ -317,9 +322,7 @@ int hv_ringbuffer_write(struct vmbus_cha channel->out_full_flag = false; /* Write to the ring buffer */ - next_write_location = hv_get_next_write_location(outring_info); - - old_write = next_write_location; + next_write_location = old_write; for (i = 0; i < kv_count; i++) { next_write_location = hv_copyto_ringbuffer(outring_info,