netfilter: keep conntrack reference until IPsecv6 policy checks are done
[ Upstream commit b0e214d212030fe497d4d150bb3474e50ad5d093 ]
Keep the conntrack reference until policy checks have been performed for
IPsec V6 NAT support, just like ipv4.
The reference needs to be dropped before a packet is
queued to avoid having the conntrack module unloadable.
Fixes: 58a317f106
("netfilter: ipv6: add IPv6 NAT support")
Signed-off-by: Madhu Koriginja <madhu.koriginja@nxp.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
8d05f25475
commit
2361aee1c5
@ -783,6 +783,7 @@ static int dccp_v6_rcv(struct sk_buff *skb)
|
|||||||
|
|
||||||
if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
|
if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
|
||||||
goto discard_and_relse;
|
goto discard_and_relse;
|
||||||
|
nf_reset_ct(skb);
|
||||||
|
|
||||||
return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4,
|
return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4,
|
||||||
refcounted) ? -1 : 0;
|
refcounted) ? -1 : 0;
|
||||||
|
@ -404,10 +404,6 @@ void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
|
|||||||
/* Only do this once for first final protocol */
|
/* Only do this once for first final protocol */
|
||||||
have_final = true;
|
have_final = true;
|
||||||
|
|
||||||
/* Free reference early: we don't need it any more,
|
|
||||||
and it may hold ip_conntrack module loaded
|
|
||||||
indefinitely. */
|
|
||||||
nf_reset_ct(skb);
|
|
||||||
|
|
||||||
skb_postpull_rcsum(skb, skb_network_header(skb),
|
skb_postpull_rcsum(skb, skb_network_header(skb),
|
||||||
skb_network_header_len(skb));
|
skb_network_header_len(skb));
|
||||||
@ -430,10 +426,12 @@ void ip6_protocol_deliver_rcu(struct net *net, struct sk_buff *skb, int nexthdr,
|
|||||||
goto discard;
|
goto discard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
|
if (!(ipprot->flags & INET6_PROTO_NOPOLICY)) {
|
||||||
!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
|
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
|
||||||
SKB_DR_SET(reason, XFRM_POLICY);
|
SKB_DR_SET(reason, XFRM_POLICY);
|
||||||
goto discard;
|
goto discard;
|
||||||
|
}
|
||||||
|
nf_reset_ct(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = INDIRECT_CALL_2(ipprot->handler, tcp_v6_rcv, udpv6_rcv,
|
ret = INDIRECT_CALL_2(ipprot->handler, tcp_v6_rcv, udpv6_rcv,
|
||||||
|
@ -193,10 +193,8 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
|
|||||||
struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
|
struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
|
||||||
|
|
||||||
/* Not releasing hash table! */
|
/* Not releasing hash table! */
|
||||||
if (clone) {
|
if (clone)
|
||||||
nf_reset_ct(clone);
|
|
||||||
rawv6_rcv(sk, clone);
|
rawv6_rcv(sk, clone);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
@ -387,6 +385,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
|
|||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return NET_RX_DROP;
|
return NET_RX_DROP;
|
||||||
}
|
}
|
||||||
|
nf_reset_ct(skb);
|
||||||
|
|
||||||
if (!rp->checksum)
|
if (!rp->checksum)
|
||||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||||
|
@ -1722,6 +1722,8 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
|
|||||||
if (drop_reason)
|
if (drop_reason)
|
||||||
goto discard_and_relse;
|
goto discard_and_relse;
|
||||||
|
|
||||||
|
nf_reset_ct(skb);
|
||||||
|
|
||||||
if (tcp_filter(sk, skb)) {
|
if (tcp_filter(sk, skb)) {
|
||||||
drop_reason = SKB_DROP_REASON_SOCKET_FILTER;
|
drop_reason = SKB_DROP_REASON_SOCKET_FILTER;
|
||||||
goto discard_and_relse;
|
goto discard_and_relse;
|
||||||
|
@ -701,6 +701,7 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
|
|||||||
drop_reason = SKB_DROP_REASON_XFRM_POLICY;
|
drop_reason = SKB_DROP_REASON_XFRM_POLICY;
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
nf_reset_ct(skb);
|
||||||
|
|
||||||
if (static_branch_unlikely(&udpv6_encap_needed_key) && up->encap_type) {
|
if (static_branch_unlikely(&udpv6_encap_needed_key) && up->encap_type) {
|
||||||
int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
|
int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
|
||||||
@ -1024,6 +1025,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
|
|||||||
|
|
||||||
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
|
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
|
||||||
goto discard;
|
goto discard;
|
||||||
|
nf_reset_ct(skb);
|
||||||
|
|
||||||
if (udp_lib_checksum_complete(skb))
|
if (udp_lib_checksum_complete(skb))
|
||||||
goto csum_error;
|
goto csum_error;
|
||||||
|
Loading…
Reference in New Issue
Block a user