summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArseniy Krasnov <avkrasnov@sberdevices.ru>2023-03-28 14:31:28 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-11-20 11:52:19 +0100
commit830c11c9c085154b3d2ec827739c8c3940743b88 (patch)
tree4c428013b1b40d826da623e3946a50b5074828fd
parentcd12535b97dd7d18cf655ec78ce1cf1f29a576be (diff)
downloadlinux-stable-830c11c9c085154b3d2ec827739c8c3940743b88.tar.gz
linux-stable-830c11c9c085154b3d2ec827739c8c3940743b88.tar.bz2
linux-stable-830c11c9c085154b3d2ec827739c8c3940743b88.zip
virtio/vsock: fix header length on skb merging
commit f7154d967bc4ee25ea1572937550e711b2525474 upstream. This fixes appending newly arrived skbuff to the last skbuff of the socket's queue. Problem fires when we are trying to append data to skbuff which was already processed in dequeue callback at least once. Dequeue callback calls function 'skb_pull()' which changes 'skb->len'. In current implementation 'skb->len' is used to update length in header of the last skbuff after new data was copied to it. This is bug, because value in header is used to calculate 'rx_bytes'/'fwd_cnt' and thus must be not be changed during skbuff's lifetime. Bug starts to fire since: commit 077706165717 ("virtio/vsock: don't use skbuff state to account credit") It presents before, but didn't triggered due to a little bit buggy implementation of credit calculation logic. So use Fixes tag for it. Fixes: 077706165717 ("virtio/vsock: don't use skbuff state to account credit") Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/vmw_vsock/virtio_transport_common.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index 72e3b8a2ee1a..79e79fd6efd1 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -1075,7 +1075,7 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk,
memcpy(skb_put(last_skb, skb->len), skb->data, skb->len);
free_pkt = true;
last_hdr->flags |= hdr->flags;
- last_hdr->len = cpu_to_le32(last_skb->len);
+ le32_add_cpu(&last_hdr->len, len);
goto out;
}
}