diff options
| author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2023-06-14 12:02:02 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-06-28 10:28:11 +0200 |
| commit | b1b9c81e29d2251b3e7c35de9f15a8e9d446c6e4 (patch) | |
| tree | 747f1b7f346fdf3a495aef0324bf1981e48a2db1 | |
| parent | 31cd0d4a4470e28707471dd0f1b746af4d26ebbc (diff) | |
| download | linux-b1b9c81e29d2251b3e7c35de9f15a8e9d446c6e4.tar.gz linux-b1b9c81e29d2251b3e7c35de9f15a8e9d446c6e4.tar.bz2 linux-b1b9c81e29d2251b3e7c35de9f15a8e9d446c6e4.zip | |
xfrm: Linearize the skb after offloading if needed.
[ Upstream commit f015b900bc3285322029b4a7d132d6aeb0e51857 ]
With offloading enabled, esp_xmit() gets invoked very late, from within
validate_xmit_xfrm() which is after validate_xmit_skb() validates and
linearizes the skb if the underlying device does not support fragments.
esp_output_tail() may add a fragment to the skb while adding the auth
tag/ IV. Devices without the proper support will then send skb->data
points to with the correct length so the packet will have garbage at the
end. A pcap sniffer will claim that the proper data has been sent since
it parses the skb properly.
It is not affected with INET_ESP_OFFLOAD disabled.
Linearize the skb after offloading if the sending hardware requires it.
It was tested on v4, v6 has been adopted.
Fixes: 7785bba299a8d ("esp: Add a software GRO codepath")
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
| -rw-r--r-- | net/ipv4/esp4_offload.c | 3 | ||||
| -rw-r--r-- | net/ipv6/esp6_offload.c | 3 |
2 files changed, 6 insertions, 0 deletions
diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c index 84257678160a..dc50764b0180 100644 --- a/net/ipv4/esp4_offload.c +++ b/net/ipv4/esp4_offload.c @@ -338,6 +338,9 @@ static int esp_xmit(struct xfrm_state *x, struct sk_buff *skb, netdev_features_ secpath_reset(skb); + if (skb_needs_linearize(skb, skb->dev->features) && + __skb_linearize(skb)) + return -ENOMEM; return 0; } diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c index 7608be04d0f5..87dbd53c29a6 100644 --- a/net/ipv6/esp6_offload.c +++ b/net/ipv6/esp6_offload.c @@ -372,6 +372,9 @@ static int esp6_xmit(struct xfrm_state *x, struct sk_buff *skb, netdev_features secpath_reset(skb); + if (skb_needs_linearize(skb, skb->dev->features) && + __skb_linearize(skb)) + return -ENOMEM; return 0; } |
