mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-08-19 03:47:27 +00:00
kvm tools: net: don't propagate error codes from tx/rx operations
Currently, if a ->tx or ->rx callback into the net_dev_operations encounters an error, it returns -1 to the virtio-net code, which in turn treats this as an unsigned (size_t) size describing the data available. The resulting memcpy operation then quickly explodes with a SEGV. This patch detects the error code from the low-level callbacks and exits the thread dealing with the erroneous queue. Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
+1
-1
@@ -36,7 +36,7 @@ int uip_tx(struct iovec *iov, u16 out, struct uip_info *info)
|
||||
|
||||
buf = malloc(eth_len);
|
||||
if (!buf)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
|
||||
eth = (struct uip_eth *)buf;
|
||||
for (i = 1; i < out; i++) {
|
||||
|
||||
+16
-4
@@ -81,7 +81,7 @@ static void *virtio_net_rx_thread(void *p)
|
||||
struct net_dev *ndev = p;
|
||||
u16 out, in;
|
||||
u16 head;
|
||||
size_t len, copied;
|
||||
int len, copied;
|
||||
u32 id;
|
||||
|
||||
mutex_lock(&ndev->mutex);
|
||||
@@ -108,11 +108,17 @@ static void *virtio_net_rx_thread(void *p)
|
||||
struct virtio_net_hdr_mrg_rxbuf *hdr;
|
||||
|
||||
len = ndev->ops->rx(&dummy_iov, 1, ndev);
|
||||
if (len < 0) {
|
||||
pr_warning("%s: rx on vq %u failed (%d), exiting thread\n",
|
||||
__func__, id, len);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
copied = 0;
|
||||
head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
|
||||
hdr = (void *)iov[0].iov_base;
|
||||
while (copied < len) {
|
||||
size_t iovsize = min(len - copied, iov_size(iov, in));
|
||||
size_t iovsize = min_t(size_t, len - copied, iov_size(iov, in));
|
||||
|
||||
memcpy_toiovec(iov, buffer + copied, iovsize);
|
||||
copied += iovsize;
|
||||
@@ -131,6 +137,7 @@ static void *virtio_net_rx_thread(void *p)
|
||||
}
|
||||
}
|
||||
|
||||
out_err:
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
|
||||
@@ -165,6 +172,12 @@ static void *virtio_net_tx_thread(void *p)
|
||||
while (virt_queue__available(vq)) {
|
||||
head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
|
||||
len = ndev->ops->tx(iov, out, ndev);
|
||||
if (len < 0) {
|
||||
pr_warning("%s: tx on vq %u failed (%d)\n",
|
||||
__func__, id, len);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
virt_queue__set_used_elem(vq, head, len);
|
||||
}
|
||||
|
||||
@@ -172,10 +185,9 @@ static void *virtio_net_tx_thread(void *p)
|
||||
ndev->vdev.ops->signal_vq(kvm, &ndev->vdev, id);
|
||||
}
|
||||
|
||||
out_err:
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
static virtio_net_ctrl_ack virtio_net_handle_mq(struct kvm* kvm, struct net_dev *ndev, struct virtio_net_ctrl_hdr *ctrl)
|
||||
|
||||
Reference in New Issue
Block a user