netfilter: use actual socket sk for REJECT action
authorJan Engelhardt <jengelh@inai.de>
Sat, 21 Nov 2020 11:11:51 +0000 (12:11 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 1 Dec 2020 13:33:55 +0000 (14:33 +0100)
True to the message of commit v5.10-rc1-105-g46d6c5ae953c, _do_
actually make use of state->sk when possible, such as in the REJECT
modules.

Reported-by: Minqiang Chen <ptpt52@gmail.com>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Jan Engelhardt <jengelh@inai.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/ipv4/nf_reject.h
include/net/netfilter/ipv6/nf_reject.h
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/nf_reject_ipv4.c
net/ipv4/netfilter/nft_reject_ipv4.c
net/ipv6/netfilter/ip6t_REJECT.c
net/ipv6/netfilter/nf_reject_ipv6.c
net/ipv6/netfilter/nft_reject_ipv6.c
net/netfilter/nft_reject_inet.c

index 0d8ff84..c653fcb 100644 (file)
@@ -8,8 +8,8 @@
 #include <net/netfilter/nf_reject.h>
 
 void nf_send_unreach(struct sk_buff *skb_in, int code, int hook);
-void nf_send_reset(struct net *net, struct sk_buff *oldskb, int hook);
-
+void nf_send_reset(struct net *net, struct sock *, struct sk_buff *oldskb,
+                  int hook);
 const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb,
                                             struct tcphdr *_oth, int hook);
 struct iphdr *nf_reject_iphdr_put(struct sk_buff *nskb,
index edcf6d1..d729344 100644 (file)
@@ -7,9 +7,8 @@
 
 void nf_send_unreach6(struct net *net, struct sk_buff *skb_in, unsigned char code,
                      unsigned int hooknum);
-
-void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook);
-
+void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+                   int hook);
 const struct tcphdr *nf_reject_ip6_tcphdr_get(struct sk_buff *oldskb,
                                              struct tcphdr *otcph,
                                              unsigned int *otcplen, int hook);
index e16b98e..4b88407 100644 (file)
@@ -56,7 +56,8 @@ reject_tg(struct sk_buff *skb, const struct xt_action_param *par)
                nf_send_unreach(skb, ICMP_PKT_FILTERED, hook);
                break;
        case IPT_TCP_RESET:
-               nf_send_reset(xt_net(par), skb, hook);
+               nf_send_reset(xt_net(par), par->state->sk, skb, hook);
+               break;
        case IPT_ICMP_ECHOREPLY:
                /* Doesn't happen. */
                break;
index 4109055..4eed5af 100644 (file)
@@ -234,7 +234,8 @@ static int nf_reject_fill_skb_dst(struct sk_buff *skb_in)
 }
 
 /* Send RST reply */
-void nf_send_reset(struct net *net, struct sk_buff *oldskb, int hook)
+void nf_send_reset(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+                  int hook)
 {
        struct net_device *br_indev __maybe_unused;
        struct sk_buff *nskb;
@@ -267,8 +268,7 @@ void nf_send_reset(struct net *net, struct sk_buff *oldskb, int hook)
        niph = nf_reject_iphdr_put(nskb, oldskb, IPPROTO_TCP,
                                   ip4_dst_hoplimit(skb_dst(nskb)));
        nf_reject_ip_tcphdr_put(nskb, oldskb, oth);
-
-       if (ip_route_me_harder(net, nskb->sk, nskb, RTN_UNSPEC))
+       if (ip_route_me_harder(net, sk, nskb, RTN_UNSPEC))
                goto free_nskb;
 
        niph = ip_hdr(nskb);
index e408f81..ff437e4 100644 (file)
@@ -27,7 +27,8 @@ static void nft_reject_ipv4_eval(const struct nft_expr *expr,
                nf_send_unreach(pkt->skb, priv->icmp_code, nft_hook(pkt));
                break;
        case NFT_REJECT_TCP_RST:
-               nf_send_reset(nft_net(pkt), pkt->skb, nft_hook(pkt));
+               nf_send_reset(nft_net(pkt), pkt->xt.state->sk, pkt->skb,
+                             nft_hook(pkt));
                break;
        default:
                break;
index 3ac5485..a35019d 100644 (file)
@@ -61,7 +61,7 @@ reject_tg6(struct sk_buff *skb, const struct xt_action_param *par)
                /* Do nothing */
                break;
        case IP6T_TCP_RESET:
-               nf_send_reset6(net, skb, xt_hooknum(par));
+               nf_send_reset6(net, par->state->sk, skb, xt_hooknum(par));
                break;
        case IP6T_ICMP6_POLICY_FAIL:
                nf_send_unreach6(net, skb, ICMPV6_POLICY_FAIL, xt_hooknum(par));
index aa35e6e..570d1d7 100644 (file)
@@ -275,7 +275,8 @@ static int nf_reject6_fill_skb_dst(struct sk_buff *skb_in)
        return 0;
 }
 
-void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
+void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+                   int hook)
 {
        struct net_device *br_indev __maybe_unused;
        struct sk_buff *nskb;
@@ -367,7 +368,7 @@ void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
                dev_queue_xmit(nskb);
        } else
 #endif
-               ip6_local_out(net, nskb->sk, nskb);
+               ip6_local_out(net, sk, nskb);
 }
 EXPORT_SYMBOL_GPL(nf_send_reset6);
 
index c1098a1..7969d1f 100644 (file)
@@ -28,7 +28,8 @@ static void nft_reject_ipv6_eval(const struct nft_expr *expr,
                                 nft_hook(pkt));
                break;
        case NFT_REJECT_TCP_RST:
-               nf_send_reset6(nft_net(pkt), pkt->skb, nft_hook(pkt));
+               nf_send_reset6(nft_net(pkt), pkt->xt.state->sk, pkt->skb,
+                              nft_hook(pkt));
                break;
        default:
                break;
index 32f3ea3..9509018 100644 (file)
@@ -28,7 +28,8 @@ static void nft_reject_inet_eval(const struct nft_expr *expr,
                                        nft_hook(pkt));
                        break;
                case NFT_REJECT_TCP_RST:
-                       nf_send_reset(nft_net(pkt), pkt->skb, nft_hook(pkt));
+                       nf_send_reset(nft_net(pkt), pkt->xt.state->sk,
+                                     pkt->skb, nft_hook(pkt));
                        break;
                case NFT_REJECT_ICMPX_UNREACH:
                        nf_send_unreach(pkt->skb,
@@ -44,7 +45,8 @@ static void nft_reject_inet_eval(const struct nft_expr *expr,
                                         priv->icmp_code, nft_hook(pkt));
                        break;
                case NFT_REJECT_TCP_RST:
-                       nf_send_reset6(nft_net(pkt), pkt->skb, nft_hook(pkt));
+                       nf_send_reset6(nft_net(pkt), pkt->xt.state->sk,
+                                      pkt->skb, nft_hook(pkt));
                        break;
                case NFT_REJECT_ICMPX_UNREACH:
                        nf_send_unreach6(nft_net(pkt), pkt->skb,