Skip to content

Commit a28e1ba

Browse files
committed
net: loopback: Avoid sending IP packets without an Ethernet header
JIRA: https://issues.redhat.com/browse/RHEL-115601 Upstream Status: net-next.git commit 0e4427f commit 0e4427f Author: Ido Schimmel <idosch@nvidia.com> Date: Thu Feb 20 09:25:59 2025 +0200 net: loopback: Avoid sending IP packets without an Ethernet header After commit 2260059 ("ipv4: give an IPv4 dev to blackhole_netdev") IPv4 neighbors can be constructed on the blackhole net device, but they are constructed with an output function (neigh_direct_output()) that simply calls dev_queue_xmit(). The latter will transmit packets via 'skb->dev' which might not be the blackhole net device if dst_dev_put() switched 'dst->dev' to the blackhole net device while another CPU was using the dst entry in ip_output(), but after it already initialized 'skb->dev' from 'dst->dev'. Specifically, the following can happen: CPU1 CPU2 udp_sendmsg(sk1) udp_sendmsg(sk2) udp_send_skb() [...] ip_output() skb->dev = skb_dst(skb)->dev dst_dev_put() dst->dev = blackhole_netdev ip_finish_output2() resolves neigh on dst->dev neigh_output() neigh_direct_output() dev_queue_xmit() This will result in IPv4 packets being sent without an Ethernet header via a valid net device: tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on enp9s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 22:07:02.329668 20:00:40:11:18:fb > 45:00:00:44:f4:94, ethertype Unknown (0x58c6), length 68: 0x0000: 8dda 74ca f1ae ca6c ca6c 0098 969c 0400 ..t....l.l...... 0x0010: 0000 4730 3f18 6800 0000 0000 0000 9971 ..G0?.h........q 0x0020: c4c9 9055 a157 0a70 9ead bf83 38ca ab38 ...U.W.p....8..8 0x0030: 8add ab96 e052 .....R Fix by making sure that neighbors are constructed on top of the blackhole net device with an output function that simply consumes the packets, in a similar fashion to dst_discard_out() and blackhole_netdev_xmit(). Fixes: 8d7017f ("blackhole_netdev: use blackhole_netdev to invalidate dst entries") Fixes: 2260059 ("ipv4: give an IPv4 dev to blackhole_netdev") Reported-by: Florian Meister <fmei@sfs.com> Closes: https://lore.kernel.org/netdev/20250210084931.23a5c2e4@hermes.local/ Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20250220072559.782296-1-idosch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Davide Caratti <dcaratti@redhat.com>
1 parent b8bd692 commit a28e1ba

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

drivers/net/loopback.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,22 @@ static netdev_tx_t blackhole_netdev_xmit(struct sk_buff *skb,
244244
return NETDEV_TX_OK;
245245
}
246246

247+
static int blackhole_neigh_output(struct neighbour *n, struct sk_buff *skb)
248+
{
249+
kfree_skb(skb);
250+
return 0;
251+
}
252+
253+
static int blackhole_neigh_construct(struct net_device *dev,
254+
struct neighbour *n)
255+
{
256+
n->output = blackhole_neigh_output;
257+
return 0;
258+
}
259+
247260
static const struct net_device_ops blackhole_netdev_ops = {
248261
.ndo_start_xmit = blackhole_netdev_xmit,
262+
.ndo_neigh_construct = blackhole_neigh_construct,
249263
};
250264

251265
/* This is a dst-dummy device used specifically for invalidated

0 commit comments

Comments
 (0)