aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-04-09 10:42:15 -0400
committerPatrick McHardy <kaber@trash.net>2010-04-09 10:42:15 -0400
commited86308f6179d8fa6151c2d0f652aad0091548e2 (patch)
tree7a85671939266d2f80a03395f4c8af6f15f93948 /net/netfilter
parente9f13cab49f7f28b65a6f63201fca56480b2e059 (diff)
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: Valdis Kletnieks <Valdis.Kletnieks@vt.edu> Tested-by: Valdis Kletnieks <Valdis.Kletnieks@vt.edu> Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/nf_conntrack_ecache.c18
-rw-r--r--net/netfilter/nf_log.c8
2 files changed, 6 insertions, 20 deletions
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index d5a9bcd7d61..849614af232 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -81,11 +81,9 @@ EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
81int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new) 81int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new)
82{ 82{
83 int ret = 0; 83 int ret = 0;
84 struct nf_ct_event_notifier *notify;
85 84
86 mutex_lock(&nf_ct_ecache_mutex); 85 mutex_lock(&nf_ct_ecache_mutex);
87 notify = rcu_dereference(nf_conntrack_event_cb); 86 if (nf_conntrack_event_cb != NULL) {
88 if (notify != NULL) {
89 ret = -EBUSY; 87 ret = -EBUSY;
90 goto out_unlock; 88 goto out_unlock;
91 } 89 }
@@ -101,11 +99,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
101 99
102void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new) 100void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new)
103{ 101{
104 struct nf_ct_event_notifier *notify;
105
106 mutex_lock(&nf_ct_ecache_mutex); 102 mutex_lock(&nf_ct_ecache_mutex);
107 notify = rcu_dereference(nf_conntrack_event_cb); 103 BUG_ON(nf_conntrack_event_cb != new);
108 BUG_ON(notify != new);
109 rcu_assign_pointer(nf_conntrack_event_cb, NULL); 104 rcu_assign_pointer(nf_conntrack_event_cb, NULL);
110 mutex_unlock(&nf_ct_ecache_mutex); 105 mutex_unlock(&nf_ct_ecache_mutex);
111} 106}
@@ -114,11 +109,9 @@ EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
114int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new) 109int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new)
115{ 110{
116 int ret = 0; 111 int ret = 0;
117 struct nf_exp_event_notifier *notify;
118 112
119 mutex_lock(&nf_ct_ecache_mutex); 113 mutex_lock(&nf_ct_ecache_mutex);
120 notify = rcu_dereference(nf_expect_event_cb); 114 if (nf_expect_event_cb != NULL) {
121 if (notify != NULL) {
122 ret = -EBUSY; 115 ret = -EBUSY;
123 goto out_unlock; 116 goto out_unlock;
124 } 117 }
@@ -134,11 +127,8 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier);
134 127
135void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new) 128void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new)
136{ 129{
137 struct nf_exp_event_notifier *notify;
138
139 mutex_lock(&nf_ct_ecache_mutex); 130 mutex_lock(&nf_ct_ecache_mutex);
140 notify = rcu_dereference(nf_expect_event_cb); 131 BUG_ON(nf_expect_event_cb != new);
141 BUG_ON(notify != new);
142 rcu_assign_pointer(nf_expect_event_cb, NULL); 132 rcu_assign_pointer(nf_expect_event_cb, NULL);
143 mutex_unlock(&nf_ct_ecache_mutex); 133 mutex_unlock(&nf_ct_ecache_mutex);
144} 134}
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 015725a5cd5..908f59935fb 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -35,7 +35,6 @@ static struct nf_logger *__find_logger(int pf, const char *str_logger)
35/* return EEXIST if the same logger is registred, 0 on success. */ 35/* return EEXIST if the same logger is registred, 0 on success. */
36int nf_log_register(u_int8_t pf, struct nf_logger *logger) 36int nf_log_register(u_int8_t pf, struct nf_logger *logger)
37{ 37{
38 const struct nf_logger *llog;
39 int i; 38 int i;
40 39
41 if (pf >= ARRAY_SIZE(nf_loggers)) 40 if (pf >= ARRAY_SIZE(nf_loggers))
@@ -52,8 +51,7 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
52 } else { 51 } else {
53 /* register at end of list to honor first register win */ 52 /* register at end of list to honor first register win */
54 list_add_tail(&logger->list[pf], &nf_loggers_l[pf]); 53 list_add_tail(&logger->list[pf], &nf_loggers_l[pf]);
55 llog = rcu_dereference(nf_loggers[pf]); 54 if (nf_loggers[pf] == NULL)
56 if (llog == NULL)
57 rcu_assign_pointer(nf_loggers[pf], logger); 55 rcu_assign_pointer(nf_loggers[pf], logger);
58 } 56 }
59 57
@@ -65,13 +63,11 @@ EXPORT_SYMBOL(nf_log_register);
65 63
66void nf_log_unregister(struct nf_logger *logger) 64void nf_log_unregister(struct nf_logger *logger)
67{ 65{
68 const struct nf_logger *c_logger;
69 int i; 66 int i;
70 67
71 mutex_lock(&nf_log_mutex); 68 mutex_lock(&nf_log_mutex);
72 for (i = 0; i < ARRAY_SIZE(nf_loggers); i++) { 69 for (i = 0; i < ARRAY_SIZE(nf_loggers); i++) {
73 c_logger = rcu_dereference(nf_loggers[i]); 70 if (nf_loggers[i] == logger)
74 if (c_logger == logger)
75 rcu_assign_pointer(nf_loggers[i], NULL); 71 rcu_assign_pointer(nf_loggers[i], NULL);
76 list_del(&logger->list[i]); 72 list_del(&logger->list[i]);
77 } 73 }