diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-03-22 18:58:41 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-03-22 19:52:07 -0400 |
commit | 1ac0bf99260761ad0a536ddbc15f6f9b82b9bab3 (patch) | |
tree | d343d753dd84c0be8742466e811835474ab87a83 /net | |
parent | c1ebd7dff700277e4d0a3da36833a406142e31d4 (diff) |
netfilter: xt_CT: missing rcu_read_lock section in timeout assignment
Fix a dereference to pointer without rcu_read_lock held.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/xt_CT.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 80c39f0f6e91..33a02b41abb4 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c | |||
@@ -218,6 +218,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) | |||
218 | struct ctnl_timeout *timeout; | 218 | struct ctnl_timeout *timeout; |
219 | struct nf_conn_timeout *timeout_ext; | 219 | struct nf_conn_timeout *timeout_ext; |
220 | 220 | ||
221 | rcu_read_lock(); | ||
221 | timeout_find_get = | 222 | timeout_find_get = |
222 | rcu_dereference(nf_ct_timeout_find_get_hook); | 223 | rcu_dereference(nf_ct_timeout_find_get_hook); |
223 | 224 | ||
@@ -228,21 +229,21 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) | |||
228 | ret = -EINVAL; | 229 | ret = -EINVAL; |
229 | pr_info("You cannot use inversion on " | 230 | pr_info("You cannot use inversion on " |
230 | "L4 protocol\n"); | 231 | "L4 protocol\n"); |
231 | goto err3; | 232 | goto err4; |
232 | } | 233 | } |
233 | timeout = timeout_find_get(info->timeout); | 234 | timeout = timeout_find_get(info->timeout); |
234 | if (timeout == NULL) { | 235 | if (timeout == NULL) { |
235 | ret = -ENOENT; | 236 | ret = -ENOENT; |
236 | pr_info("No such timeout policy \"%s\"\n", | 237 | pr_info("No such timeout policy \"%s\"\n", |
237 | info->timeout); | 238 | info->timeout); |
238 | goto err3; | 239 | goto err4; |
239 | } | 240 | } |
240 | if (timeout->l3num != par->family) { | 241 | if (timeout->l3num != par->family) { |
241 | ret = -EINVAL; | 242 | ret = -EINVAL; |
242 | pr_info("Timeout policy `%s' can only be " | 243 | pr_info("Timeout policy `%s' can only be " |
243 | "used by L3 protocol number %d\n", | 244 | "used by L3 protocol number %d\n", |
244 | info->timeout, timeout->l3num); | 245 | info->timeout, timeout->l3num); |
245 | goto err3; | 246 | goto err4; |
246 | } | 247 | } |
247 | if (timeout->l4proto->l4proto != e->ip.proto) { | 248 | if (timeout->l4proto->l4proto != e->ip.proto) { |
248 | ret = -EINVAL; | 249 | ret = -EINVAL; |
@@ -250,19 +251,20 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) | |||
250 | "used by L4 protocol number %d\n", | 251 | "used by L4 protocol number %d\n", |
251 | info->timeout, | 252 | info->timeout, |
252 | timeout->l4proto->l4proto); | 253 | timeout->l4proto->l4proto); |
253 | goto err3; | 254 | goto err4; |
254 | } | 255 | } |
255 | timeout_ext = nf_ct_timeout_ext_add(ct, timeout, | 256 | timeout_ext = nf_ct_timeout_ext_add(ct, timeout, |
256 | GFP_KERNEL); | 257 | GFP_KERNEL); |
257 | if (timeout_ext == NULL) { | 258 | if (timeout_ext == NULL) { |
258 | ret = -ENOMEM; | 259 | ret = -ENOMEM; |
259 | goto err3; | 260 | goto err4; |
260 | } | 261 | } |
261 | } else { | 262 | } else { |
262 | ret = -ENOENT; | 263 | ret = -ENOENT; |
263 | pr_info("Timeout policy base is empty\n"); | 264 | pr_info("Timeout policy base is empty\n"); |
264 | goto err3; | 265 | goto err4; |
265 | } | 266 | } |
267 | rcu_read_unlock(); | ||
266 | } | 268 | } |
267 | #endif | 269 | #endif |
268 | 270 | ||
@@ -272,6 +274,8 @@ out: | |||
272 | info->ct = ct; | 274 | info->ct = ct; |
273 | return 0; | 275 | return 0; |
274 | 276 | ||
277 | err4: | ||
278 | rcu_read_unlock(); | ||
275 | err3: | 279 | err3: |
276 | nf_conntrack_free(ct); | 280 | nf_conntrack_free(ct); |
277 | err2: | 281 | err2: |
@@ -313,6 +317,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par) | |||
313 | nf_ct_l3proto_module_put(par->family); | 317 | nf_ct_l3proto_module_put(par->family); |
314 | 318 | ||
315 | #ifdef CONFIG_NF_CONNTRACK_TIMEOUT | 319 | #ifdef CONFIG_NF_CONNTRACK_TIMEOUT |
320 | rcu_read_lock(); | ||
316 | timeout_put = rcu_dereference(nf_ct_timeout_put_hook); | 321 | timeout_put = rcu_dereference(nf_ct_timeout_put_hook); |
317 | 322 | ||
318 | if (timeout_put) { | 323 | if (timeout_put) { |
@@ -320,6 +325,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par) | |||
320 | if (timeout_ext) | 325 | if (timeout_ext) |
321 | timeout_put(timeout_ext->timeout); | 326 | timeout_put(timeout_ext->timeout); |
322 | } | 327 | } |
328 | rcu_read_unlock(); | ||
323 | #endif | 329 | #endif |
324 | } | 330 | } |
325 | nf_ct_put(info->ct); | 331 | nf_ct_put(info->ct); |