From: Sasha Levin Date: Thu, 18 Jun 2026 16:26:55 +0000 (-0400) Subject: Fixes for all trees X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for all trees Signed-off-by: Sasha Levin --- 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 index 0000000000..f94eb71d5b --- /dev/null +++ b/queue-5.15/netfilter-require-ethernet-mac-header-before-using-e.patch @@ -0,0 +1,183 @@ +From 7c27d0b8cee95b6c754d845675865fedad5fd309 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 4 Apr 2026 17:39:48 +0800 +Subject: netfilter: require Ethernet MAC header before using eth_hdr() + +From: Zhengchuan Liang + +[ 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 +Tested-by: Ren Wei +Signed-off-by: Zhengchuan Liang +Signed-off-by: Ren Wei +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + #include + + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + +@@ -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 + diff --git a/queue-5.15/series b/queue-5.15/series index 500ddf94c7..13280126c8 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -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 index 0000000000..5bd2d50ac4 --- /dev/null +++ b/queue-6.1/netfilter-require-ethernet-mac-header-before-using-e.patch @@ -0,0 +1,183 @@ +From 2cbf2e9531608311ddecc98d7f17bdd9e48d4e43 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 4 Apr 2026 17:39:48 +0800 +Subject: netfilter: require Ethernet MAC header before using eth_hdr() + +From: Zhengchuan Liang + +[ 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 +Tested-by: Ren Wei +Signed-off-by: Zhengchuan Liang +Signed-off-by: Ren Wei +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + #include + + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + +@@ -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 + diff --git a/queue-6.1/series b/queue-6.1/series index 1b7b73706e..d1e9ad8836 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -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 index 0000000000..ffd14416b9 --- /dev/null +++ b/queue-6.12/netfilter-require-ethernet-mac-header-before-using-e.patch @@ -0,0 +1,183 @@ +From 3f2b1719b698dbc76f542a257131fe68465fc157 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 4 Apr 2026 17:39:48 +0800 +Subject: netfilter: require Ethernet MAC header before using eth_hdr() + +From: Zhengchuan Liang + +[ 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 +Tested-by: Ren Wei +Signed-off-by: Zhengchuan Liang +Signed-off-by: Ren Wei +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + #include + + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + +@@ -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 + diff --git a/queue-6.12/series b/queue-6.12/series index c267acf435..0ad7320840 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -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 index 0000000000..99697e5ee0 --- /dev/null +++ b/queue-6.18/netfilter-require-ethernet-mac-header-before-using-e.patch @@ -0,0 +1,183 @@ +From be967fca34d0550688ac45a7d62639016b889b50 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 4 Apr 2026 17:39:48 +0800 +Subject: netfilter: require Ethernet MAC header before using eth_hdr() + +From: Zhengchuan Liang + +[ 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 +Tested-by: Ren Wei +Signed-off-by: Zhengchuan Liang +Signed-off-by: Ren Wei +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + #include + + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + +@@ -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 + diff --git a/queue-6.18/series b/queue-6.18/series index 410f2ef878..25f104eeeb 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -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 index 0000000000..485f684d4e --- /dev/null +++ b/queue-6.6/netfilter-require-ethernet-mac-header-before-using-e.patch @@ -0,0 +1,183 @@ +From cb6836f2a029b6f85d7f8d58943ebe5c1e0250eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 4 Apr 2026 17:39:48 +0800 +Subject: netfilter: require Ethernet MAC header before using eth_hdr() + +From: Zhengchuan Liang + +[ 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 +Tested-by: Ren Wei +Signed-off-by: Zhengchuan Liang +Signed-off-by: Ren Wei +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + #include + + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + +@@ -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 + diff --git a/queue-6.6/series b/queue-6.6/series index 295c1c8454..8dc656fc0a 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -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 index 0000000000..71a0c61559 --- /dev/null +++ b/queue-7.0/netfilter-require-ethernet-mac-header-before-using-e.patch @@ -0,0 +1,183 @@ +From 298a6cec6a40b55cb13e048abe9587d05e743b80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 4 Apr 2026 17:39:48 +0800 +Subject: netfilter: require Ethernet MAC header before using eth_hdr() + +From: Zhengchuan Liang + +[ 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 +Tested-by: Ren Wei +Signed-off-by: Zhengchuan Liang +Signed-off-by: Ren Wei +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + #include + + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + #include + #include + +@@ -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 + diff --git a/queue-7.0/series b/queue-7.0/series index e021f7afc0..0d640aa056 100644 --- a/queue-7.0/series +++ b/queue-7.0/series @@ -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