Commit ed86308f authored by Patrick McHardy's avatar Patrick McHardy

netfilter: remove invalid rcu_dereference() calls

The CONFIG_PROVE_RCU option discovered a few invalid uses of
rcu_dereference() in netfilter. In all these cases, the code code
intends to check whether a pointer is already assigned when
performing registration or whether the assigned pointer matches
when performing unregistration. The entire registration/
unregistration is protected by a mutex, so we don't need the
rcu_dereference() calls.
Reported-by: default avatarValdis Kletnieks <Valdis.Kletnieks@vt.edu>
Tested-by: default avatarValdis Kletnieks <Valdis.Kletnieks@vt.edu>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent e9f13cab
...@@ -81,11 +81,9 @@ EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events); ...@@ -81,11 +81,9 @@ EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new) int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new)
{ {
int ret = 0; int ret = 0;
struct nf_ct_event_notifier *notify;
mutex_lock(&nf_ct_ecache_mutex); mutex_lock(&nf_ct_ecache_mutex);
notify = rcu_dereference(nf_conntrack_event_cb); if (nf_conntrack_event_cb != NULL) {
if (notify != NULL) {
ret = -EBUSY; ret = -EBUSY;
goto out_unlock; goto out_unlock;
} }
...@@ -101,11 +99,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier); ...@@ -101,11 +99,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new) void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new)
{ {
struct nf_ct_event_notifier *notify;
mutex_lock(&nf_ct_ecache_mutex); mutex_lock(&nf_ct_ecache_mutex);
notify = rcu_dereference(nf_conntrack_event_cb); BUG_ON(nf_conntrack_event_cb != new);
BUG_ON(notify != new);
rcu_assign_pointer(nf_conntrack_event_cb, NULL); rcu_assign_pointer(nf_conntrack_event_cb, NULL);
mutex_unlock(&nf_ct_ecache_mutex); mutex_unlock(&nf_ct_ecache_mutex);
} }
...@@ -114,11 +109,9 @@ EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier); ...@@ -114,11 +109,9 @@ EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new) int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new)
{ {
int ret = 0; int ret = 0;
struct nf_exp_event_notifier *notify;
mutex_lock(&nf_ct_ecache_mutex); mutex_lock(&nf_ct_ecache_mutex);
notify = rcu_dereference(nf_expect_event_cb); if (nf_expect_event_cb != NULL) {
if (notify != NULL) {
ret = -EBUSY; ret = -EBUSY;
goto out_unlock; goto out_unlock;
} }
...@@ -134,11 +127,8 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier); ...@@ -134,11 +127,8 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier);
void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new) void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new)
{ {
struct nf_exp_event_notifier *notify;
mutex_lock(&nf_ct_ecache_mutex); mutex_lock(&nf_ct_ecache_mutex);
notify = rcu_dereference(nf_expect_event_cb); BUG_ON(nf_expect_event_cb != new);
BUG_ON(notify != new);
rcu_assign_pointer(nf_expect_event_cb, NULL); rcu_assign_pointer(nf_expect_event_cb, NULL);
mutex_unlock(&nf_ct_ecache_mutex); mutex_unlock(&nf_ct_ecache_mutex);
} }
......
...@@ -35,7 +35,6 @@ static struct nf_logger *__find_logger(int pf, const char *str_logger) ...@@ -35,7 +35,6 @@ static struct nf_logger *__find_logger(int pf, const char *str_logger)
/* return EEXIST if the same logger is registred, 0 on success. */ /* return EEXIST if the same logger is registred, 0 on success. */
int nf_log_register(u_int8_t pf, struct nf_logger *logger) int nf_log_register(u_int8_t pf, struct nf_logger *logger)
{ {
const struct nf_logger *llog;
int i; int i;
if (pf >= ARRAY_SIZE(nf_loggers)) if (pf >= ARRAY_SIZE(nf_loggers))
...@@ -52,8 +51,7 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger) ...@@ -52,8 +51,7 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
} else { } else {
/* register at end of list to honor first register win */ /* register at end of list to honor first register win */
list_add_tail(&logger->list[pf], &nf_loggers_l[pf]); list_add_tail(&logger->list[pf], &nf_loggers_l[pf]);
llog = rcu_dereference(nf_loggers[pf]); if (nf_loggers[pf] == NULL)
if (llog == NULL)
rcu_assign_pointer(nf_loggers[pf], logger); rcu_assign_pointer(nf_loggers[pf], logger);
} }
...@@ -65,13 +63,11 @@ EXPORT_SYMBOL(nf_log_register); ...@@ -65,13 +63,11 @@ EXPORT_SYMBOL(nf_log_register);
void nf_log_unregister(struct nf_logger *logger) void nf_log_unregister(struct nf_logger *logger)
{ {
const struct nf_logger *c_logger;
int i; int i;
mutex_lock(&nf_log_mutex); mutex_lock(&nf_log_mutex);
for (i = 0; i < ARRAY_SIZE(nf_loggers); i++) { for (i = 0; i < ARRAY_SIZE(nf_loggers); i++) {
c_logger = rcu_dereference(nf_loggers[i]); if (nf_loggers[i] == logger)
if (c_logger == logger)
rcu_assign_pointer(nf_loggers[i], NULL); rcu_assign_pointer(nf_loggers[i], NULL);
list_del(&logger->list[i]); list_del(&logger->list[i]);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment