From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752038AbcLFCaq (ORCPT ); Mon, 5 Dec 2016 21:30:46 -0500 Received: from mx1.redhat.com ([209.132.183.28]:50540 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751443AbcLFCan (ORCPT ); Mon, 5 Dec 2016 21:30:43 -0500 Subject: Re: [PATCH] virtio-net: Fix DMA-from-the-stack in virtnet_set_mac_address() To: Andy Lutomirski , netdev@vger.kernel.org References: Cc: linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org, "Michael S . Tsirkin" , Laura Abbott From: Jason Wang Message-ID: <05232199-2e0c-3fe5-ef85-c0013f017a69@redhat.com> Date: Tue, 6 Dec 2016 10:30:37 +0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 06 Dec 2016 02:30:43 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2016年12月06日 10:10, Andy Lutomirski wrote: > 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 > Cc: Jason Wang > Cc: Laura Abbott > Reported-by: zbyszek@in.waw.pl > Signed-off-by: Andy Lutomirski > --- > > Very lightly tested. > > drivers/net/virtio_net.c | 19 ++++++++++++++----- > 1 file changed, 14 insertions(+), 5 deletions(-) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index 7276d5a95bd0..cbf1c613c67a 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -969,12 +969,17 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p) > struct virtnet_info *vi = netdev_priv(dev); > struct virtio_device *vdev = vi->vdev; > int ret; > - struct sockaddr *addr = p; > + struct sockaddr *addr; > struct scatterlist sg; > > - ret = eth_prepare_mac_addr_change(dev, p); > + addr = kmalloc(sizeof(*addr), GFP_KERNEL); > + if (!addr) > + return -ENOMEM; > + memcpy(addr, p, sizeof(*addr)); > + > + ret = eth_prepare_mac_addr_change(dev, addr); > if (ret) > - return ret; > + goto out; > > if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR)) { > sg_init_one(&sg, addr->sa_data, dev->addr_len); > @@ -982,7 +987,8 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p) > VIRTIO_NET_CTRL_MAC_ADDR_SET, &sg)) { > dev_warn(&vdev->dev, > "Failed to set mac address by vq command.\n"); > - return -EINVAL; > + ret = -EINVAL; > + goto out; > } > } else if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC) && > !virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) { > @@ -996,8 +1002,11 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p) > } > > eth_commit_mac_addr_change(dev, p); > + ret = 0; > > - return 0; > +out: > + kfree(addr); > + return ret; > } > > static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev, Acked-by: Jason Wang