|
Jiri Slaby |
f15162 |
From: Sabrina Dubroca <sd@queasysnail.net>
|
|
Jiri Slaby |
f15162 |
Date: Sat, 30 Jun 2018 17:38:55 +0200
|
|
Jiri Slaby |
f15162 |
Subject: net: fix use-after-free in GRO with ESP
|
|
Jiri Slaby |
f15162 |
Git-commit: 603d4cf8fe095b1ee78f423d514427be507fb513
|
|
Jiri Slaby |
f15162 |
Patch-mainline: v4.18-rc4
|
|
Jiri Slaby |
f15162 |
References: networking-stable-18_07_19
|
|
Jiri Slaby |
f15162 |
|
|
Jiri Slaby |
f15162 |
Since the addition of GRO for ESP, gro_receive can consume the skb and
|
|
Jiri Slaby |
f15162 |
return -EINPROGRESS. In that case, the lower layer GRO handler cannot
|
|
Jiri Slaby |
f15162 |
touch the skb anymore.
|
|
Jiri Slaby |
f15162 |
|
|
Jiri Slaby |
f15162 |
Commit 5f114163f2f5 ("net: Add a skb_gro_flush_final helper.") converted
|
|
Jiri Slaby |
f15162 |
some of the gro_receive handlers that can lead to ESP's gro_receive so
|
|
Jiri Slaby |
f15162 |
that they wouldn't access the skb when -EINPROGRESS is returned, but
|
|
Jiri Slaby |
f15162 |
missed other spots, mainly in tunneling protocols.
|
|
Jiri Slaby |
f15162 |
|
|
Jiri Slaby |
f15162 |
This patch finishes the conversion to using skb_gro_flush_final(), and
|
|
Jiri Slaby |
f15162 |
adds a new helper, skb_gro_flush_final_remcsum(), used in VXLAN and
|
|
Jiri Slaby |
f15162 |
GUE.
|
|
Jiri Slaby |
f15162 |
|
|
Jiri Slaby |
f15162 |
Fixes: 5f114163f2f5 ("net: Add a skb_gro_flush_final helper.")
|
|
Jiri Slaby |
f15162 |
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
|
|
Jiri Slaby |
f15162 |
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
|
|
Jiri Slaby |
f15162 |
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Jiri Slaby |
f15162 |
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
|
Jiri Slaby |
f15162 |
---
|
|
Jiri Slaby |
f15162 |
drivers/net/geneve.c | 2 +-
|
|
Jiri Slaby |
f15162 |
drivers/net/vxlan.c | 4 +---
|
|
Jiri Slaby |
f15162 |
include/linux/netdevice.h | 20 ++++++++++++++++++++
|
|
Jiri Slaby |
f15162 |
net/8021q/vlan.c | 2 +-
|
|
Jiri Slaby |
f15162 |
net/ipv4/fou.c | 4 +---
|
|
Jiri Slaby |
f15162 |
net/ipv4/gre_offload.c | 2 +-
|
|
Jiri Slaby |
f15162 |
net/ipv4/udp_offload.c | 2 +-
|
|
Jiri Slaby |
f15162 |
7 files changed, 26 insertions(+), 10 deletions(-)
|
|
Jiri Slaby |
f15162 |
|
|
Jiri Slaby |
f15162 |
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
|
|
Jiri Slaby |
f15162 |
index 750eaa53bf0c..ada33c2d9ac2 100644
|
|
Jiri Slaby |
f15162 |
--- a/drivers/net/geneve.c
|
|
Jiri Slaby |
f15162 |
+++ b/drivers/net/geneve.c
|
|
Jiri Slaby |
f15162 |
@@ -476,7 +476,7 @@ static struct sk_buff **geneve_gro_receive(struct sock *sk,
|
|
Jiri Slaby |
f15162 |
out_unlock:
|
|
Jiri Slaby |
f15162 |
rcu_read_unlock();
|
|
Jiri Slaby |
f15162 |
out:
|
|
Jiri Slaby |
f15162 |
- NAPI_GRO_CB(skb)->flush |= flush;
|
|
Jiri Slaby |
f15162 |
+ skb_gro_flush_final(skb, pp, flush);
|
|
Jiri Slaby |
f15162 |
|
|
Jiri Slaby |
f15162 |
return pp;
|
|
Jiri Slaby |
f15162 |
}
|
|
Jiri Slaby |
f15162 |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
|
|
Jiri Slaby |
f15162 |
index aee0e60471f1..f6bb1d54d4bd 100644
|
|
Jiri Slaby |
f15162 |
--- a/drivers/net/vxlan.c
|
|
Jiri Slaby |
f15162 |
+++ b/drivers/net/vxlan.c
|
|
Jiri Slaby |
f15162 |
@@ -623,9 +623,7 @@ static struct sk_buff **vxlan_gro_receive(struct sock *sk,
|
|
Jiri Slaby |
f15162 |
flush = 0;
|
|
Jiri Slaby |
f15162 |
|
|
Jiri Slaby |
f15162 |
out:
|
|
Jiri Slaby |
f15162 |
- skb_gro_remcsum_cleanup(skb, &grc;;
|
|
Jiri Slaby |
f15162 |
- skb->remcsum_offload = 0;
|
|
Jiri Slaby |
f15162 |
- NAPI_GRO_CB(skb)->flush |= flush;
|
|
Jiri Slaby |
f15162 |
+ skb_gro_flush_final_remcsum(skb, pp, flush, &grc;;
|
|
Jiri Slaby |
f15162 |
|
|
Jiri Slaby |
f15162 |
return pp;
|
|
Jiri Slaby |
f15162 |
}
|
|
Jiri Slaby |
f15162 |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
|
|
Jiri Slaby |
f15162 |
index 3ec9850c7936..3d0cc0b5cec2 100644
|
|
Jiri Slaby |
f15162 |
--- a/include/linux/netdevice.h
|
|
Jiri Slaby |
f15162 |
+++ b/include/linux/netdevice.h
|
|
Jiri Slaby |
f15162 |
@@ -2789,11 +2789,31 @@ static inline void skb_gro_flush_final(struct sk_buff *skb, struct sk_buff **pp,
|
|
Jiri Slaby |
f15162 |
if (PTR_ERR(pp) != -EINPROGRESS)
|
|
Jiri Slaby |
f15162 |
NAPI_GRO_CB(skb)->flush |= flush;
|
|
Jiri Slaby |
f15162 |
}
|
|
Jiri Slaby |
f15162 |
+static inline void skb_gro_flush_final_remcsum(struct sk_buff *skb,
|
|
Jiri Slaby |
f15162 |
+ struct sk_buff **pp,
|
|
Jiri Slaby |
f15162 |
+ int flush,
|
|
Jiri Slaby |
f15162 |
+ struct gro_remcsum *grc)
|
|
Jiri Slaby |
f15162 |
+{
|
|
Jiri Slaby |
f15162 |
+ if (PTR_ERR(pp) != -EINPROGRESS) {
|
|
Jiri Slaby |
f15162 |
+ NAPI_GRO_CB(skb)->flush |= flush;
|
|
Jiri Slaby |
f15162 |
+ skb_gro_remcsum_cleanup(skb, grc);
|
|
Jiri Slaby |
f15162 |
+ skb->remcsum_offload = 0;
|
|
Jiri Slaby |
f15162 |
+ }
|
|
Jiri Slaby |
f15162 |
+}
|
|
Jiri Slaby |
f15162 |
#else
|
|
Jiri Slaby |
f15162 |
static inline void skb_gro_flush_final(struct sk_buff *skb, struct sk_buff **pp, int flush)
|
|
Jiri Slaby |
f15162 |
{
|
|
Jiri Slaby |
f15162 |
NAPI_GRO_CB(skb)->flush |= flush;
|
|
Jiri Slaby |
f15162 |
}
|
|
Jiri Slaby |
f15162 |
+static inline void skb_gro_flush_final_remcsum(struct sk_buff *skb,
|
|
Jiri Slaby |
f15162 |
+ struct sk_buff **pp,
|
|
Jiri Slaby |
f15162 |
+ int flush,
|
|
Jiri Slaby |
f15162 |
+ struct gro_remcsum *grc)
|
|
Jiri Slaby |
f15162 |
+{
|
|
Jiri Slaby |
f15162 |
+ NAPI_GRO_CB(skb)->flush |= flush;
|
|
Jiri Slaby |
f15162 |
+ skb_gro_remcsum_cleanup(skb, grc);
|
|
Jiri Slaby |
f15162 |
+ skb->remcsum_offload = 0;
|
|
Jiri Slaby |
f15162 |
+}
|
|
Jiri Slaby |
f15162 |
#endif
|
|
Jiri Slaby |
f15162 |
|
|
Jiri Slaby |
f15162 |
static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
|
|
Jiri Slaby |
f15162 |
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
|
|
Jiri Slaby |
f15162 |
index 73a65789271b..8ccee3d01822 100644
|
|
Jiri Slaby |
f15162 |
--- a/net/8021q/vlan.c
|
|
Jiri Slaby |
f15162 |
+++ b/net/8021q/vlan.c
|
|
Jiri Slaby |
f15162 |
@@ -693,7 +693,7 @@ static struct sk_buff **vlan_gro_receive(struct sk_buff **head,
|
|
Jiri Slaby |
f15162 |
out_unlock:
|
|
Jiri Slaby |
f15162 |
rcu_read_unlock();
|
|
Jiri Slaby |
f15162 |
out:
|
|
Jiri Slaby |
f15162 |
- NAPI_GRO_CB(skb)->flush |= flush;
|
|
Jiri Slaby |
f15162 |
+ skb_gro_flush_final(skb, pp, flush);
|
|
Jiri Slaby |
f15162 |
|
|
Jiri Slaby |
f15162 |
return pp;
|
|
Jiri Slaby |
f15162 |
}
|
|
Jiri Slaby |
f15162 |
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
|
|
Jiri Slaby |
f15162 |
index 1540db65241a..c9ec1603666b 100644
|
|
Jiri Slaby |
f15162 |
--- a/net/ipv4/fou.c
|
|
Jiri Slaby |
f15162 |
+++ b/net/ipv4/fou.c
|
|
Jiri Slaby |
f15162 |
@@ -448,9 +448,7 @@ static struct sk_buff **gue_gro_receive(struct sock *sk,
|
|
Jiri Slaby |
f15162 |
out_unlock:
|
|
Jiri Slaby |
f15162 |
rcu_read_unlock();
|
|
Jiri Slaby |
f15162 |
out:
|
|
Jiri Slaby |
f15162 |
- NAPI_GRO_CB(skb)->flush |= flush;
|
|
Jiri Slaby |
f15162 |
- skb_gro_remcsum_cleanup(skb, &grc;;
|
|
Jiri Slaby |
f15162 |
- skb->remcsum_offload = 0;
|
|
Jiri Slaby |
f15162 |
+ skb_gro_flush_final_remcsum(skb, pp, flush, &grc;;
|
|
Jiri Slaby |
f15162 |
|
|
Jiri Slaby |
f15162 |
return pp;
|
|
Jiri Slaby |
f15162 |
}
|
|
Jiri Slaby |
f15162 |
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
|
|
Jiri Slaby |
f15162 |
index 1859c473b21a..6a7d980105f6 100644
|
|
Jiri Slaby |
f15162 |
--- a/net/ipv4/gre_offload.c
|
|
Jiri Slaby |
f15162 |
+++ b/net/ipv4/gre_offload.c
|
|
Jiri Slaby |
f15162 |
@@ -223,7 +223,7 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head,
|
|
Jiri Slaby |
f15162 |
out_unlock:
|
|
Jiri Slaby |
f15162 |
rcu_read_unlock();
|
|
Jiri Slaby |
f15162 |
out:
|
|
Jiri Slaby |
f15162 |
- NAPI_GRO_CB(skb)->flush |= flush;
|
|
Jiri Slaby |
f15162 |
+ skb_gro_flush_final(skb, pp, flush);
|
|
Jiri Slaby |
f15162 |
|
|
Jiri Slaby |
f15162 |
return pp;
|
|
Jiri Slaby |
f15162 |
}
|
|
Jiri Slaby |
f15162 |
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
|
|
Jiri Slaby |
f15162 |
index 92dc9e5a7ff3..69c54540d5b4 100644
|
|
Jiri Slaby |
f15162 |
--- a/net/ipv4/udp_offload.c
|
|
Jiri Slaby |
f15162 |
+++ b/net/ipv4/udp_offload.c
|
|
Jiri Slaby |
f15162 |
@@ -394,7 +394,7 @@ struct sk_buff **udp_gro_receive(struct sk_buff **head, struct sk_buff *skb,
|
|
Jiri Slaby |
f15162 |
out_unlock:
|
|
Jiri Slaby |
f15162 |
rcu_read_unlock();
|
|
Jiri Slaby |
f15162 |
out:
|
|
Jiri Slaby |
f15162 |
- NAPI_GRO_CB(skb)->flush |= flush;
|
|
Jiri Slaby |
f15162 |
+ skb_gro_flush_final(skb, pp, flush);
|
|
Jiri Slaby |
f15162 |
return pp;
|
|
Jiri Slaby |
f15162 |
}
|
|
Jiri Slaby |
f15162 |
EXPORT_SYMBOL(udp_gro_receive);
|
|
Jiri Slaby |
f15162 |
--
|
|
Jiri Slaby |
f15162 |
2.18.0
|
|
Jiri Slaby |
f15162 |
|