aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/net_namespace.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2017-05-30 05:38:12 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2017-06-19 13:09:19 -0400
commit7866cc57b51c1e118e5d78d1a8f721f378eec5c4 (patch)
treee1ce697fb956d559617dc47bb99743fc54b7f2f8 /net/core/net_namespace.c
parent2c41f33c1b7030448212cdacd40e80796e347eac (diff)
netns: add and use net_ns_barrier
Quoting Joe Stringer: If a user loads nf_conntrack_ftp, sends FTP traffic through a network namespace, destroys that namespace then unloads the FTP helper module, then the kernel will crash. Events that lead to the crash: 1. conntrack is created with ftp helper in netns x 2. This netns is destroyed 3. netns destruction is scheduled 4. netns destruction wq starts, removes netns from global list 5. ftp helper is unloaded, which resets all helpers of the conntracks via for_each_net() but because netns is already gone from list the for_each_net() loop doesn't include it, therefore all of these conntracks are unaffected. 6. helper module unload finishes 7. netns wq invokes destructor for rmmod'ed helper CC: "Eric W. Biederman" <ebiederm@xmission.com> Reported-by: Joe Stringer <joe@ovn.org> Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: David S. Miller <davem@davemloft.net> Acked-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/core/net_namespace.c')
-rw-r--r--net/core/net_namespace.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 1934efd4a9d4..1f15abb1d733 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -482,6 +482,23 @@ static void cleanup_net(struct work_struct *work)
482 net_drop_ns(net); 482 net_drop_ns(net);
483 } 483 }
484} 484}
485
486/**
487 * net_ns_barrier - wait until concurrent net_cleanup_work is done
488 *
489 * cleanup_net runs from work queue and will first remove namespaces
490 * from the global list, then run net exit functions.
491 *
492 * Call this in module exit path to make sure that all netns
493 * ->exit ops have been invoked before the function is removed.
494 */
495void net_ns_barrier(void)
496{
497 mutex_lock(&net_mutex);
498 mutex_unlock(&net_mutex);
499}
500EXPORT_SYMBOL(net_ns_barrier);
501
485static DECLARE_WORK(net_cleanup_work, cleanup_net); 502static DECLARE_WORK(net_cleanup_work, cleanup_net);
486 503
487void __put_net(struct net *net) 504void __put_net(struct net *net)