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@xxxxxxxxx> --- 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