diff options
author | Patrick McHardy <kaber@trash.net> | 2010-04-09 10:42:15 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-04-09 10:42:15 -0400 |
commit | ed86308f6179d8fa6151c2d0f652aad0091548e2 (patch) | |
tree | 7a85671939266d2f80a03395f4c8af6f15f93948 /net/netfilter | |
parent | e9f13cab49f7f28b65a6f63201fca56480b2e059 (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.c | 18 | ||||
-rw-r--r-- | net/netfilter/nf_log.c | 8 |
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); | |||
81 | int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new) | 81 | int 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 | ||
102 | void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new) | 100 | void 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); | |||
114 | int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new) | 109 | int 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 | ||
135 | void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new) | 128 | void 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. */ |
36 | int nf_log_register(u_int8_t pf, struct nf_logger *logger) | 36 | int 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 | ||
66 | void nf_log_unregister(struct nf_logger *logger) | 64 | void 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 | } |