linux-hyperv.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] hv: account for packet descriptor in maximum packet size
@ 2021-12-12 12:13 Yanming Liu
  2021-12-13  1:47 ` Andrea Parri
  0 siblings, 1 reply; 10+ messages in thread
From: Yanming Liu @ 2021-12-12 12:13 UTC (permalink / raw)
  To: linux-hyperv
  Cc: Andrea Parri (Microsoft), Andres Beltran, Dexuan Cui, Wei Liu,
	Stephen Hemminger, Haiyang Zhang, K. Y. Srinivasan, Yanming Liu

Commit adae1e931acd ("Drivers: hv: vmbus: Copy packets sent by Hyper-V
out of the ring buffer") introduced a notion of maximum packet size and
used that size to initialize a buffer holding all incoming packet along
with their vmpacket_descriptor header. All vmbus drivers set the maximum
packet size to the size of their receive buffer. However most drivers
are expecting this maximum packet size being packet payload size due to
vmbus_recvpacket() stripping the packet descriptor off. This leads to
corruption of the ring buffer state when receiving a maximum sized
packet.

Specifically, in hv_balloon I have observed of a dm_unballoon_request
message of 4096 bytes being truncated to 4080 bytes. When the driver
tries to read next packet it starts from the wrong read_index, receives
garbage and prints a lot of "Unhandled message: type: <garbage>" in
dmesg.

Allocate the packet buffer with 'sizeof(struct vmpacket_descriptor)'
more bytes to make room for the descriptor. This is still flawed as
'desc->offset8' may not match the packet descriptor size, but this is
impossible to handle correctly without re-designing the original patch
and I have not observed such packets sent by Hyper-V in practice.

Fixes: adae1e931acd ("Drivers: hv: vmbus: Copy packets sent by Hyper-V out of the ring buffer")
Signed-off-by: Yanming Liu <yanminglr@gmail.com>
---
 drivers/hv/ring_buffer.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 71efacb90965..e403ed4755ed 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -256,6 +256,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
 
 	/* Initialize buffer that holds copies of incoming packets */
 	if (max_pkt_size) {
+		max_pkt_size += sizeof(struct vmpacket_descriptor);
 		ring_info->pkt_buffer = kzalloc(max_pkt_size, GFP_KERNEL);
 		if (!ring_info->pkt_buffer)
 			return -ENOMEM;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-12-15 14:05 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-12-12 12:13 [PATCH] hv: account for packet descriptor in maximum packet size Yanming Liu
2021-12-13  1:47 ` Andrea Parri
2021-12-13  6:44   ` Yanming Liu
2021-12-13 17:01   ` Yanming Liu
2021-12-14  2:06     ` Andrea Parri
2021-12-14  4:28       ` Andrea Parri
2021-12-14 16:28         ` Yanming Liu
2021-12-14 21:36           ` Andrea Parri
2021-12-15 12:30             ` Yanming Liu
2021-12-15 14:05               ` Andrea Parri

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).