Public bug reported:

[SRU Justification]

[Impact]

In vxlan_xmit_one(), the local variable old_iph caches the return value of
ip_hdr(skb) — a pointer into skb->data — before calling
skb_tunnel_check_pmtu().  That function may internally call
pskb_expand_head() to reallocate skb->head, which invalidates any
previously derived pointer into the skb data area.  After the call returns,
old_iph is passed to ip_tunnel_ecn_encap(), constituting a use-after-free
(UAF).

The UAF is reachable when a vxlan interface is attached to a bridge and
locally-originated bridged IP traffic encounters a PMTU exception — i.e.,
when an ICMP Fragmentation Needed / Packet Too Big message arrives for
traffic being forwarded through the bridged vxlan tunnel.  At minimum this
silently corrupts the ECN/TOS encoding of the outer IP header of the
re-encapsulated packet, causing the bridged PMTU path to malfunction
(affected senders see 100% packet loss after the PMTU exception fires).  In
the worst case it exposes kernel memory corruption or a crash.

[Fix]

Replace the two stale uses of old_iph after skb_tunnel_check_pmtu() with a
fresh call to ip_hdr(skb), which re-derives the current IP header pointer
from skb->head after any possible reallocation.  This matches the approach
already used in drivers/net/bareudp.c and drivers/net/geneve.c for the same
pattern.

Upstream commit: 7d9ef0cb271555d8cf39fefe6c981e1493b25ecf
  "vxlan: do not reuse cached ip_hdr() value after skb_tunnel_check_pmtu()"
  Author: Eric Dumazet <[email protected]>
  Reviewed-by: Stefano Brivio <[email protected]> (author of 4cb47a8644cc)

The change is 2 lines in drivers/net/vxlan/vxlan_core.c.

[Test Plan]

The kernel selftests pmtu.sh exercises the bridged vxlan PMTU path and
reliably reproduces the failure.  Run from the kernel source tree:

  cd tools/testing/selftests/net
  sudo bash pmtu.sh pmtu_ipv4_br_vxlan4_exception \
                    pmtu_ipv6_br_vxlan4_exception \
                    pmtu_ipv4_br_vxlan6_exception \
                    pmtu_ipv6_br_vxlan6_exception

Without fix: all four report [FAIL] — the locally-bridged sender (ns_a)
sees 100% packet loss because the UAF corrupts the TOS/ECN re-encoding of
the outer header, breaking the PMTU feedback loop.

With fix: all four report [ OK ].

The full ubuntu_kselftests_net autotest (net:pmtu.sh) covers all 16
bridged vxlan/geneve exception subtests and can be used for automated
verification.

[Where problems could occur]

Regression potential: low, the commit is already upstream (v7.1-rc3) and
fixes a specific issue.

** Affects: linux (Ubuntu)
     Importance: Undecided
         Status: New

** Affects: linux (Ubuntu Resolute)
     Importance: Undecided
         Status: New

** Description changed:

- SRU Justification]
+ [SRU Justification]
  
  [Impact]
  
  In vxlan_xmit_one(), the local variable old_iph caches the return value of
  ip_hdr(skb) — a pointer into skb->data — before calling
  skb_tunnel_check_pmtu().  That function may internally call
  pskb_expand_head() to reallocate skb->head, which invalidates any
  previously derived pointer into the skb data area.  After the call returns,
  old_iph is passed to ip_tunnel_ecn_encap(), constituting a use-after-free
  (UAF).
  
  The UAF is reachable when a vxlan interface is attached to a bridge and
  locally-originated bridged IP traffic encounters a PMTU exception — i.e.,
  when an ICMP Fragmentation Needed / Packet Too Big message arrives for
  traffic being forwarded through the bridged vxlan tunnel.  At minimum this
  silently corrupts the ECN/TOS encoding of the outer IP header of the
  re-encapsulated packet, causing the bridged PMTU path to malfunction
  (affected senders see 100% packet loss after the PMTU exception fires).  In
  the worst case it exposes kernel memory corruption or a crash.
  
  [Fix]
  
  Replace the two stale uses of old_iph after skb_tunnel_check_pmtu() with a
  fresh call to ip_hdr(skb), which re-derives the current IP header pointer
  from skb->head after any possible reallocation.  This matches the approach
  already used in drivers/net/bareudp.c and drivers/net/geneve.c for the same
  pattern.
  
  Upstream commit: 7d9ef0cb271555d8cf39fefe6c981e1493b25ecf
-   "vxlan: do not reuse cached ip_hdr() value after skb_tunnel_check_pmtu()"
-   Author: Eric Dumazet <[email protected]>
-   Reviewed-by: Stefano Brivio <[email protected]> (author of 4cb47a8644cc)
+   "vxlan: do not reuse cached ip_hdr() value after skb_tunnel_check_pmtu()"
+   Author: Eric Dumazet <[email protected]>
+   Reviewed-by: Stefano Brivio <[email protected]> (author of 4cb47a8644cc)
  
  The change is 2 lines in drivers/net/vxlan/vxlan_core.c.
  
  [Test Plan]
  
  The kernel selftests pmtu.sh exercises the bridged vxlan PMTU path and
  reliably reproduces the failure.  Run from the kernel source tree:
  
-   cd tools/testing/selftests/net
-   sudo bash pmtu.sh pmtu_ipv4_br_vxlan4_exception \
-                     pmtu_ipv6_br_vxlan4_exception \
-                     pmtu_ipv4_br_vxlan6_exception \
-                     pmtu_ipv6_br_vxlan6_exception
+   cd tools/testing/selftests/net
+   sudo bash pmtu.sh pmtu_ipv4_br_vxlan4_exception \
+                     pmtu_ipv6_br_vxlan4_exception \
+                     pmtu_ipv4_br_vxlan6_exception \
+                     pmtu_ipv6_br_vxlan6_exception
  
  Without fix: all four report [FAIL] — the locally-bridged sender (ns_a)
  sees 100% packet loss because the UAF corrupts the TOS/ECN re-encoding of
  the outer header, breaking the PMTU feedback loop.
  
  With fix: all four report [ OK ].
  
  The full ubuntu_kselftests_net autotest (net:pmtu.sh) covers all 16
  bridged vxlan/geneve exception subtests and can be used for automated
  verification.
  
  [Where problems could occur]
  
  Regression potential: low, the commit is already upstream (v7.1-rc3) and
  fixes a specific issue.

** Also affects: linux (Ubuntu Resolute)
   Importance: Undecided
       Status: New

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2156063

Title:
  vxlan: do not reuse cached ip_hdr() value after
  skb_tunnel_check_pmtu()

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2156063/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to