Skip to content

Commit

Permalink
fix: patch Linux with blackhole patch
Browse files Browse the repository at this point in the history
See siderolabs/talos#9837

This causes invalid Ethernet packets to be sent out, which might
trigger unrelated issues in some environments.

See:

* git.kernel.org/netdev/net/c/0e4427f8f587
* lore.kernel.org/netdev/[email protected]/T

Signed-off-by: Andrey Smirnov <[email protected]>
  • Loading branch information
smira committed Feb 25, 2025
1 parent 08389dd commit cc5317a
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 1 deletion.
2 changes: 1 addition & 1 deletion kernel/build/patches/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
| Patch file | Description | Upstream status | Link |
|----------------------------------------------------------------------------|--------------------------------------------|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| mpt3sas-ubsan.patch | Backport fixes for UBSAN reporting | in 6.8 | Commit fd7090e384725edb1910a4b0a9c51007858f2c81 |
| blackhole.patch | Backport fixes for blackhole device sending packets without Ethernet header | in 6.14 | Commit 0e4427f8f587c4b603475468bb3aee9418574893 |
89 changes: 89 additions & 0 deletions kernel/build/patches/blackhole.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
From 0e4427f8f587c4b603475468bb3aee9418574893 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <[email protected]>
Date: Thu, 20 Feb 2025 09:25:59 +0200
Subject: net: loopback: Avoid sending IP packets without an Ethernet header

After commit 22600596b675 ("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: 8d7017fd621d ("blackhole_netdev: use blackhole_netdev to invalidate dst entries")
Fixes: 22600596b675 ("ipv4: give an IPv4 dev to blackhole_netdev")
Reported-by: Florian Meister <[email protected]>
Closes: https://lore.kernel.org/netdev/[email protected]/
Signed-off-by: Ido Schimmel <[email protected]>
Reviewed-by: Eric Dumazet <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
---
drivers/net/loopback.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index c8840c3b9a1bc7..f1d68153987e1b 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -244,8 +244,22 @@ static netdev_tx_t blackhole_netdev_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
}

+static int blackhole_neigh_output(struct neighbour *n, struct sk_buff *skb)
+{
+ kfree_skb(skb);
+ return 0;
+}
+
+static int blackhole_neigh_construct(struct net_device *dev,
+ struct neighbour *n)
+{
+ n->output = blackhole_neigh_output;
+ return 0;
+}
+
static const struct net_device_ops blackhole_netdev_ops = {
.ndo_start_xmit = blackhole_netdev_xmit,
+ .ndo_neigh_construct = blackhole_neigh_construct,
};

/* This is a dst-dummy device used specifically for invalidated
--
cgit 1.2.3-korg

1 change: 1 addition & 0 deletions kernel/build/pkg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ steps:
cd /src
for patch in $(find /pkg/patches -type f -name "*.patch" | sort); do
patch -p1 < $patch || (echo "Failed to apply patch $patch" && exit 1)
echo "Applied patch $patch"
done
build:
{{ if .BUILD_ARG_KERNEL_TARGET }}
Expand Down

0 comments on commit cc5317a

Please sign in to comment.