]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for all trees master
authorSasha Levin <sashal@kernel.org>
Thu, 18 Jun 2026 16:26:55 +0000 (12:26 -0400)
committerSasha Levin <sashal@kernel.org>
Thu, 18 Jun 2026 16:26:55 +0000 (12:26 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
12 files changed:
queue-5.15/netfilter-require-ethernet-mac-header-before-using-e.patch [new file with mode: 0644]
queue-5.15/series
queue-6.1/netfilter-require-ethernet-mac-header-before-using-e.patch [new file with mode: 0644]
queue-6.1/series
queue-6.12/netfilter-require-ethernet-mac-header-before-using-e.patch [new file with mode: 0644]
queue-6.12/series
queue-6.18/netfilter-require-ethernet-mac-header-before-using-e.patch [new file with mode: 0644]
queue-6.18/series
queue-6.6/netfilter-require-ethernet-mac-header-before-using-e.patch [new file with mode: 0644]
queue-6.6/series
queue-7.0/netfilter-require-ethernet-mac-header-before-using-e.patch [new file with mode: 0644]
queue-7.0/series

diff --git a/queue-5.15/netfilter-require-ethernet-mac-header-before-using-e.patch b/queue-5.15/netfilter-require-ethernet-mac-header-before-using-e.patch
new file mode 100644 (file)
index 0000000..f94eb71
--- /dev/null
@@ -0,0 +1,183 @@
+From 7c27d0b8cee95b6c754d845675865fedad5fd309 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Apr 2026 17:39:48 +0800
+Subject: netfilter: require Ethernet MAC header before using eth_hdr()
+
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+
+[ Upstream commit 62443dc21114c0bbc476fa62973db89743f2f137 ]
+
+`ip6t_eui64`, `xt_mac`, the `bitmap:ip,mac`, `hash:ip,mac`, and
+`hash:mac` ipset types, and `nf_log_syslog` access `eth_hdr(skb)`
+after either assuming that the skb is associated with an Ethernet
+device or checking only that the `ETH_HLEN` bytes at
+`skb_mac_header(skb)` lie between `skb->head` and `skb->data`.
+
+Make these paths first verify that the skb is associated with an
+Ethernet device, that the MAC header was set, and that it spans at
+least a full Ethernet header before accessing `eth_hdr(skb)`.
+
+Suggested-by: Florian Westphal <fw@strlen.de>
+Tested-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/netfilter/ip6t_eui64.c           | 7 +++++--
+ net/netfilter/ipset/ip_set_bitmap_ipmac.c | 5 +++--
+ net/netfilter/ipset/ip_set_hash_ipmac.c   | 9 +++++----
+ net/netfilter/ipset/ip_set_hash_mac.c     | 5 +++--
+ net/netfilter/nf_log_syslog.c             | 8 +++++++-
+ net/netfilter/xt_mac.c                    | 4 +---
+ 6 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
+index da69a27e8332c1..bbb684f9964c03 100644
+--- a/net/ipv6/netfilter/ip6t_eui64.c
++++ b/net/ipv6/netfilter/ip6t_eui64.c
+@@ -7,6 +7,7 @@
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/ipv6.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/netfilter/x_tables.h>
+@@ -21,8 +22,10 @@ eui64_mt6(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       unsigned char eui64[8];
+-      if (!(skb_mac_header(skb) >= skb->head &&
+-            skb_mac_header(skb) + ETH_HLEN <= skb->data)) {
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER)
++              return false;
++
++      if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN) {
+               par->hotdrop = true;
+               return false;
+       }
+diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+index 2c625e0f49ec02..752f59ef874429 100644
+--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
++++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+@@ -11,6 +11,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/netlink.h>
+ #include <linux/jiffies.h>
+@@ -220,8 +221,8 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
+               return -IPSET_ERR_BITMAP_RANGE;
+       /* Backward compatibility: we don't check the second flag */
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       e.id = ip_to_id(map, ip);
+diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c
+index 467c59a83c0abc..b9a2681e248881 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipmac.c
++++ b/net/netfilter/ipset/ip_set_hash_ipmac.c
+@@ -11,6 +11,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
+ #include <linux/random.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <net/ip.h>
+ #include <net/ipv6.h>
+@@ -89,8 +90,8 @@ hash_ipmac4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       struct hash_ipmac4_elem e = { .ip = 0, { .foo[0] = 0, .foo[1] = 0 } };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_TWO_SRC)
+@@ -205,8 +206,8 @@ hash_ipmac6_kadt(struct ip_set *set, const struct sk_buff *skb,
+       };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_TWO_SRC)
+diff --git a/net/netfilter/ipset/ip_set_hash_mac.c b/net/netfilter/ipset/ip_set_hash_mac.c
+index 718814730acf6b..41a122591fe24d 100644
+--- a/net/netfilter/ipset/ip_set_hash_mac.c
++++ b/net/netfilter/ipset/ip_set_hash_mac.c
+@@ -8,6 +8,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <net/netlink.h>
+@@ -77,8 +78,8 @@ hash_mac4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       struct hash_mac4_elem e = { { .foo[0] = 0, .foo[1] = 0 } };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_ONE_SRC)
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index 2b0edb22ba511b..cae95c7963d73e 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -72,7 +72,10 @@ dump_arp_packet(struct nf_log_buf *m,
+       else
+               logflags = NF_LOG_DEFAULT_MASK;
+-      if (logflags & NF_LOG_MACDECODE) {
++      if ((logflags & NF_LOG_MACDECODE) &&
++          skb->dev && skb->dev->type == ARPHRD_ETHER &&
++          skb_mac_header_was_set(skb) &&
++          skb_mac_header_len(skb) >= ETH_HLEN) {
+               nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
+                              eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
+               nf_log_dump_vlan(m, skb);
+@@ -781,6 +784,9 @@ static void dump_ipv4_mac_header(struct nf_log_buf *m,
+       switch (dev->type) {
+       case ARPHRD_ETHER:
++              if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
++                      return;
++
+               nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
+                              eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
+               nf_log_dump_vlan(m, skb);
+diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
+index bd2354760895d2..7fc5156825e49c 100644
+--- a/net/netfilter/xt_mac.c
++++ b/net/netfilter/xt_mac.c
+@@ -29,9 +29,7 @@ static bool mac_mt(const struct sk_buff *skb, struct xt_action_param *par)
+       if (skb->dev == NULL || skb->dev->type != ARPHRD_ETHER)
+               return false;
+-      if (skb_mac_header(skb) < skb->head)
+-              return false;
+-      if (skb_mac_header(skb) + ETH_HLEN > skb->data)
++      if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return false;
+       ret  = ether_addr_equal(eth_hdr(skb)->h_source, info->srcaddr);
+       ret ^= info->invert;
+-- 
+2.53.0
+
index 500ddf94c705ae10ad15f3700ce9d11ea025e424..13280126c85953d7fa92e2d3c40b45365cad67a8 100644 (file)
@@ -406,3 +406,4 @@ bluetooth-mgmt-fix-backward-compatibility-with-userspace.patch
 ksmbd-oob-read-regression-in-smb_check_perm_dacl-ace-walk-loops.patch
 batman-adv-tp_meter-fix-race-condition-in-send-error-reporting.patch
 batman-adv-tp_meter-avoid-role-confusion-in-tp_list.patch
+netfilter-require-ethernet-mac-header-before-using-e.patch
diff --git a/queue-6.1/netfilter-require-ethernet-mac-header-before-using-e.patch b/queue-6.1/netfilter-require-ethernet-mac-header-before-using-e.patch
new file mode 100644 (file)
index 0000000..5bd2d50
--- /dev/null
@@ -0,0 +1,183 @@
+From 2cbf2e9531608311ddecc98d7f17bdd9e48d4e43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Apr 2026 17:39:48 +0800
+Subject: netfilter: require Ethernet MAC header before using eth_hdr()
+
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+
+[ Upstream commit 62443dc21114c0bbc476fa62973db89743f2f137 ]
+
+`ip6t_eui64`, `xt_mac`, the `bitmap:ip,mac`, `hash:ip,mac`, and
+`hash:mac` ipset types, and `nf_log_syslog` access `eth_hdr(skb)`
+after either assuming that the skb is associated with an Ethernet
+device or checking only that the `ETH_HLEN` bytes at
+`skb_mac_header(skb)` lie between `skb->head` and `skb->data`.
+
+Make these paths first verify that the skb is associated with an
+Ethernet device, that the MAC header was set, and that it spans at
+least a full Ethernet header before accessing `eth_hdr(skb)`.
+
+Suggested-by: Florian Westphal <fw@strlen.de>
+Tested-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/netfilter/ip6t_eui64.c           | 7 +++++--
+ net/netfilter/ipset/ip_set_bitmap_ipmac.c | 5 +++--
+ net/netfilter/ipset/ip_set_hash_ipmac.c   | 9 +++++----
+ net/netfilter/ipset/ip_set_hash_mac.c     | 5 +++--
+ net/netfilter/nf_log_syslog.c             | 8 +++++++-
+ net/netfilter/xt_mac.c                    | 4 +---
+ 6 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
+index da69a27e8332c1..bbb684f9964c03 100644
+--- a/net/ipv6/netfilter/ip6t_eui64.c
++++ b/net/ipv6/netfilter/ip6t_eui64.c
+@@ -7,6 +7,7 @@
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/ipv6.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/netfilter/x_tables.h>
+@@ -21,8 +22,10 @@ eui64_mt6(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       unsigned char eui64[8];
+-      if (!(skb_mac_header(skb) >= skb->head &&
+-            skb_mac_header(skb) + ETH_HLEN <= skb->data)) {
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER)
++              return false;
++
++      if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN) {
+               par->hotdrop = true;
+               return false;
+       }
+diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+index 2c625e0f49ec02..752f59ef874429 100644
+--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
++++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+@@ -11,6 +11,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/netlink.h>
+ #include <linux/jiffies.h>
+@@ -220,8 +221,8 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
+               return -IPSET_ERR_BITMAP_RANGE;
+       /* Backward compatibility: we don't check the second flag */
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       e.id = ip_to_id(map, ip);
+diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c
+index 467c59a83c0abc..b9a2681e248881 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipmac.c
++++ b/net/netfilter/ipset/ip_set_hash_ipmac.c
+@@ -11,6 +11,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
+ #include <linux/random.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <net/ip.h>
+ #include <net/ipv6.h>
+@@ -89,8 +90,8 @@ hash_ipmac4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       struct hash_ipmac4_elem e = { .ip = 0, { .foo[0] = 0, .foo[1] = 0 } };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_TWO_SRC)
+@@ -205,8 +206,8 @@ hash_ipmac6_kadt(struct ip_set *set, const struct sk_buff *skb,
+       };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_TWO_SRC)
+diff --git a/net/netfilter/ipset/ip_set_hash_mac.c b/net/netfilter/ipset/ip_set_hash_mac.c
+index 718814730acf6b..41a122591fe24d 100644
+--- a/net/netfilter/ipset/ip_set_hash_mac.c
++++ b/net/netfilter/ipset/ip_set_hash_mac.c
+@@ -8,6 +8,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <net/netlink.h>
+@@ -77,8 +78,8 @@ hash_mac4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       struct hash_mac4_elem e = { { .foo[0] = 0, .foo[1] = 0 } };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_ONE_SRC)
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index 09b9152e9e5492..11325bad19b367 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -78,7 +78,10 @@ dump_arp_packet(struct nf_log_buf *m,
+       else
+               logflags = NF_LOG_DEFAULT_MASK;
+-      if (logflags & NF_LOG_MACDECODE) {
++      if ((logflags & NF_LOG_MACDECODE) &&
++          skb->dev && skb->dev->type == ARPHRD_ETHER &&
++          skb_mac_header_was_set(skb) &&
++          skb_mac_header_len(skb) >= ETH_HLEN) {
+               nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
+                              eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
+               nf_log_dump_vlan(m, skb);
+@@ -787,6 +790,9 @@ static void dump_mac_header(struct nf_log_buf *m,
+       switch (dev->type) {
+       case ARPHRD_ETHER:
++              if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
++                      return;
++
+               nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
+                              eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
+               nf_log_dump_vlan(m, skb);
+diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
+index bd2354760895d2..7fc5156825e49c 100644
+--- a/net/netfilter/xt_mac.c
++++ b/net/netfilter/xt_mac.c
+@@ -29,9 +29,7 @@ static bool mac_mt(const struct sk_buff *skb, struct xt_action_param *par)
+       if (skb->dev == NULL || skb->dev->type != ARPHRD_ETHER)
+               return false;
+-      if (skb_mac_header(skb) < skb->head)
+-              return false;
+-      if (skb_mac_header(skb) + ETH_HLEN > skb->data)
++      if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return false;
+       ret  = ether_addr_equal(eth_hdr(skb)->h_source, info->srcaddr);
+       ret ^= info->invert;
+-- 
+2.53.0
+
index 1b7b73706ee690c7e4fe27782036cff371cf6d54..d1e9ad88365a8da0ebef0685dc85cdc1c435bc98 100644 (file)
@@ -525,3 +525,4 @@ media-rc-igorplugusb-fix-control-request-setup-packet.patch
 ksmbd-oob-read-regression-in-smb_check_perm_dacl-ace-walk-loops.patch
 batman-adv-tp_meter-fix-race-condition-in-send-error-reporting.patch
 batman-adv-tp_meter-avoid-role-confusion-in-tp_list.patch
+netfilter-require-ethernet-mac-header-before-using-e.patch
diff --git a/queue-6.12/netfilter-require-ethernet-mac-header-before-using-e.patch b/queue-6.12/netfilter-require-ethernet-mac-header-before-using-e.patch
new file mode 100644 (file)
index 0000000..ffd1441
--- /dev/null
@@ -0,0 +1,183 @@
+From 3f2b1719b698dbc76f542a257131fe68465fc157 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Apr 2026 17:39:48 +0800
+Subject: netfilter: require Ethernet MAC header before using eth_hdr()
+
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+
+[ Upstream commit 62443dc21114c0bbc476fa62973db89743f2f137 ]
+
+`ip6t_eui64`, `xt_mac`, the `bitmap:ip,mac`, `hash:ip,mac`, and
+`hash:mac` ipset types, and `nf_log_syslog` access `eth_hdr(skb)`
+after either assuming that the skb is associated with an Ethernet
+device or checking only that the `ETH_HLEN` bytes at
+`skb_mac_header(skb)` lie between `skb->head` and `skb->data`.
+
+Make these paths first verify that the skb is associated with an
+Ethernet device, that the MAC header was set, and that it spans at
+least a full Ethernet header before accessing `eth_hdr(skb)`.
+
+Suggested-by: Florian Westphal <fw@strlen.de>
+Tested-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/netfilter/ip6t_eui64.c           | 7 +++++--
+ net/netfilter/ipset/ip_set_bitmap_ipmac.c | 5 +++--
+ net/netfilter/ipset/ip_set_hash_ipmac.c   | 9 +++++----
+ net/netfilter/ipset/ip_set_hash_mac.c     | 5 +++--
+ net/netfilter/nf_log_syslog.c             | 8 +++++++-
+ net/netfilter/xt_mac.c                    | 4 +---
+ 6 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
+index da69a27e8332c1..bbb684f9964c03 100644
+--- a/net/ipv6/netfilter/ip6t_eui64.c
++++ b/net/ipv6/netfilter/ip6t_eui64.c
+@@ -7,6 +7,7 @@
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/ipv6.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/netfilter/x_tables.h>
+@@ -21,8 +22,10 @@ eui64_mt6(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       unsigned char eui64[8];
+-      if (!(skb_mac_header(skb) >= skb->head &&
+-            skb_mac_header(skb) + ETH_HLEN <= skb->data)) {
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER)
++              return false;
++
++      if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN) {
+               par->hotdrop = true;
+               return false;
+       }
+diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+index 2c625e0f49ec02..752f59ef874429 100644
+--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
++++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+@@ -11,6 +11,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/netlink.h>
+ #include <linux/jiffies.h>
+@@ -220,8 +221,8 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
+               return -IPSET_ERR_BITMAP_RANGE;
+       /* Backward compatibility: we don't check the second flag */
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       e.id = ip_to_id(map, ip);
+diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c
+index 467c59a83c0abc..b9a2681e248881 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipmac.c
++++ b/net/netfilter/ipset/ip_set_hash_ipmac.c
+@@ -11,6 +11,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
+ #include <linux/random.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <net/ip.h>
+ #include <net/ipv6.h>
+@@ -89,8 +90,8 @@ hash_ipmac4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       struct hash_ipmac4_elem e = { .ip = 0, { .foo[0] = 0, .foo[1] = 0 } };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_TWO_SRC)
+@@ -205,8 +206,8 @@ hash_ipmac6_kadt(struct ip_set *set, const struct sk_buff *skb,
+       };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_TWO_SRC)
+diff --git a/net/netfilter/ipset/ip_set_hash_mac.c b/net/netfilter/ipset/ip_set_hash_mac.c
+index 718814730acf6b..41a122591fe24d 100644
+--- a/net/netfilter/ipset/ip_set_hash_mac.c
++++ b/net/netfilter/ipset/ip_set_hash_mac.c
+@@ -8,6 +8,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <net/netlink.h>
+@@ -77,8 +78,8 @@ hash_mac4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       struct hash_mac4_elem e = { { .foo[0] = 0, .foo[1] = 0 } };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_ONE_SRC)
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index 09b9152e9e5492..11325bad19b367 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -78,7 +78,10 @@ dump_arp_packet(struct nf_log_buf *m,
+       else
+               logflags = NF_LOG_DEFAULT_MASK;
+-      if (logflags & NF_LOG_MACDECODE) {
++      if ((logflags & NF_LOG_MACDECODE) &&
++          skb->dev && skb->dev->type == ARPHRD_ETHER &&
++          skb_mac_header_was_set(skb) &&
++          skb_mac_header_len(skb) >= ETH_HLEN) {
+               nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
+                              eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
+               nf_log_dump_vlan(m, skb);
+@@ -787,6 +790,9 @@ static void dump_mac_header(struct nf_log_buf *m,
+       switch (dev->type) {
+       case ARPHRD_ETHER:
++              if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
++                      return;
++
+               nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
+                              eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
+               nf_log_dump_vlan(m, skb);
+diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
+index bd2354760895d2..7fc5156825e49c 100644
+--- a/net/netfilter/xt_mac.c
++++ b/net/netfilter/xt_mac.c
+@@ -29,9 +29,7 @@ static bool mac_mt(const struct sk_buff *skb, struct xt_action_param *par)
+       if (skb->dev == NULL || skb->dev->type != ARPHRD_ETHER)
+               return false;
+-      if (skb_mac_header(skb) < skb->head)
+-              return false;
+-      if (skb_mac_header(skb) + ETH_HLEN > skb->data)
++      if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return false;
+       ret  = ether_addr_equal(eth_hdr(skb)->h_source, info->srcaddr);
+       ret ^= info->invert;
+-- 
+2.53.0
+
index c267acf435846f7a6bc787ab23873b5f21c7efba..0ad7320840126238e7c63d81ea38b258817e7acd 100644 (file)
@@ -260,3 +260,4 @@ tcp-secure_seq-add-back-ports-to-ts-offset.patch
 mptcp-pm-fix-extra_subflows-underflow-on-userspace-pm-subflow-creation.patch
 revert-selftest-ptp-update-ptp-selftest-to-exercise-the-gettimex-options.patch
 vsock-virtio-fix-skb-overhead-overflow-on-32-bit-builds.patch
+netfilter-require-ethernet-mac-header-before-using-e.patch
diff --git a/queue-6.18/netfilter-require-ethernet-mac-header-before-using-e.patch b/queue-6.18/netfilter-require-ethernet-mac-header-before-using-e.patch
new file mode 100644 (file)
index 0000000..99697e5
--- /dev/null
@@ -0,0 +1,183 @@
+From be967fca34d0550688ac45a7d62639016b889b50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Apr 2026 17:39:48 +0800
+Subject: netfilter: require Ethernet MAC header before using eth_hdr()
+
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+
+[ Upstream commit 62443dc21114c0bbc476fa62973db89743f2f137 ]
+
+`ip6t_eui64`, `xt_mac`, the `bitmap:ip,mac`, `hash:ip,mac`, and
+`hash:mac` ipset types, and `nf_log_syslog` access `eth_hdr(skb)`
+after either assuming that the skb is associated with an Ethernet
+device or checking only that the `ETH_HLEN` bytes at
+`skb_mac_header(skb)` lie between `skb->head` and `skb->data`.
+
+Make these paths first verify that the skb is associated with an
+Ethernet device, that the MAC header was set, and that it spans at
+least a full Ethernet header before accessing `eth_hdr(skb)`.
+
+Suggested-by: Florian Westphal <fw@strlen.de>
+Tested-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/netfilter/ip6t_eui64.c           | 7 +++++--
+ net/netfilter/ipset/ip_set_bitmap_ipmac.c | 5 +++--
+ net/netfilter/ipset/ip_set_hash_ipmac.c   | 9 +++++----
+ net/netfilter/ipset/ip_set_hash_mac.c     | 5 +++--
+ net/netfilter/nf_log_syslog.c             | 8 +++++++-
+ net/netfilter/xt_mac.c                    | 4 +---
+ 6 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
+index da69a27e8332c1..bbb684f9964c03 100644
+--- a/net/ipv6/netfilter/ip6t_eui64.c
++++ b/net/ipv6/netfilter/ip6t_eui64.c
+@@ -7,6 +7,7 @@
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/ipv6.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/netfilter/x_tables.h>
+@@ -21,8 +22,10 @@ eui64_mt6(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       unsigned char eui64[8];
+-      if (!(skb_mac_header(skb) >= skb->head &&
+-            skb_mac_header(skb) + ETH_HLEN <= skb->data)) {
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER)
++              return false;
++
++      if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN) {
+               par->hotdrop = true;
+               return false;
+       }
+diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+index 2c625e0f49ec02..752f59ef874429 100644
+--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
++++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+@@ -11,6 +11,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/netlink.h>
+ #include <linux/jiffies.h>
+@@ -220,8 +221,8 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
+               return -IPSET_ERR_BITMAP_RANGE;
+       /* Backward compatibility: we don't check the second flag */
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       e.id = ip_to_id(map, ip);
+diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c
+index 467c59a83c0abc..b9a2681e248881 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipmac.c
++++ b/net/netfilter/ipset/ip_set_hash_ipmac.c
+@@ -11,6 +11,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
+ #include <linux/random.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <net/ip.h>
+ #include <net/ipv6.h>
+@@ -89,8 +90,8 @@ hash_ipmac4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       struct hash_ipmac4_elem e = { .ip = 0, { .foo[0] = 0, .foo[1] = 0 } };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_TWO_SRC)
+@@ -205,8 +206,8 @@ hash_ipmac6_kadt(struct ip_set *set, const struct sk_buff *skb,
+       };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_TWO_SRC)
+diff --git a/net/netfilter/ipset/ip_set_hash_mac.c b/net/netfilter/ipset/ip_set_hash_mac.c
+index 718814730acf6b..41a122591fe24d 100644
+--- a/net/netfilter/ipset/ip_set_hash_mac.c
++++ b/net/netfilter/ipset/ip_set_hash_mac.c
+@@ -8,6 +8,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <net/netlink.h>
+@@ -77,8 +78,8 @@ hash_mac4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       struct hash_mac4_elem e = { { .foo[0] = 0, .foo[1] = 0 } };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_ONE_SRC)
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index 613f37b300a560..6fa0812cd79ca4 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -78,7 +78,10 @@ dump_arp_packet(struct nf_log_buf *m,
+       else
+               logflags = NF_LOG_DEFAULT_MASK;
+-      if (logflags & NF_LOG_MACDECODE) {
++      if ((logflags & NF_LOG_MACDECODE) &&
++          skb->dev && skb->dev->type == ARPHRD_ETHER &&
++          skb_mac_header_was_set(skb) &&
++          skb_mac_header_len(skb) >= ETH_HLEN) {
+               nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
+                              eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
+               nf_log_dump_vlan(m, skb);
+@@ -789,6 +792,9 @@ static void dump_mac_header(struct nf_log_buf *m,
+       switch (dev->type) {
+       case ARPHRD_ETHER:
++              if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
++                      return;
++
+               nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
+                              eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
+               nf_log_dump_vlan(m, skb);
+diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
+index bd2354760895d2..7fc5156825e49c 100644
+--- a/net/netfilter/xt_mac.c
++++ b/net/netfilter/xt_mac.c
+@@ -29,9 +29,7 @@ static bool mac_mt(const struct sk_buff *skb, struct xt_action_param *par)
+       if (skb->dev == NULL || skb->dev->type != ARPHRD_ETHER)
+               return false;
+-      if (skb_mac_header(skb) < skb->head)
+-              return false;
+-      if (skb_mac_header(skb) + ETH_HLEN > skb->data)
++      if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return false;
+       ret  = ether_addr_equal(eth_hdr(skb)->h_source, info->srcaddr);
+       ret ^= info->invert;
+-- 
+2.53.0
+
index 410f2ef87877f2348c18de5b7e670f94a34ba549..25f104eeeb156bcea763ed6249d453badd822634 100644 (file)
@@ -325,3 +325,4 @@ arm64-errata-mitigate-tlbi-errata-on-microsoft-azure-cobalt-100-cpu.patch
 block-fix-handling-of-dead-zone-write-plugs.patch
 vsock-virtio-fix-skb-overhead-overflow-on-32-bit-builds.patch
 cfi-include-uaccess.h-for-get_kernel_nofault.patch
+netfilter-require-ethernet-mac-header-before-using-e.patch
diff --git a/queue-6.6/netfilter-require-ethernet-mac-header-before-using-e.patch b/queue-6.6/netfilter-require-ethernet-mac-header-before-using-e.patch
new file mode 100644 (file)
index 0000000..485f684
--- /dev/null
@@ -0,0 +1,183 @@
+From cb6836f2a029b6f85d7f8d58943ebe5c1e0250eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Apr 2026 17:39:48 +0800
+Subject: netfilter: require Ethernet MAC header before using eth_hdr()
+
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+
+[ Upstream commit 62443dc21114c0bbc476fa62973db89743f2f137 ]
+
+`ip6t_eui64`, `xt_mac`, the `bitmap:ip,mac`, `hash:ip,mac`, and
+`hash:mac` ipset types, and `nf_log_syslog` access `eth_hdr(skb)`
+after either assuming that the skb is associated with an Ethernet
+device or checking only that the `ETH_HLEN` bytes at
+`skb_mac_header(skb)` lie between `skb->head` and `skb->data`.
+
+Make these paths first verify that the skb is associated with an
+Ethernet device, that the MAC header was set, and that it spans at
+least a full Ethernet header before accessing `eth_hdr(skb)`.
+
+Suggested-by: Florian Westphal <fw@strlen.de>
+Tested-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/netfilter/ip6t_eui64.c           | 7 +++++--
+ net/netfilter/ipset/ip_set_bitmap_ipmac.c | 5 +++--
+ net/netfilter/ipset/ip_set_hash_ipmac.c   | 9 +++++----
+ net/netfilter/ipset/ip_set_hash_mac.c     | 5 +++--
+ net/netfilter/nf_log_syslog.c             | 8 +++++++-
+ net/netfilter/xt_mac.c                    | 4 +---
+ 6 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
+index da69a27e8332c1..bbb684f9964c03 100644
+--- a/net/ipv6/netfilter/ip6t_eui64.c
++++ b/net/ipv6/netfilter/ip6t_eui64.c
+@@ -7,6 +7,7 @@
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/ipv6.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/netfilter/x_tables.h>
+@@ -21,8 +22,10 @@ eui64_mt6(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       unsigned char eui64[8];
+-      if (!(skb_mac_header(skb) >= skb->head &&
+-            skb_mac_header(skb) + ETH_HLEN <= skb->data)) {
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER)
++              return false;
++
++      if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN) {
+               par->hotdrop = true;
+               return false;
+       }
+diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+index 2c625e0f49ec02..752f59ef874429 100644
+--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
++++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+@@ -11,6 +11,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/netlink.h>
+ #include <linux/jiffies.h>
+@@ -220,8 +221,8 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
+               return -IPSET_ERR_BITMAP_RANGE;
+       /* Backward compatibility: we don't check the second flag */
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       e.id = ip_to_id(map, ip);
+diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c
+index 467c59a83c0abc..b9a2681e248881 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipmac.c
++++ b/net/netfilter/ipset/ip_set_hash_ipmac.c
+@@ -11,6 +11,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
+ #include <linux/random.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <net/ip.h>
+ #include <net/ipv6.h>
+@@ -89,8 +90,8 @@ hash_ipmac4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       struct hash_ipmac4_elem e = { .ip = 0, { .foo[0] = 0, .foo[1] = 0 } };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_TWO_SRC)
+@@ -205,8 +206,8 @@ hash_ipmac6_kadt(struct ip_set *set, const struct sk_buff *skb,
+       };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_TWO_SRC)
+diff --git a/net/netfilter/ipset/ip_set_hash_mac.c b/net/netfilter/ipset/ip_set_hash_mac.c
+index 718814730acf6b..41a122591fe24d 100644
+--- a/net/netfilter/ipset/ip_set_hash_mac.c
++++ b/net/netfilter/ipset/ip_set_hash_mac.c
+@@ -8,6 +8,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <net/netlink.h>
+@@ -77,8 +78,8 @@ hash_mac4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       struct hash_mac4_elem e = { { .foo[0] = 0, .foo[1] = 0 } };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_ONE_SRC)
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index 09b9152e9e5492..11325bad19b367 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -78,7 +78,10 @@ dump_arp_packet(struct nf_log_buf *m,
+       else
+               logflags = NF_LOG_DEFAULT_MASK;
+-      if (logflags & NF_LOG_MACDECODE) {
++      if ((logflags & NF_LOG_MACDECODE) &&
++          skb->dev && skb->dev->type == ARPHRD_ETHER &&
++          skb_mac_header_was_set(skb) &&
++          skb_mac_header_len(skb) >= ETH_HLEN) {
+               nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
+                              eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
+               nf_log_dump_vlan(m, skb);
+@@ -787,6 +790,9 @@ static void dump_mac_header(struct nf_log_buf *m,
+       switch (dev->type) {
+       case ARPHRD_ETHER:
++              if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
++                      return;
++
+               nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
+                              eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
+               nf_log_dump_vlan(m, skb);
+diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
+index bd2354760895d2..7fc5156825e49c 100644
+--- a/net/netfilter/xt_mac.c
++++ b/net/netfilter/xt_mac.c
+@@ -29,9 +29,7 @@ static bool mac_mt(const struct sk_buff *skb, struct xt_action_param *par)
+       if (skb->dev == NULL || skb->dev->type != ARPHRD_ETHER)
+               return false;
+-      if (skb_mac_header(skb) < skb->head)
+-              return false;
+-      if (skb_mac_header(skb) + ETH_HLEN > skb->data)
++      if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return false;
+       ret  = ether_addr_equal(eth_hdr(skb)->h_source, info->srcaddr);
+       ret ^= info->invert;
+-- 
+2.53.0
+
index 295c1c84545d3673fb1406b2123d0930e184f952..8dc656fc0aa66c6579d137b0fe9b4be917e18625 100644 (file)
@@ -445,3 +445,4 @@ revert-selftest-ptp-update-ptp-selftest-to-exercise-the-gettimex-options.patch
 x86-cpu-amd-move-the-zen3-btc_no-detection-to-the-zen3-init-function.patch
 x86-cpu-amd-call-the-spectral-chicken-in-the-zen2-init-function.patch
 x86-cpu-amd-rename-init_amd_zn-to-init_amd_zen_common.patch
+netfilter-require-ethernet-mac-header-before-using-e.patch
diff --git a/queue-7.0/netfilter-require-ethernet-mac-header-before-using-e.patch b/queue-7.0/netfilter-require-ethernet-mac-header-before-using-e.patch
new file mode 100644 (file)
index 0000000..71a0c61
--- /dev/null
@@ -0,0 +1,183 @@
+From 298a6cec6a40b55cb13e048abe9587d05e743b80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Apr 2026 17:39:48 +0800
+Subject: netfilter: require Ethernet MAC header before using eth_hdr()
+
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+
+[ Upstream commit 62443dc21114c0bbc476fa62973db89743f2f137 ]
+
+`ip6t_eui64`, `xt_mac`, the `bitmap:ip,mac`, `hash:ip,mac`, and
+`hash:mac` ipset types, and `nf_log_syslog` access `eth_hdr(skb)`
+after either assuming that the skb is associated with an Ethernet
+device or checking only that the `ETH_HLEN` bytes at
+`skb_mac_header(skb)` lie between `skb->head` and `skb->data`.
+
+Make these paths first verify that the skb is associated with an
+Ethernet device, that the MAC header was set, and that it spans at
+least a full Ethernet header before accessing `eth_hdr(skb)`.
+
+Suggested-by: Florian Westphal <fw@strlen.de>
+Tested-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/netfilter/ip6t_eui64.c           | 7 +++++--
+ net/netfilter/ipset/ip_set_bitmap_ipmac.c | 5 +++--
+ net/netfilter/ipset/ip_set_hash_ipmac.c   | 9 +++++----
+ net/netfilter/ipset/ip_set_hash_mac.c     | 5 +++--
+ net/netfilter/nf_log_syslog.c             | 8 +++++++-
+ net/netfilter/xt_mac.c                    | 4 +---
+ 6 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
+index da69a27e8332c1..bbb684f9964c03 100644
+--- a/net/ipv6/netfilter/ip6t_eui64.c
++++ b/net/ipv6/netfilter/ip6t_eui64.c
+@@ -7,6 +7,7 @@
+ #include <linux/module.h>
+ #include <linux/skbuff.h>
+ #include <linux/ipv6.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/netfilter/x_tables.h>
+@@ -21,8 +22,10 @@ eui64_mt6(const struct sk_buff *skb, struct xt_action_param *par)
+ {
+       unsigned char eui64[8];
+-      if (!(skb_mac_header(skb) >= skb->head &&
+-            skb_mac_header(skb) + ETH_HLEN <= skb->data)) {
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER)
++              return false;
++
++      if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN) {
+               par->hotdrop = true;
+               return false;
+       }
+diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+index 2c625e0f49ec02..752f59ef874429 100644
+--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
++++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+@@ -11,6 +11,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <linux/netlink.h>
+ #include <linux/jiffies.h>
+@@ -220,8 +221,8 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
+               return -IPSET_ERR_BITMAP_RANGE;
+       /* Backward compatibility: we don't check the second flag */
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       e.id = ip_to_id(map, ip);
+diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c
+index 467c59a83c0abc..b9a2681e248881 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipmac.c
++++ b/net/netfilter/ipset/ip_set_hash_ipmac.c
+@@ -11,6 +11,7 @@
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
+ #include <linux/random.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <net/ip.h>
+ #include <net/ipv6.h>
+@@ -89,8 +90,8 @@ hash_ipmac4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       struct hash_ipmac4_elem e = { .ip = 0, { .foo[0] = 0, .foo[1] = 0 } };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_TWO_SRC)
+@@ -205,8 +206,8 @@ hash_ipmac6_kadt(struct ip_set *set, const struct sk_buff *skb,
+       };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_TWO_SRC)
+diff --git a/net/netfilter/ipset/ip_set_hash_mac.c b/net/netfilter/ipset/ip_set_hash_mac.c
+index 718814730acf6b..41a122591fe24d 100644
+--- a/net/netfilter/ipset/ip_set_hash_mac.c
++++ b/net/netfilter/ipset/ip_set_hash_mac.c
+@@ -8,6 +8,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/errno.h>
++#include <linux/if_arp.h>
+ #include <linux/if_ether.h>
+ #include <net/netlink.h>
+@@ -77,8 +78,8 @@ hash_mac4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       struct hash_mac4_elem e = { { .foo[0] = 0, .foo[1] = 0 } };
+       struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+-      if (skb_mac_header(skb) < skb->head ||
+-          (skb_mac_header(skb) + ETH_HLEN) > skb->data)
++      if (!skb->dev || skb->dev->type != ARPHRD_ETHER ||
++          !skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return -EINVAL;
+       if (opt->flags & IPSET_DIM_ONE_SRC)
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index c0462d403157a9..dfacd9279f6ee0 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -78,7 +78,10 @@ dump_arp_packet(struct nf_log_buf *m,
+       else
+               logflags = NF_LOG_DEFAULT_MASK;
+-      if (logflags & NF_LOG_MACDECODE) {
++      if ((logflags & NF_LOG_MACDECODE) &&
++          skb->dev && skb->dev->type == ARPHRD_ETHER &&
++          skb_mac_header_was_set(skb) &&
++          skb_mac_header_len(skb) >= ETH_HLEN) {
+               nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
+                              eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
+               nf_log_dump_vlan(m, skb);
+@@ -789,6 +792,9 @@ static void dump_mac_header(struct nf_log_buf *m,
+       switch (dev->type) {
+       case ARPHRD_ETHER:
++              if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
++                      return;
++
+               nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM ",
+                              eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest);
+               nf_log_dump_vlan(m, skb);
+diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
+index bd2354760895d2..7fc5156825e49c 100644
+--- a/net/netfilter/xt_mac.c
++++ b/net/netfilter/xt_mac.c
+@@ -29,9 +29,7 @@ static bool mac_mt(const struct sk_buff *skb, struct xt_action_param *par)
+       if (skb->dev == NULL || skb->dev->type != ARPHRD_ETHER)
+               return false;
+-      if (skb_mac_header(skb) < skb->head)
+-              return false;
+-      if (skb_mac_header(skb) + ETH_HLEN > skb->data)
++      if (!skb_mac_header_was_set(skb) || skb_mac_header_len(skb) < ETH_HLEN)
+               return false;
+       ret  = ether_addr_equal(eth_hdr(skb)->h_source, info->srcaddr);
+       ret ^= info->invert;
+-- 
+2.53.0
+
index e021f7afc0b3a112941bc02e81766dbaf84ab742..0d640aa05639cafa3e87f4b941290fd932f2cc4a 100644 (file)
@@ -377,3 +377,4 @@ arm64-errata-mitigate-tlbi-errata-on-various-arm-cpus.patch
 arm64-errata-mitigate-tlbi-errata-on-nvidia-olympus-cpu.patch
 arm64-errata-mitigate-tlbi-errata-on-microsoft-azure-cobalt-100-cpu.patch
 vsock-virtio-fix-skb-overhead-overflow-on-32-bit-builds.patch
+netfilter-require-ethernet-mac-header-before-using-e.patch