do {
virtqueue_disable_cb(vq);
for (;;) {
+ unsigned int len, payload_len;
+ struct virtio_vsock_hdr *hdr;
struct sk_buff *skb;
- unsigned int len;
if (!virtio_transport_more_replies(vsock)) {
/* Stop rx until the device processes already
vsock->rx_buf_nr--;
/* Drop short/long packets */
- if (unlikely(len < sizeof(struct virtio_vsock_hdr) ||
+ if (unlikely(len < sizeof(*hdr) ||
len > virtio_vsock_skb_len(skb))) {
kfree_skb(skb);
continue;
}
+ hdr = virtio_vsock_hdr(skb);
+ payload_len = le32_to_cpu(hdr->len);
+ if (unlikely(payload_len > len - sizeof(*hdr))) {
+ kfree_skb(skb);
+ continue;
+ }
+
virtio_vsock_skb_rx_put(skb);
virtio_transport_deliver_tap_pkt(skb);
virtio_transport_recv_pkt(&virtio_transport, skb);