Skip to content

Commit 603d4cf

Browse files
qsndavem330
authored andcommitted
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. Commit 5f11416 ("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: 5f11416 ("net: Add a skb_gro_flush_final helper.") Signed-off-by: Sabrina Dubroca <[email protected]> Reviewed-by: Stefano Brivio <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1236f22 commit 603d4cf

File tree

7 files changed

+26
-10
lines changed

7 files changed

+26
-10
lines changed

drivers/net/geneve.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ static struct sk_buff **geneve_gro_receive(struct sock *sk,
476476
out_unlock:
477477
rcu_read_unlock();
478478
out:
479-
NAPI_GRO_CB(skb)->flush |= flush;
479+
skb_gro_flush_final(skb, pp, flush);
480480

481481
return pp;
482482
}

drivers/net/vxlan.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,9 +623,7 @@ static struct sk_buff **vxlan_gro_receive(struct sock *sk,
623623
flush = 0;
624624

625625
out:
626-
skb_gro_remcsum_cleanup(skb, &grc);
627-
skb->remcsum_offload = 0;
628-
NAPI_GRO_CB(skb)->flush |= flush;
626+
skb_gro_flush_final_remcsum(skb, pp, flush, &grc);
629627

630628
return pp;
631629
}

include/linux/netdevice.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,11 +2789,31 @@ static inline void skb_gro_flush_final(struct sk_buff *skb, struct sk_buff **pp,
27892789
if (PTR_ERR(pp) != -EINPROGRESS)
27902790
NAPI_GRO_CB(skb)->flush |= flush;
27912791
}
2792+
static inline void skb_gro_flush_final_remcsum(struct sk_buff *skb,
2793+
struct sk_buff **pp,
2794+
int flush,
2795+
struct gro_remcsum *grc)
2796+
{
2797+
if (PTR_ERR(pp) != -EINPROGRESS) {
2798+
NAPI_GRO_CB(skb)->flush |= flush;
2799+
skb_gro_remcsum_cleanup(skb, grc);
2800+
skb->remcsum_offload = 0;
2801+
}
2802+
}
27922803
#else
27932804
static inline void skb_gro_flush_final(struct sk_buff *skb, struct sk_buff **pp, int flush)
27942805
{
27952806
NAPI_GRO_CB(skb)->flush |= flush;
27962807
}
2808+
static inline void skb_gro_flush_final_remcsum(struct sk_buff *skb,
2809+
struct sk_buff **pp,
2810+
int flush,
2811+
struct gro_remcsum *grc)
2812+
{
2813+
NAPI_GRO_CB(skb)->flush |= flush;
2814+
skb_gro_remcsum_cleanup(skb, grc);
2815+
skb->remcsum_offload = 0;
2816+
}
27972817
#endif
27982818

27992819
static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,

net/8021q/vlan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ static struct sk_buff **vlan_gro_receive(struct sk_buff **head,
693693
out_unlock:
694694
rcu_read_unlock();
695695
out:
696-
NAPI_GRO_CB(skb)->flush |= flush;
696+
skb_gro_flush_final(skb, pp, flush);
697697

698698
return pp;
699699
}

net/ipv4/fou.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -448,9 +448,7 @@ static struct sk_buff **gue_gro_receive(struct sock *sk,
448448
out_unlock:
449449
rcu_read_unlock();
450450
out:
451-
NAPI_GRO_CB(skb)->flush |= flush;
452-
skb_gro_remcsum_cleanup(skb, &grc);
453-
skb->remcsum_offload = 0;
451+
skb_gro_flush_final_remcsum(skb, pp, flush, &grc);
454452

455453
return pp;
456454
}

net/ipv4/gre_offload.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head,
223223
out_unlock:
224224
rcu_read_unlock();
225225
out:
226-
NAPI_GRO_CB(skb)->flush |= flush;
226+
skb_gro_flush_final(skb, pp, flush);
227227

228228
return pp;
229229
}

net/ipv4/udp_offload.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ struct sk_buff **udp_gro_receive(struct sk_buff **head, struct sk_buff *skb,
394394
out_unlock:
395395
rcu_read_unlock();
396396
out:
397-
NAPI_GRO_CB(skb)->flush |= flush;
397+
skb_gro_flush_final(skb, pp, flush);
398398
return pp;
399399
}
400400
EXPORT_SYMBOL(udp_gro_receive);

0 commit comments

Comments
 (0)