b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| 2 | From: "Jason A. Donenfeld" <Jason@zx2c4.com> |
| 3 | Date: Mon, 22 Feb 2021 17:25:47 +0100 |
| 4 | Subject: [PATCH] wireguard: device: do not generate ICMP for non-IP packets |
| 5 | |
| 6 | commit 99fff5264e7ab06f45b0ad60243475be0a8d0559 upstream. |
| 7 | |
| 8 | If skb->protocol doesn't match the actual skb->data header, it's |
| 9 | probably not a good idea to pass it off to icmp{,v6}_ndo_send, which is |
| 10 | expecting to reply to a valid IP packet. So this commit has that early |
| 11 | mismatch case jump to a later error label. |
| 12 | |
| 13 | Fixes: e7096c131e51 ("net: WireGuard secure network tunnel") |
| 14 | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> |
| 15 | Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| 16 | Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> |
| 17 | --- |
| 18 | drivers/net/wireguard/device.c | 7 ++++--- |
| 19 | 1 file changed, 4 insertions(+), 3 deletions(-) |
| 20 | |
| 21 | --- a/drivers/net/wireguard/device.c |
| 22 | +++ b/drivers/net/wireguard/device.c |
| 23 | @@ -138,7 +138,7 @@ static netdev_tx_t wg_xmit(struct sk_buf |
| 24 | else if (skb->protocol == htons(ETH_P_IPV6)) |
| 25 | net_dbg_ratelimited("%s: No peer has allowed IPs matching %pI6\n", |
| 26 | dev->name, &ipv6_hdr(skb)->daddr); |
| 27 | - goto err; |
| 28 | + goto err_icmp; |
| 29 | } |
| 30 | |
| 31 | family = READ_ONCE(peer->endpoint.addr.sa_family); |
| 32 | @@ -201,12 +201,13 @@ static netdev_tx_t wg_xmit(struct sk_buf |
| 33 | |
| 34 | err_peer: |
| 35 | wg_peer_put(peer); |
| 36 | -err: |
| 37 | - ++dev->stats.tx_errors; |
| 38 | +err_icmp: |
| 39 | if (skb->protocol == htons(ETH_P_IP)) |
| 40 | icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); |
| 41 | else if (skb->protocol == htons(ETH_P_IPV6)) |
| 42 | icmpv6_ndo_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0); |
| 43 | +err: |
| 44 | + ++dev->stats.tx_errors; |
| 45 | kfree_skb(skb); |
| 46 | return ret; |
| 47 | } |