Skip to content

Commit f778941

Browse files
Guillaume Naultkuba-moo
authored andcommitted
vxlan: Pull inner IP header in vxlan_rcv().
Ensure the inner IP header is part of skb's linear data before reading its ECN bits. Otherwise we might read garbage. One symptom is the system erroneously logging errors like "vxlan: non-ECT from xxx.xxx.xxx.xxx with TOS=xxxx". Similar bugs have been fixed in geneve, ip_tunnel and ip6_tunnel (see commit 1ca1ba4 ("geneve: make sure to pull inner header in geneve_rx()") for example). So let's reuse the same code structure for consistency. Maybe we'll can add a common helper in the future. Fixes: d342894 ("vxlan: virtual extensible lan") Signed-off-by: Guillaume Nault <[email protected]> Reviewed-by: Ido Schimmel <[email protected]> Reviewed-by: Eric Dumazet <[email protected]> Reviewed-by: Nikolay Aleksandrov <[email protected]> Reviewed-by: Sabrina Dubroca <[email protected]> Link: https://lore.kernel.org/r/1239c8db54efec341dd6455c77e0380f58923a3c.1714495737.git.gnault@redhat.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 97bf6f8 commit f778941

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

drivers/net/vxlan/vxlan_core.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1674,6 +1674,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
16741674
bool raw_proto = false;
16751675
void *oiph;
16761676
__be32 vni = 0;
1677+
int nh;
16771678

16781679
/* Need UDP and VXLAN header to be present */
16791680
if (!pskb_may_pull(skb, VXLAN_HLEN))
@@ -1762,9 +1763,25 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
17621763
skb->pkt_type = PACKET_HOST;
17631764
}
17641765

1765-
oiph = skb_network_header(skb);
1766+
/* Save offset of outer header relative to skb->head,
1767+
* because we are going to reset the network header to the inner header
1768+
* and might change skb->head.
1769+
*/
1770+
nh = skb_network_header(skb) - skb->head;
1771+
17661772
skb_reset_network_header(skb);
17671773

1774+
if (!pskb_inet_may_pull(skb)) {
1775+
DEV_STATS_INC(vxlan->dev, rx_length_errors);
1776+
DEV_STATS_INC(vxlan->dev, rx_errors);
1777+
vxlan_vnifilter_count(vxlan, vni, vninode,
1778+
VXLAN_VNI_STATS_RX_ERRORS, 0);
1779+
goto drop;
1780+
}
1781+
1782+
/* Get the outer header. */
1783+
oiph = skb->head + nh;
1784+
17681785
if (!vxlan_ecn_decapsulate(vs, oiph, skb)) {
17691786
DEV_STATS_INC(vxlan->dev, rx_frame_errors);
17701787
DEV_STATS_INC(vxlan->dev, rx_errors);

0 commit comments

Comments
 (0)