]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.17-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 May 2022 23:23:56 +0000 (01:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 May 2022 23:23:56 +0000 (01:23 +0200)
added patches:
netfilter-nft_socket-only-do-sk-lookups-when-indev-is-available.patch

queue-5.17/netfilter-nft_socket-only-do-sk-lookups-when-indev-is-available.patch [new file with mode: 0644]
queue-5.17/series

diff --git a/queue-5.17/netfilter-nft_socket-only-do-sk-lookups-when-indev-is-available.patch b/queue-5.17/netfilter-nft_socket-only-do-sk-lookups-when-indev-is-available.patch
new file mode 100644 (file)
index 0000000..39ae813
--- /dev/null
@@ -0,0 +1,110 @@
+From 743b83f15d4069ea57c3e40996bf4a1077e0cdc1 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Thu, 28 Apr 2022 09:39:21 +0200
+Subject: netfilter: nft_socket: only do sk lookups when indev is available
+
+From: Florian Westphal <fw@strlen.de>
+
+commit 743b83f15d4069ea57c3e40996bf4a1077e0cdc1 upstream.
+
+Check if the incoming interface is available and NFT_BREAK
+in case neither skb->sk nor input device are set.
+
+Because nf_sk_lookup_slow*() assume packet headers are in the
+'in' direction, use in postrouting is not going to yield a meaningful
+result.  Same is true for the forward chain, so restrict the use
+to prerouting, input and output.
+
+Use in output work if a socket is already attached to the skb.
+
+Fixes: 554ced0a6e29 ("netfilter: nf_tables: add support for native socket matching")
+Reported-and-tested-by: Topi Miettinen <toiwoton@gmail.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/nft_socket.c |   52 ++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 38 insertions(+), 14 deletions(-)
+
+--- a/net/netfilter/nft_socket.c
++++ b/net/netfilter/nft_socket.c
+@@ -53,6 +53,32 @@ nft_sock_get_eval_cgroupv2(u32 *dest, st
+ }
+ #endif
++static struct sock *nft_socket_do_lookup(const struct nft_pktinfo *pkt)
++{
++      const struct net_device *indev = nft_in(pkt);
++      const struct sk_buff *skb = pkt->skb;
++      struct sock *sk = NULL;
++
++      if (!indev)
++              return NULL;
++
++      switch (nft_pf(pkt)) {
++      case NFPROTO_IPV4:
++              sk = nf_sk_lookup_slow_v4(nft_net(pkt), skb, indev);
++              break;
++#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
++      case NFPROTO_IPV6:
++              sk = nf_sk_lookup_slow_v6(nft_net(pkt), skb, indev);
++              break;
++#endif
++      default:
++              WARN_ON_ONCE(1);
++              break;
++      }
++
++      return sk;
++}
++
+ static void nft_socket_eval(const struct nft_expr *expr,
+                           struct nft_regs *regs,
+                           const struct nft_pktinfo *pkt)
+@@ -66,20 +92,7 @@ static void nft_socket_eval(const struct
+               sk = NULL;
+       if (!sk)
+-              switch(nft_pf(pkt)) {
+-              case NFPROTO_IPV4:
+-                      sk = nf_sk_lookup_slow_v4(nft_net(pkt), skb, nft_in(pkt));
+-                      break;
+-#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
+-              case NFPROTO_IPV6:
+-                      sk = nf_sk_lookup_slow_v6(nft_net(pkt), skb, nft_in(pkt));
+-                      break;
+-#endif
+-              default:
+-                      WARN_ON_ONCE(1);
+-                      regs->verdict.code = NFT_BREAK;
+-                      return;
+-              }
++              sk = nft_socket_do_lookup(pkt);
+       if (!sk) {
+               regs->verdict.code = NFT_BREAK;
+@@ -197,6 +210,16 @@ static int nft_socket_dump(struct sk_buf
+       return 0;
+ }
++static int nft_socket_validate(const struct nft_ctx *ctx,
++                             const struct nft_expr *expr,
++                             const struct nft_data **data)
++{
++      return nft_chain_validate_hooks(ctx->chain,
++                                      (1 << NF_INET_PRE_ROUTING) |
++                                      (1 << NF_INET_LOCAL_IN) |
++                                      (1 << NF_INET_LOCAL_OUT));
++}
++
+ static struct nft_expr_type nft_socket_type;
+ static const struct nft_expr_ops nft_socket_ops = {
+       .type           = &nft_socket_type,
+@@ -204,6 +227,7 @@ static const struct nft_expr_ops nft_soc
+       .eval           = nft_socket_eval,
+       .init           = nft_socket_init,
+       .dump           = nft_socket_dump,
++      .validate       = nft_socket_validate,
+ };
+ static struct nft_expr_type nft_socket_type __read_mostly = {
index 58f22931d23b4d51b3cdd6ddce5d0c0be95bc79d..b9fa15710f06e39c68b1f4710d561825020d2eae 100644 (file)
@@ -205,3 +205,4 @@ tty-n_gsm-fix-mux-cleanup-after-unregister-tty-device.patch
 tty-n_gsm-fix-wrong-signal-octet-encoding-in-convergence-layer-type-2.patch
 tty-n_gsm-fix-frame-reception-handling.patch
 tty-n_gsm-fix-malformed-counter-for-out-of-frame-data.patch
+netfilter-nft_socket-only-do-sk-lookups-when-indev-is-available.patch