Commit d8316f39 authored by MST's avatar MST Committed by David S. Miller
Browse files

vhost: fix total length when packets are too short

When mergeable buffers are disabled, and the
incoming packet is too large for the rx buffer,
get_rx_bufs returns success.

This was intentional in order for make recvmsg
truncate the packet and then handle_rx would
detect err != sock_len and drop it.

Unfortunately we pass the original sock_len to
recvmsg - which means we use parts of iov not fully

Fix this up by detecting this overrun and doing packet drop

Signed-off-by: MST's avatarMichael S. Tsirkin <>
Signed-off-by: default avatarDavid S. Miller <>
parent 05efa8c9
......@@ -532,6 +532,12 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
*iovcount = seg;
if (unlikely(log))
*log_num = nlogs;
/* Detect overrun */
if (unlikely(datalen > 0)) {
r = UIO_MAXIOV + 1;
goto err;
return headcount;
vhost_discard_vq_desc(vq, headcount);
......@@ -587,6 +593,14 @@ static void handle_rx(struct vhost_net *net)
/* On error, stop handling until the next kick. */
if (unlikely(headcount < 0))
/* On overrun, truncate and discard */
if (unlikely(headcount > UIO_MAXIOV)) {
msg.msg_iovlen = 1;
err = sock->ops->recvmsg(NULL, sock, &msg,
pr_debug("Discarded rx packet: len %zd\n", sock_len);
/* OK, now we need to know about added descriptors. */
if (!headcount) {
if (unlikely(vhost_enable_notify(&net->dev, vq))) {
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment