vxlan: fix use-after-free on deletion
[ Upstream commit a53cb29b0af346af44e4abf13d7e59f807fba690 ] Adding a vxlan interface to a socket isn't symmetrical, while adding is done in vxlan_open() the deletion is done in vxlan_dellink(). This can cause a use-after-free error when we close the vxlan interface before deleting it. We add vxlan_vs_del_dev() to match vxlan_vs_add_dev() and call it from vxlan_stop() to match the call from vxlan_open(). Fixes: 56ef9c909b40 ("vxlan: Move socket initialization to within rtnl scope") Acked-by: Jiri Benc <jbenc@redhat.com> Tested-by: Roi Dayan <roid@mellanox.com> Signed-off-by: Mark Bloch <markb@mellanox.com> Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
f4c645f67e
commit
92d88e8a7a
@ -77,6 +77,8 @@ static const u8 all_zeros_mac[ETH_ALEN];
|
||||
|
||||
static int vxlan_sock_add(struct vxlan_dev *vxlan);
|
||||
|
||||
static void vxlan_vs_del_dev(struct vxlan_dev *vxlan);
|
||||
|
||||
/* per-network namespace private data for this module */
|
||||
struct vxlan_net {
|
||||
struct list_head vxlan_list;
|
||||
@ -1052,6 +1054,8 @@ static void __vxlan_sock_release(struct vxlan_sock *vs)
|
||||
|
||||
static void vxlan_sock_release(struct vxlan_dev *vxlan)
|
||||
{
|
||||
vxlan_vs_del_dev(vxlan);
|
||||
|
||||
__vxlan_sock_release(vxlan->vn4_sock);
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
__vxlan_sock_release(vxlan->vn6_sock);
|
||||
@ -2255,6 +2259,15 @@ static void vxlan_cleanup(unsigned long arg)
|
||||
mod_timer(&vxlan->age_timer, next_timer);
|
||||
}
|
||||
|
||||
static void vxlan_vs_del_dev(struct vxlan_dev *vxlan)
|
||||
{
|
||||
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
|
||||
|
||||
spin_lock(&vn->sock_lock);
|
||||
hlist_del_init_rcu(&vxlan->hlist);
|
||||
spin_unlock(&vn->sock_lock);
|
||||
}
|
||||
|
||||
static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan)
|
||||
{
|
||||
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
|
||||
@ -3028,12 +3041,6 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev,
|
||||
static void vxlan_dellink(struct net_device *dev, struct list_head *head)
|
||||
{
|
||||
struct vxlan_dev *vxlan = netdev_priv(dev);
|
||||
struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
|
||||
|
||||
spin_lock(&vn->sock_lock);
|
||||
if (!hlist_unhashed(&vxlan->hlist))
|
||||
hlist_del_rcu(&vxlan->hlist);
|
||||
spin_unlock(&vn->sock_lock);
|
||||
|
||||
gro_cells_destroy(&vxlan->gro_cells);
|
||||
list_del(&vxlan->next);
|
||||
|
Loading…
x
Reference in New Issue
Block a user