Skip to content

Commit e37e2ff

Browse files
amlutodavem330
authored andcommitted
virtio-net: Fix DMA-from-the-stack in virtnet_set_mac_address()
With CONFIG_VMAP_STACK=y, virtnet_set_mac_address() can be passed a pointer to the stack and it will OOPS. Copy the address to the heap to prevent the crash. Cc: Michael S. Tsirkin <mst@redhat.com> Cc: Jason Wang <jasowang@redhat.com> Cc: Laura Abbott <labbott@redhat.com> Reported-by: zbyszek@in.waw.pl Signed-off-by: Andy Lutomirski <luto@kernel.org> Acked-by: Jason Wang <jasowang@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent dcb17d2 commit e37e2ff

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

drivers/net/virtio_net.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -969,20 +969,26 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p)
969969
struct virtnet_info *vi = netdev_priv(dev);
970970
struct virtio_device *vdev = vi->vdev;
971971
int ret;
972-
struct sockaddr *addr = p;
972+
struct sockaddr *addr;
973973
struct scatterlist sg;
974974

975-
ret = eth_prepare_mac_addr_change(dev, p);
975+
addr = kmalloc(sizeof(*addr), GFP_KERNEL);
976+
if (!addr)
977+
return -ENOMEM;
978+
memcpy(addr, p, sizeof(*addr));
979+
980+
ret = eth_prepare_mac_addr_change(dev, addr);
976981
if (ret)
977-
return ret;
982+
goto out;
978983

979984
if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR)) {
980985
sg_init_one(&sg, addr->sa_data, dev->addr_len);
981986
if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC,
982987
VIRTIO_NET_CTRL_MAC_ADDR_SET, &sg)) {
983988
dev_warn(&vdev->dev,
984989
"Failed to set mac address by vq command.\n");
985-
return -EINVAL;
990+
ret = -EINVAL;
991+
goto out;
986992
}
987993
} else if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC) &&
988994
!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
@@ -996,8 +1002,11 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p)
9961002
}
9971003

9981004
eth_commit_mac_addr_change(dev, p);
1005+
ret = 0;
9991006

1000-
return 0;
1007+
out:
1008+
kfree(addr);
1009+
return ret;
10011010
}
10021011

10031012
static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev,

0 commit comments

Comments
 (0)