summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2023-06-14 12:02:02 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-06-28 10:28:11 +0200
commitb1b9c81e29d2251b3e7c35de9f15a8e9d446c6e4 (patch)
tree747f1b7f346fdf3a495aef0324bf1981e48a2db1
parent31cd0d4a4470e28707471dd0f1b746af4d26ebbc (diff)
downloadlinux-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.c3
-rw-r--r--net/ipv6/esp6_offload.c3
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;
}