]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Jul 2026 13:56:14 +0000 (15:56 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Jul 2026 13:56:14 +0000 (15:56 +0200)
added patches:
netfilter-ebtables-module-names-must-be-null-terminated.patch
netfilter-ebtables-terminate-table-name-before-find_table_lock.patch
netfilter-handle-unreadable-frags.patch

queue-6.12/netfilter-ebtables-module-names-must-be-null-terminated.patch [new file with mode: 0644]
queue-6.12/netfilter-ebtables-terminate-table-name-before-find_table_lock.patch [new file with mode: 0644]
queue-6.12/netfilter-handle-unreadable-frags.patch [new file with mode: 0644]
queue-6.12/series

diff --git a/queue-6.12/netfilter-ebtables-module-names-must-be-null-terminated.patch b/queue-6.12/netfilter-ebtables-module-names-must-be-null-terminated.patch
new file mode 100644 (file)
index 0000000..f1d6053
--- /dev/null
@@ -0,0 +1,32 @@
+From 084d23f818321390509e9738a0b08bbf46df6425 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Sat, 4 Jul 2026 12:05:15 +0200
+Subject: netfilter: ebtables: module names must be null-terminated
+
+From: Florian Westphal <fw@strlen.de>
+
+commit 084d23f818321390509e9738a0b08bbf46df6425 upstream.
+
+We need to explicitly check the length, else we may pass non-null
+terminated string to request_module().
+
+Cc: stable@vger.kernel.org
+Fixes: bcf493428840 ("netfilter: ebtables: Fix extension lookup with identical name")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/netfilter/ebtables.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -402,6 +402,9 @@ ebt_check_match(struct ebt_entry_match *
+           left - sizeof(struct ebt_entry_match) < m->match_size)
+               return -EINVAL;
++      if (strnlen(m->u.name, XT_EXTENSION_MAXNAMELEN) == XT_EXTENSION_MAXNAMELEN)
++              return -EINVAL;
++
+       match = xt_find_match(NFPROTO_BRIDGE, m->u.name, m->u.revision);
+       if (IS_ERR(match) || match->family != NFPROTO_BRIDGE) {
+               if (!IS_ERR(match))
diff --git a/queue-6.12/netfilter-ebtables-terminate-table-name-before-find_table_lock.patch b/queue-6.12/netfilter-ebtables-terminate-table-name-before-find_table_lock.patch
new file mode 100644 (file)
index 0000000..7de9358
--- /dev/null
@@ -0,0 +1,77 @@
+From a622d2e9608c9dff47fc2e5759ac7aa3a836b45d Mon Sep 17 00:00:00 2001
+From: Xiang Mei <xmei5@asu.edu>
+Date: Sun, 5 Jul 2026 14:58:00 -0700
+Subject: netfilter: ebtables: terminate table name before find_table_lock()
+
+From: Xiang Mei <xmei5@asu.edu>
+
+commit a622d2e9608c9dff47fc2e5759ac7aa3a836b45d upstream.
+
+update_counters() and compat_update_counters() forward a user-supplied
+32-byte table name to find_table_lock() without NUL-terminating it. On a
+lookup miss, find_inlist_lock() calls try_then_request_module(..., "%s%s",
+"ebtable_", name), and vsnprintf() reads past the name field and the
+stack object until it hits a zero byte.
+
+  BUG: KASAN: stack-out-of-bounds in string (lib/vsprintf.c:648 lib/vsprintf.c:730)
+  Read of size 1 at addr ffff8880119dfb20 by task exploit/147
+  Call Trace:
+  ...
+   string (lib/vsprintf.c:648 lib/vsprintf.c:730)
+   vsnprintf (lib/vsprintf.c:2945)
+   __request_module (kernel/module/kmod.c:150)
+   do_update_counters.isra.0 (net/bridge/netfilter/ebtables.c:371 net/bridge/netfilter/ebtables.c:380)
+   update_counters (net/bridge/netfilter/ebtables.c:1440)
+   do_ebt_set_ctl (net/bridge/netfilter/ebtables.c:2573)
+   nf_setsockopt (net/netfilter/nf_sockopt.c:101)
+   ip_setsockopt (net/ipv4/ip_sockglue.c:1424)
+   raw_setsockopt (net/ipv4/raw.c:847)
+   __sys_setsockopt (net/socket.c:2393)
+  ...
+
+compat_do_replace() shares the same unterminated name via
+compat_copy_ebt_replace_from_user(); terminate it there too so all
+find_table_lock() callers behave alike. The other callers already
+terminate the name after the copy.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Fixes: 81e675c227ec ("netfilter: ebtables: add CONFIG_COMPAT support")
+Cc: stable@vger.kernel.org
+Reported-by: Weiming Shi <bestswngs@gmail.com>
+Assisted-by: Claude:claude-opus-4-8
+Signed-off-by: Xiang Mei <xmei5@asu.edu>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/netfilter/ebtables.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1433,6 +1433,8 @@ static int update_counters(struct net *n
+       if (copy_from_sockptr(&hlp, arg, sizeof(hlp)))
+               return -EFAULT;
++      hlp.name[sizeof(hlp.name) - 1] = '\0';
++
+       if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
+               return -EINVAL;
+@@ -2272,6 +2274,8 @@ static int compat_copy_ebt_replace_from_
+       memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry));
++      repl->name[sizeof(repl->name) - 1] = '\0';
++
+       /* starting with hook_entry, 32 vs. 64 bit structures are different */
+       for (i = 0; i < NF_BR_NUMHOOKS; i++)
+               repl->hook_entry[i] = compat_ptr(tmp.hook_entry[i]);
+@@ -2394,6 +2398,8 @@ static int compat_update_counters(struct
+       if (copy_from_sockptr(&hlp, arg, sizeof(hlp)))
+               return -EFAULT;
++      hlp.name[sizeof(hlp.name) - 1] = '\0';
++
+       /* try real handler in case userland supplied needed padding */
+       if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter))
+               return update_counters(net, arg, len);
diff --git a/queue-6.12/netfilter-handle-unreadable-frags.patch b/queue-6.12/netfilter-handle-unreadable-frags.patch
new file mode 100644 (file)
index 0000000..6daf64a
--- /dev/null
@@ -0,0 +1,176 @@
+From da5b58478a9c1b85608c9e40a3b8432d071b409e Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Sun, 5 Jul 2026 15:29:13 +0200
+Subject: netfilter: handle unreadable frags
+
+From: Florian Westphal <fw@strlen.de>
+
+commit da5b58478a9c1b85608c9e40a3b8432d071b409e upstream.
+
+sashiko reports:
+ When an skb with unreadable fragments (such as from devmem TCP, where
+ skb_frags_readable(skb) returns false) is processed by the u32 module,
+ skb_copy_bits() will safely return a negative error code [..]
+
+xt_u32: bail out with hotdrop in this case.
+gather_frags: return -1, just as if we had no fragment header.
+nfnetlink_queue: restrict to the linear part.
+nfnetlink_log: restrict to the linear part.
+
+v2:
+ - skb_zerocopy helpers don't copy readable flag, i.e. nfnetlink_queue
+ is broken too
+ xt_u32 shouldn't return true if hotdrop was set.
+
+Fixes: 65249feb6b3d ("net: add support for skbs with unreadable frags")
+Cc: stable@vger.kernel.org
+Acked-by: Mina Almasry <almasrymina@google.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/netfilter/nf_conntrack_reasm.c |    2 +-
+ net/netfilter/nfnetlink_log.c           |   26 +++++++++++++++++---------
+ net/netfilter/nfnetlink_queue.c         |   16 ++++++++++++----
+ net/netfilter/xt_u32.c                  |   16 +++++++++++-----
+ 4 files changed, 41 insertions(+), 19 deletions(-)
+
+--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
+@@ -415,7 +415,7 @@ find_prev_fhdr(struct sk_buff *skb, u8 *
+                       return -1;
+               }
+               if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
+-                      BUG();
++                      return -1;
+               if (nexthdr == NEXTHDR_AUTH)
+                       hdrlen = ipv6_authlen(&hdr);
+               else
+--- a/net/netfilter/nfnetlink_log.c
++++ b/net/netfilter/nfnetlink_log.c
+@@ -668,7 +668,7 @@ __build_packet_message(struct nfnl_log_n
+                       goto nla_put_failure;
+               if (skb_copy_bits(skb, 0, nla_data(nla), data_len))
+-                      BUG();
++                      goto nla_put_failure;
+       }
+       nlh->nlmsg_len = inst->skb->tail - old_tail;
+@@ -690,6 +690,21 @@ static const struct nf_loginfo default_l
+       },
+ };
++static unsigned int nfulnl_get_copy_len(const struct nf_loginfo *li,
++                                      const struct sk_buff *skb,
++                                      unsigned int copy_len)
++{
++      unsigned int len = skb->len;
++
++      if ((li->u.ulog.flags & NF_LOG_F_COPY_LEN) &&
++          li->u.ulog.copy_len < copy_len)
++              copy_len = li->u.ulog.copy_len;
++      if (!skb_frags_readable(skb))
++              len = skb_headlen(skb);
++
++      return min(len, copy_len);
++}
++
+ /* log handler for internal netfilter logging api */
+ static void
+ nfulnl_log_packet(struct net *net,
+@@ -782,14 +797,7 @@ nfulnl_log_packet(struct net *net,
+               break;
+       case NFULNL_COPY_PACKET:
+-              data_len = inst->copy_range;
+-              if ((li->u.ulog.flags & NF_LOG_F_COPY_LEN) &&
+-                  (li->u.ulog.copy_len < data_len))
+-                      data_len = li->u.ulog.copy_len;
+-
+-              if (data_len > skb->len)
+-                      data_len = skb->len;
+-
++              data_len = nfulnl_get_copy_len(li, skb, inst->copy_range);
+               size += nla_total_size(data_len);
+               break;
+--- a/net/netfilter/nfnetlink_queue.c
++++ b/net/netfilter/nfnetlink_queue.c
+@@ -676,6 +676,17 @@ static int nfqnl_put_master_ifindex(stru
+ }
+ #endif
++static unsigned int nfqnl_get_data_len(const struct sk_buff *entskb,
++                                     unsigned int copy_range)
++{
++      unsigned int data_len = entskb->len;
++
++      if (!skb_frags_readable(entskb))
++              data_len = skb_headlen(entskb);
++
++      return min(data_len, copy_range);
++}
++
+ static struct sk_buff *
+ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
+                          struct nf_queue_entry *entry,
+@@ -741,10 +752,7 @@ nfqnl_build_packet_message(struct net *n
+                   nf_queue_checksum_help(entskb))
+                       return NULL;
+-              data_len = READ_ONCE(queue->copy_range);
+-              if (data_len > entskb->len)
+-                      data_len = entskb->len;
+-
++              data_len = nfqnl_get_data_len(entskb, READ_ONCE(queue->copy_range));
+               hlen = skb_zerocopy_headlen(entskb);
+               hlen = min_t(unsigned int, hlen, data_len);
+               size += sizeof(struct nlattr) + hlen;
+--- a/net/netfilter/xt_u32.c
++++ b/net/netfilter/xt_u32.c
+@@ -14,8 +14,8 @@
+ #include <linux/netfilter/x_tables.h>
+ #include <linux/netfilter/xt_u32.h>
+-static bool u32_match_it(const struct xt_u32 *data,
+-                       const struct sk_buff *skb)
++static int u32_match_it(const struct xt_u32 *data,
++                      const struct sk_buff *skb)
+ {
+       const struct xt_u32_test *ct;
+       unsigned int testind;
+@@ -40,7 +40,8 @@ static bool u32_match_it(const struct xt
+                       return false;
+               if (skb_copy_bits(skb, pos, &n, sizeof(n)) < 0)
+-                      BUG();
++                      return -1;
++
+               val   = ntohl(n);
+               nnums = ct->nnums;
+@@ -68,7 +69,7 @@ static bool u32_match_it(const struct xt
+                               if (skb_copy_bits(skb, at + pos, &n,
+                                                   sizeof(n)) < 0)
+-                                      BUG();
++                                      return -1;
+                               val = ntohl(n);
+                               break;
+                       }
+@@ -90,9 +91,14 @@ static bool u32_match_it(const struct xt
+ static bool u32_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       const struct xt_u32 *data = par->matchinfo;
+-      bool ret;
++      int ret;
+       ret = u32_match_it(data, skb);
++      if (ret < 0) {
++              par->hotdrop = true;
++              return false;
++      }
++
+       return ret ^ data->invert;
+ }
index f05fcc3f7b79174243338824d2f9b8b84877b85f..b932fc6bc94a82c2baa415e1e8a4ae857a9f43c5 100644 (file)
@@ -144,3 +144,6 @@ mm-shrinker-fix-shrinker_info-teardown-race-with-expansion.patch
 mm-shrinker-fix-null-pointer-dereference-in-debugfs.patch
 mm-swap-add-cond_resched-in-swap_reclaim_full_clusters-to-prevent-softlockup.patch
 netfilter-ctnetlink-use-nf_ct_exp_net-in-expectation-dump.patch
+netfilter-handle-unreadable-frags.patch
+netfilter-ebtables-module-names-must-be-null-terminated.patch
+netfilter-ebtables-terminate-table-name-before-find_table_lock.patch