diff options
Diffstat (limited to 'net/netfilter/nf_conntrack_ecache.c')
-rw-r--r-- | net/netfilter/nf_conntrack_ecache.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c index a94ac3ad02c..cdcc7649476 100644 --- a/net/netfilter/nf_conntrack_ecache.c +++ b/net/netfilter/nf_conntrack_ecache.c @@ -82,9 +82,12 @@ EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events); int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new) { int ret = 0; + struct nf_ct_event_notifier *notify; mutex_lock(&nf_ct_ecache_mutex); - if (nf_conntrack_event_cb != NULL) { + notify = rcu_dereference_protected(nf_conntrack_event_cb, + lockdep_is_held(&nf_ct_ecache_mutex)); + if (notify != NULL) { ret = -EBUSY; goto out_unlock; } @@ -100,8 +103,12 @@ EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier); void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new) { + struct nf_ct_event_notifier *notify; + mutex_lock(&nf_ct_ecache_mutex); - BUG_ON(nf_conntrack_event_cb != new); + notify = rcu_dereference_protected(nf_conntrack_event_cb, + lockdep_is_held(&nf_ct_ecache_mutex)); + BUG_ON(notify != new); rcu_assign_pointer(nf_conntrack_event_cb, NULL); mutex_unlock(&nf_ct_ecache_mutex); } @@ -110,9 +117,12 @@ EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier); int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new) { int ret = 0; + struct nf_exp_event_notifier *notify; mutex_lock(&nf_ct_ecache_mutex); - if (nf_expect_event_cb != NULL) { + notify = rcu_dereference_protected(nf_expect_event_cb, + lockdep_is_held(&nf_ct_ecache_mutex)); + if (notify != NULL) { ret = -EBUSY; goto out_unlock; } @@ -128,8 +138,12 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier); void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new) { + struct nf_exp_event_notifier *notify; + mutex_lock(&nf_ct_ecache_mutex); - BUG_ON(nf_expect_event_cb != new); + notify = rcu_dereference_protected(nf_expect_event_cb, + lockdep_is_held(&nf_ct_ecache_mutex)); + BUG_ON(notify != new); rcu_assign_pointer(nf_expect_event_cb, NULL); mutex_unlock(&nf_ct_ecache_mutex); } |