Hello Paolo, On Mon, Nov 30, 2015, at 12:31, Paolo Abeni wrote: > After 614732eaa12d, no refcount is maintained for the vport-vxlan module. > This allows the userspace to remove such module while vport-vxlan > devices still exist, which leads to later oops. > > v1 -> v2: > - move vport 'owner' initialization in ovs_vport_ops_register() > and make such function a macro > > Fixes: 614732eaa12d ("openvswitch: Use regular VXLAN net_device device") > Signed-off-by: Paolo Abeni <pab...@redhat.com> > --- > net/openvswitch/vport-geneve.c | 1 - > net/openvswitch/vport-gre.c | 1 - > net/openvswitch/vport.c | 4 ++-- > net/openvswitch/vport.h | 8 +++++++- > 4 files changed, 9 insertions(+), 5 deletions(-) > > diff --git a/net/openvswitch/vport-geneve.c > b/net/openvswitch/vport-geneve.c > index efb736b..e41cd12 100644 > --- a/net/openvswitch/vport-geneve.c > +++ b/net/openvswitch/vport-geneve.c > @@ -117,7 +117,6 @@ static struct vport_ops ovs_geneve_vport_ops = { > .destroy = ovs_netdev_tunnel_destroy, > .get_options = geneve_get_options, > .send = dev_queue_xmit, > - .owner = THIS_MODULE, > }; > > static int __init ovs_geneve_tnl_init(void) > diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c > index c3257d7..7f8897f 100644 > --- a/net/openvswitch/vport-gre.c > +++ b/net/openvswitch/vport-gre.c > @@ -89,7 +89,6 @@ static struct vport_ops ovs_gre_vport_ops = { > .create = gre_create, > .send = dev_queue_xmit, > .destroy = ovs_netdev_tunnel_destroy, > - .owner = THIS_MODULE, > }; > > static int __init ovs_gre_tnl_init(void) > diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c > index e194c10a..31cbc8c 100644 > --- a/net/openvswitch/vport.c > +++ b/net/openvswitch/vport.c > @@ -71,7 +71,7 @@ static struct hlist_head *hash_bucket(const struct net > *net, const char *name) > return &dev_table[hash & (VPORT_HASH_BUCKETS - 1)]; > } > > -int ovs_vport_ops_register(struct vport_ops *ops) > +int __ovs_vport_ops_register(struct vport_ops *ops) > { > int err = -EEXIST; > struct vport_ops *o; > @@ -87,7 +87,7 @@ errout: > ovs_unlock(); > return err; > } > -EXPORT_SYMBOL_GPL(ovs_vport_ops_register); > +EXPORT_SYMBOL_GPL(__ovs_vport_ops_register); > > void ovs_vport_ops_unregister(struct vport_ops *ops) > { > diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h > index bdfd82a..8ea3a96 100644 > --- a/net/openvswitch/vport.h > +++ b/net/openvswitch/vport.h > @@ -196,7 +196,13 @@ static inline const char *ovs_vport_name(struct > vport *vport) > return vport->dev->name; > } > > -int ovs_vport_ops_register(struct vport_ops *ops); > +int __ovs_vport_ops_register(struct vport_ops *ops); > +#define ovs_vport_ops_register(ops) \ > + ({ \ > + (ops)->owner = THIS_MODULE; \ > + __ovs_vport_ops_register(ops); \ > + }) > + > void ovs_vport_ops_unregister(struct vport_ops *ops);
This doesn't look correct (the fault is not your patch). The register function adds the list_head of the ops struct on a list without increasing the module reference counter. Thus the module could be removed and the list walk would walk across the unloaded data section left over by the module. Does a kmemdup make sense here and a later free in the unregister function? We test type first and then only touch functions after getting module refcnt, so it would appear safe to me then. Thanks, Hannes -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html