diff options
-rw-r--r-- | net/netfilter/nf_conntrack_expect.c | 15 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_extend.c | 6 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_helper.c | 10 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_proto.c | 4 |
4 files changed, 26 insertions, 9 deletions
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index cab196cf428c..bbb21402596d 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c | |||
@@ -337,7 +337,10 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp) | |||
337 | setup_timer(&exp->timeout, nf_ct_expectation_timed_out, | 337 | setup_timer(&exp->timeout, nf_ct_expectation_timed_out, |
338 | (unsigned long)exp); | 338 | (unsigned long)exp); |
339 | if (master_help) { | 339 | if (master_help) { |
340 | p = &master_help->helper->expect_policy[exp->class]; | 340 | p = &rcu_dereference_protected( |
341 | master_help->helper, | ||
342 | lockdep_is_held(&nf_conntrack_lock) | ||
343 | )->expect_policy[exp->class]; | ||
341 | exp->timeout.expires = jiffies + p->timeout * HZ; | 344 | exp->timeout.expires = jiffies + p->timeout * HZ; |
342 | } | 345 | } |
343 | add_timer(&exp->timeout); | 346 | add_timer(&exp->timeout); |
@@ -373,7 +376,10 @@ static inline int refresh_timer(struct nf_conntrack_expect *i) | |||
373 | if (!del_timer(&i->timeout)) | 376 | if (!del_timer(&i->timeout)) |
374 | return 0; | 377 | return 0; |
375 | 378 | ||
376 | p = &master_help->helper->expect_policy[i->class]; | 379 | p = &rcu_dereference_protected( |
380 | master_help->helper, | ||
381 | lockdep_is_held(&nf_conntrack_lock) | ||
382 | )->expect_policy[i->class]; | ||
377 | i->timeout.expires = jiffies + p->timeout * HZ; | 383 | i->timeout.expires = jiffies + p->timeout * HZ; |
378 | add_timer(&i->timeout); | 384 | add_timer(&i->timeout); |
379 | return 1; | 385 | return 1; |
@@ -411,7 +417,10 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) | |||
411 | } | 417 | } |
412 | /* Will be over limit? */ | 418 | /* Will be over limit? */ |
413 | if (master_help) { | 419 | if (master_help) { |
414 | p = &master_help->helper->expect_policy[expect->class]; | 420 | p = &rcu_dereference_protected( |
421 | master_help->helper, | ||
422 | lockdep_is_held(&nf_conntrack_lock) | ||
423 | )->expect_policy[expect->class]; | ||
415 | if (p->max_expected && | 424 | if (p->max_expected && |
416 | master_help->expecting[expect->class] >= p->max_expected) { | 425 | master_help->expecting[expect->class] >= p->max_expected) { |
417 | evict_oldest_expect(master, expect); | 426 | evict_oldest_expect(master, expect); |
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index 920f9244388b..80a23ed62bb0 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c | |||
@@ -140,14 +140,16 @@ static void update_alloc_size(struct nf_ct_ext_type *type) | |||
140 | /* This assumes that extended areas in conntrack for the types | 140 | /* This assumes that extended areas in conntrack for the types |
141 | whose NF_CT_EXT_F_PREALLOC bit set are allocated in order */ | 141 | whose NF_CT_EXT_F_PREALLOC bit set are allocated in order */ |
142 | for (i = min; i <= max; i++) { | 142 | for (i = min; i <= max; i++) { |
143 | t1 = nf_ct_ext_types[i]; | 143 | t1 = rcu_dereference_protected(nf_ct_ext_types[i], |
144 | lockdep_is_held(&nf_ct_ext_type_mutex)); | ||
144 | if (!t1) | 145 | if (!t1) |
145 | continue; | 146 | continue; |
146 | 147 | ||
147 | t1->alloc_size = ALIGN(sizeof(struct nf_ct_ext), t1->align) + | 148 | t1->alloc_size = ALIGN(sizeof(struct nf_ct_ext), t1->align) + |
148 | t1->len; | 149 | t1->len; |
149 | for (j = 0; j < NF_CT_EXT_NUM; j++) { | 150 | for (j = 0; j < NF_CT_EXT_NUM; j++) { |
150 | t2 = nf_ct_ext_types[j]; | 151 | t2 = rcu_dereference_protected(nf_ct_ext_types[j], |
152 | lockdep_is_held(&nf_ct_ext_type_mutex)); | ||
151 | if (t2 == NULL || t2 == t1 || | 153 | if (t2 == NULL || t2 == t1 || |
152 | (t2->flags & NF_CT_EXT_F_PREALLOC) == 0) | 154 | (t2->flags & NF_CT_EXT_F_PREALLOC) == 0) |
153 | continue; | 155 | continue; |
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 59e1a4cd4e8b..767bbe98a0f0 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c | |||
@@ -158,7 +158,10 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i, | |||
158 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(i); | 158 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(i); |
159 | struct nf_conn_help *help = nfct_help(ct); | 159 | struct nf_conn_help *help = nfct_help(ct); |
160 | 160 | ||
161 | if (help && help->helper == me) { | 161 | if (help && rcu_dereference_protected( |
162 | help->helper, | ||
163 | lockdep_is_held(&nf_conntrack_lock) | ||
164 | ) == me) { | ||
162 | nf_conntrack_event(IPCT_HELPER, ct); | 165 | nf_conntrack_event(IPCT_HELPER, ct); |
163 | rcu_assign_pointer(help->helper, NULL); | 166 | rcu_assign_pointer(help->helper, NULL); |
164 | } | 167 | } |
@@ -210,7 +213,10 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me, | |||
210 | hlist_for_each_entry_safe(exp, n, next, | 213 | hlist_for_each_entry_safe(exp, n, next, |
211 | &net->ct.expect_hash[i], hnode) { | 214 | &net->ct.expect_hash[i], hnode) { |
212 | struct nf_conn_help *help = nfct_help(exp->master); | 215 | struct nf_conn_help *help = nfct_help(exp->master); |
213 | if ((help->helper == me || exp->helper == me) && | 216 | if ((rcu_dereference_protected( |
217 | help->helper, | ||
218 | lockdep_is_held(&nf_conntrack_lock) | ||
219 | ) == me || exp->helper == me) && | ||
214 | del_timer(&exp->timeout)) { | 220 | del_timer(&exp->timeout)) { |
215 | nf_ct_unlink_expect(exp); | 221 | nf_ct_unlink_expect(exp); |
216 | nf_ct_expect_put(exp); | 222 | nf_ct_expect_put(exp); |
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 03b56a0fff30..5701c8dd783c 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c | |||
@@ -284,7 +284,7 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) | |||
284 | mutex_lock(&nf_ct_proto_mutex); | 284 | mutex_lock(&nf_ct_proto_mutex); |
285 | if (!nf_ct_protos[l4proto->l3proto]) { | 285 | if (!nf_ct_protos[l4proto->l3proto]) { |
286 | /* l3proto may be loaded latter. */ | 286 | /* l3proto may be loaded latter. */ |
287 | struct nf_conntrack_l4proto **proto_array; | 287 | struct nf_conntrack_l4proto __rcu **proto_array; |
288 | int i; | 288 | int i; |
289 | 289 | ||
290 | proto_array = kmalloc(MAX_NF_CT_PROTO * | 290 | proto_array = kmalloc(MAX_NF_CT_PROTO * |
@@ -296,7 +296,7 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) | |||
296 | } | 296 | } |
297 | 297 | ||
298 | for (i = 0; i < MAX_NF_CT_PROTO; i++) | 298 | for (i = 0; i < MAX_NF_CT_PROTO; i++) |
299 | proto_array[i] = &nf_conntrack_l4proto_generic; | 299 | RCU_INIT_POINTER(proto_array[i], &nf_conntrack_l4proto_generic); |
300 | 300 | ||
301 | /* Before making proto_array visible to lockless readers, | 301 | /* Before making proto_array visible to lockless readers, |
302 | * we must make sure its content is committed to memory. | 302 | * we must make sure its content is committed to memory. |