mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
tunnels: load network headers after skb_cow() in iptunnel_pmtud_build_icmp[v6]()
Sashiko found that iptunnel_pmtud_build_icmp() and
iptunnel_pmtud_build_icmpv6() were caching ip_hdr() and ipv6_hdr()
before an skb_cow() call which can reallocate skb->head.
Fix this possible UAF by initializing the local variables
after the skb_cow() call.
Remove skb_reset_network_header() calls which were not needed.
Fixes: 4cb47a8644 ("tunnels: PMTU discovery support for directly bridged IP packets")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
Link: https://patch.msgid.link/20260525201335.2361845-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
d895767c33
commit
b4bc943530
|
|
@ -212,7 +212,7 @@ EXPORT_SYMBOL_GPL(iptunnel_handle_offloads);
|
|||
*/
|
||||
static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
const struct iphdr *iph;
|
||||
struct icmphdr *icmph;
|
||||
struct iphdr *niph;
|
||||
struct ethhdr eh;
|
||||
|
|
@ -226,7 +226,6 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
|
|||
|
||||
skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
|
||||
pskb_pull(skb, ETH_HLEN);
|
||||
skb_reset_network_header(skb);
|
||||
|
||||
err = pskb_trim(skb, 576 - sizeof(*niph) - sizeof(*icmph));
|
||||
if (err)
|
||||
|
|
@ -236,7 +235,7 @@ static int iptunnel_pmtud_build_icmp(struct sk_buff *skb, int mtu)
|
|||
err = skb_cow(skb, sizeof(*niph) + sizeof(*icmph) + ETH_HLEN);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
iph = ip_hdr(skb);
|
||||
icmph = skb_push(skb, sizeof(*icmph));
|
||||
*icmph = (struct icmphdr) {
|
||||
.type = ICMP_DEST_UNREACH,
|
||||
|
|
@ -308,7 +307,7 @@ static int iptunnel_pmtud_check_icmp(struct sk_buff *skb, int mtu)
|
|||
*/
|
||||
static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
|
||||
{
|
||||
const struct ipv6hdr *ip6h = ipv6_hdr(skb);
|
||||
const struct ipv6hdr *ip6h;
|
||||
struct icmp6hdr *icmp6h;
|
||||
struct ipv6hdr *nip6h;
|
||||
struct ethhdr eh;
|
||||
|
|
@ -323,7 +322,6 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
|
|||
|
||||
skb_copy_bits(skb, skb_mac_offset(skb), &eh, ETH_HLEN);
|
||||
pskb_pull(skb, ETH_HLEN);
|
||||
skb_reset_network_header(skb);
|
||||
|
||||
err = pskb_trim(skb, IPV6_MIN_MTU - sizeof(*nip6h) - sizeof(*icmp6h));
|
||||
if (err)
|
||||
|
|
@ -334,6 +332,7 @@ static int iptunnel_pmtud_build_icmpv6(struct sk_buff *skb, int mtu)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
ip6h = ipv6_hdr(skb);
|
||||
icmp6h = skb_push(skb, sizeof(*icmp6h));
|
||||
*icmp6h = (struct icmp6hdr) {
|
||||
.icmp6_type = ICMPV6_PKT_TOOBIG,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user