aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/netfilter/nf_conntrack_expect.c15
-rw-r--r--net/netfilter/nf_conntrack_extend.c6
-rw-r--r--net/netfilter/nf_conntrack_helper.c10
-rw-r--r--net/netfilter/nf_conntrack_proto.c4
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.