mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 05:04:09 +08:00
net: fix use-after-free in GRO with ESP
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. Commit5f114163f2
("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:5f114163f2
("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>
This commit is contained in:
parent
1236f22fba
commit
603d4cf8fe
@ -476,7 +476,7 @@ static struct sk_buff **geneve_gro_receive(struct sock *sk,
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
out:
|
||||
NAPI_GRO_CB(skb)->flush |= flush;
|
||||
skb_gro_flush_final(skb, pp, flush);
|
||||
|
||||
return pp;
|
||||
}
|
||||
|
@ -623,9 +623,7 @@ static struct sk_buff **vxlan_gro_receive(struct sock *sk,
|
||||
flush = 0;
|
||||
|
||||
out:
|
||||
skb_gro_remcsum_cleanup(skb, &grc);
|
||||
skb->remcsum_offload = 0;
|
||||
NAPI_GRO_CB(skb)->flush |= flush;
|
||||
skb_gro_flush_final_remcsum(skb, pp, flush, &grc);
|
||||
|
||||
return pp;
|
||||
}
|
||||
|
@ -2789,11 +2789,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,
|
||||
|
@ -693,7 +693,7 @@ static struct sk_buff **vlan_gro_receive(struct sk_buff **head,
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
out:
|
||||
NAPI_GRO_CB(skb)->flush |= flush;
|
||||
skb_gro_flush_final(skb, pp, flush);
|
||||
|
||||
return pp;
|
||||
}
|
||||
|
@ -448,9 +448,7 @@ next_proto:
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
out:
|
||||
NAPI_GRO_CB(skb)->flush |= flush;
|
||||
skb_gro_remcsum_cleanup(skb, &grc);
|
||||
skb->remcsum_offload = 0;
|
||||
skb_gro_flush_final_remcsum(skb, pp, flush, &grc);
|
||||
|
||||
return pp;
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head,
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
out:
|
||||
NAPI_GRO_CB(skb)->flush |= flush;
|
||||
skb_gro_flush_final(skb, pp, flush);
|
||||
|
||||
return pp;
|
||||
}
|
||||
|
@ -394,7 +394,7 @@ unflush:
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
out:
|
||||
NAPI_GRO_CB(skb)->flush |= flush;
|
||||
skb_gro_flush_final(skb, pp, flush);
|
||||
return pp;
|
||||
}
|
||||
EXPORT_SYMBOL(udp_gro_receive);
|
||||
|
Loading…
Reference in New Issue
Block a user