summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorSabrina Dubroca <sd@queasysnail.net>2018-06-30 17:38:55 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-07-22 15:15:59 +0200
commitbeff4d81c5472ba11f9ed0db0e273a4cf9314583 (patch)
tree045453fa22ce9260f5efa0af205fe1bdbd65e0bc /include
parenteb895b632c92a58f0d7bbdbd1c26a47da51ea74a (diff)
downloadlinux-stable-beff4d81c5472ba11f9ed0db0e273a4cf9314583.tar.gz
linux-stable-beff4d81c5472ba11f9ed0db0e273a4cf9314583.tar.bz2
linux-stable-beff4d81c5472ba11f9ed0db0e273a4cf9314583.zip
net: fix use-after-free in GRO with ESP
[ Upstream commit 603d4cf8fe095b1ee78f423d514427be507fb513 ] Since the addition of GRO for ESP, gro_receive can consume the skb and return -EINPROGRESS. In that case, the lower layer GRO handler cannot touch the skb anymore. Commit 5f114163f2f5 ("net: Add a skb_gro_flush_final helper.") converted some of the gro_receive handlers that can lead to ESP's gro_receive so that they wouldn't access the skb when -EINPROGRESS is returned, but missed other spots, mainly in tunneling protocols. This patch finishes the conversion to using skb_gro_flush_final(), and adds a new helper, skb_gro_flush_final_remcsum(), used in VXLAN and GUE. Fixes: 5f114163f2f5 ("net: Add a skb_gro_flush_final helper.") Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Reviewed-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/netdevice.h20
1 files changed, 20 insertions, 0 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index cf44503ea81a..5ad916d31471 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2735,11 +2735,31 @@ static inline void skb_gro_flush_final(struct sk_buff *skb, struct sk_buff **pp,
if (PTR_ERR(pp) != -EINPROGRESS)
NAPI_GRO_CB(skb)->flush |= flush;
}
+static inline void skb_gro_flush_final_remcsum(struct sk_buff *skb,
+ struct sk_buff **pp,
+ int flush,
+ struct gro_remcsum *grc)
+{
+ if (PTR_ERR(pp) != -EINPROGRESS) {
+ NAPI_GRO_CB(skb)->flush |= flush;
+ skb_gro_remcsum_cleanup(skb, grc);
+ skb->remcsum_offload = 0;
+ }
+}
#else
static inline void skb_gro_flush_final(struct sk_buff *skb, struct sk_buff **pp, int flush)
{
NAPI_GRO_CB(skb)->flush |= flush;
}
+static inline void skb_gro_flush_final_remcsum(struct sk_buff *skb,
+ struct sk_buff **pp,
+ int flush,
+ struct gro_remcsum *grc)
+{
+ NAPI_GRO_CB(skb)->flush |= flush;
+ skb_gro_remcsum_cleanup(skb, grc);
+ skb->remcsum_offload = 0;
+}
#endif
static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,