diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index dc442fb791b0..1b1797f1f33d 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -160,6 +160,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
160 | { | 160 | { |
161 | struct nf_conn *ct; | 161 | struct nf_conn *ct; |
162 | struct nf_conn_help *help; | 162 | struct nf_conn_help *help; |
163 | struct nf_conntrack_helper *helper; | ||
163 | enum ip_conntrack_info ctinfo; | 164 | enum ip_conntrack_info ctinfo; |
164 | unsigned int ret, protoff; | 165 | unsigned int ret, protoff; |
165 | unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; | 166 | unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; |
@@ -172,7 +173,11 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
172 | goto out; | 173 | goto out; |
173 | 174 | ||
174 | help = nfct_help(ct); | 175 | help = nfct_help(ct); |
175 | if (!help || !help->helper) | 176 | if (!help) |
177 | goto out; | ||
178 | /* rcu_read_lock()ed by nf_hook_slow */ | ||
179 | helper = rcu_dereference(help->helper); | ||
180 | if (!helper) | ||
176 | goto out; | 181 | goto out; |
177 | 182 | ||
178 | protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, | 183 | protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, |
@@ -182,7 +187,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
182 | return NF_ACCEPT; | 187 | return NF_ACCEPT; |
183 | } | 188 | } |
184 | 189 | ||
185 | ret = help->helper->help(pskb, protoff, ct, ctinfo); | 190 | ret = helper->help(pskb, protoff, ct, ctinfo); |
186 | if (ret != NF_ACCEPT) | 191 | if (ret != NF_ACCEPT) |
187 | return ret; | 192 | return ret; |
188 | out: | 193 | out: |