]> Git Repo - linux.git/commitdiff
netfilter: keep conntrack reference until IPsecv6 policy checks are done
authorMadhu Koriginja <[email protected]>
Tue, 21 Mar 2023 15:58:44 +0000 (21:28 +0530)
committerFlorian Westphal <[email protected]>
Wed, 22 Mar 2023 20:50:23 +0000 (21:50 +0100)
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: 58a317f1061c ("netfilter: ipv6: add IPv6 NAT support")
Signed-off-by: Madhu Koriginja <[email protected]>
Signed-off-by: Florian Westphal <[email protected]>
net/dccp/ipv6.c
net/ipv6/ip6_input.c
net/ipv6/raw.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c

index 47fb108342239a0d26de913021ed489216bf5093..93c98990d72632e18ae50c046b9fdc9e096f66de 100644 (file)
@@ -784,6 +784,7 @@ lookup:
 
        if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
                goto discard_and_relse;
+       nf_reset_ct(skb);
 
        return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4,
                                refcounted) ? -1 : 0;
index e1ebf5e42ebe9ac39c13f109b03853c557ff2718..d94041bb42872f02eaaa5bd2f64ae2301a8a48a4 100644 (file)
@@ -404,10 +404,6 @@ resubmit_final:
                        /* Only do this once for first final protocol */
                        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_network_header_len(skb));
@@ -430,10 +426,12 @@ resubmit_final:
                                goto discard;
                        }
                }
-               if (!(ipprot->flags & INET6_PROTO_NOPOLICY) &&
-                   !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
-                       SKB_DR_SET(reason, XFRM_POLICY);
-                       goto discard;
+               if (!(ipprot->flags & INET6_PROTO_NOPOLICY)) {
+                       if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+                               SKB_DR_SET(reason, XFRM_POLICY);
+                               goto discard;
+                       }
+                       nf_reset_ct(skb);
                }
 
                ret = INDIRECT_CALL_2(ipprot->handler, tcp_v6_rcv, udpv6_rcv,
index 6ac2f2690c44c96e9ac4cb7368ee7abdbeaf4334..4ab62a9c5c8e6b2a3322f19c5d4365afe85f74b4 100644 (file)
@@ -194,10 +194,8 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
                        struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
 
                        /* Not releasing hash table! */
-                       if (clone) {
-                               nf_reset_ct(clone);
+                       if (clone)
                                rawv6_rcv(sk, clone);
-                       }
                }
        }
        rcu_read_unlock();
@@ -391,6 +389,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
                kfree_skb_reason(skb, SKB_DROP_REASON_XFRM_POLICY);
                return NET_RX_DROP;
        }
+       nf_reset_ct(skb);
 
        if (!rp->checksum)
                skb->ip_summed = CHECKSUM_UNNECESSARY;
index 35cf523c9efd4370bf3110f6777592eabb15ca9e..244cf86c4cbb6e5e4d4fb92b112a8f6b2da7ec5a 100644 (file)
@@ -1723,6 +1723,8 @@ process:
        if (drop_reason)
                goto discard_and_relse;
 
+       nf_reset_ct(skb);
+
        if (tcp_filter(sk, skb)) {
                drop_reason = SKB_DROP_REASON_SOCKET_FILTER;
                goto discard_and_relse;
index d350e57c479299e732bd3595c1964acddde2d876..4caa70a1b871f0055e49859fd3d5ac7fde989ded 100644 (file)
@@ -704,6 +704,7 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
                drop_reason = SKB_DROP_REASON_XFRM_POLICY;
                goto drop;
        }
+       nf_reset_ct(skb);
 
        if (static_branch_unlikely(&udpv6_encap_needed_key) && up->encap_type) {
                int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
@@ -1027,6 +1028,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 
        if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
                goto discard;
+       nf_reset_ct(skb);
 
        if (udp_lib_checksum_complete(skb))
                goto csum_error;
This page took 0.066893 seconds and 4 git commands to generate.