From: Kirill Tkhai <ktk...@virtuozzo.com> Date: Tue, 16 Jan 2018 12:31:41 +0300
> peernet2id_alloc() is racy without rtnl_lock() as refcount_read(&peer->count) > under net->nsid_lock does not guarantee, peer is alive: > > rcu_read_lock() > peernet2id_alloc() .. > spin_lock_bh(&net->nsid_lock) .. > refcount_read(&peer->count) (!= 0) .. > .. put_net() > .. cleanup_net() > .. for_each_net(tmp) > .. > spin_lock_bh(&tmp->nsid_lock) > .. __peernet2id(tmp, net) == > -1 > .. .. > .. .. > __peernet2id_alloc(alloc == true) .. > .. .. > rcu_read_unlock() .. > .. synchronize_rcu() > .. kmem_cache_free(net) > > After the above situation, net::netns_id contains id pointing to freed memory, > and any other dereferencing by the id will operate with this freed memory. > > Currently, peernet2id_alloc() is used under rtnl_lock() everywhere except > ovs_vport_cmd_fill_info(), and this race can't occur. But peernet2id_alloc() > is generic interface, and better we fix it before someone really starts > use it in wrong context. > > v2: Don't place refcount_read(&net->count) under net->nsid_lock > as suggested by Eric W. Biederman <ebied...@xmission.com> > v3: Rebase on top of net-next > > Signed-off-by: Kirill Tkhai <ktk...@virtuozzo.com> Applied to net-next.