Skip to content

Commit 969b06b

Browse files
willdeacongregkh
authored andcommitted
vsock/virtio: Validate length in packet header before skb_put()
commit 0dab924 upstream. When receiving a vsock packet in the guest, only the virtqueue buffer size is validated prior to virtio_vsock_skb_rx_put(). Unfortunately, virtio_vsock_skb_rx_put() uses the length from the packet header as the length argument to skb_put(), potentially resulting in SKB overflow if the host has gone wonky. Validate the length as advertised by the packet header before calling virtio_vsock_skb_rx_put(). Cc: <stable@vger.kernel.org> Fixes: 71dc9ec ("virtio/vsock: replace virtio_vsock_pkt with sk_buff") Signed-off-by: Will Deacon <will@kernel.org> Message-Id: <20250717090116.11987-3-will@kernel.org> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 85ea58d commit 969b06b

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

net/vmw_vsock/virtio_transport.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,9 @@ static void virtio_transport_rx_work(struct work_struct *work)
494494
do {
495495
virtqueue_disable_cb(vq);
496496
for (;;) {
497+
unsigned int len, payload_len;
498+
struct virtio_vsock_hdr *hdr;
497499
struct sk_buff *skb;
498-
unsigned int len;
499500

500501
if (!virtio_transport_more_replies(vsock)) {
501502
/* Stop rx until the device processes already
@@ -512,12 +513,19 @@ static void virtio_transport_rx_work(struct work_struct *work)
512513
vsock->rx_buf_nr--;
513514

514515
/* Drop short/long packets */
515-
if (unlikely(len < sizeof(struct virtio_vsock_hdr) ||
516+
if (unlikely(len < sizeof(*hdr) ||
516517
len > virtio_vsock_skb_len(skb))) {
517518
kfree_skb(skb);
518519
continue;
519520
}
520521

522+
hdr = virtio_vsock_hdr(skb);
523+
payload_len = le32_to_cpu(hdr->len);
524+
if (unlikely(payload_len > len - sizeof(*hdr))) {
525+
kfree_skb(skb);
526+
continue;
527+
}
528+
521529
virtio_vsock_skb_rx_put(skb);
522530
virtio_transport_deliver_tap_pkt(skb);
523531
virtio_transport_recv_pkt(&virtio_transport, skb);

0 commit comments

Comments
 (0)