Message ID | 1485886832.6360.133.camel@edumazet-glaptop3.roam.corp.google.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Eric Dumazet <eric.dumazet@gmail.com> Date: Tue, 31 Jan 2017 10:20:32 -0800 > From: Eric Dumazet <edumazet@google.com> > > Dmitry reported warnings occurring in __skb_gso_segment() [1] > > All SKB_GSO_DODGY producers can allow user space to feed > packets that trigger the current check. > > We could prevent them from doing so, rejecting packets, but > this might add regressions to existing programs. > > It turns out our SKB_GSO_DODGY handlers properly set up checksum > information that is needed anyway when packets needs to be segmented. > > By checking again skb_needs_check() after skb_mac_gso_segment(), > we should remove these pesky warnings, at a very minor cost. > > With help from Willem de Bruijn ... > Signed-off-by: Eric Dumazet <edumazet@google.com> > Reported-by: Dmitry Vyukov <dvyukov@google.com> > Cc: Willem de Bruijn <willemb@google.com> Applied, thanks Eric.
diff --git a/net/core/dev.c b/net/core/dev.c index be11abac89b3e6ce3013a6b905a268eaf4685609..6fe3d6f51e0a3fb421d6c63d6d20a3f46c408e93 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2658,11 +2658,12 @@ static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path) struct sk_buff *__skb_gso_segment(struct sk_buff *skb, netdev_features_t features, bool tx_path) { + struct sk_buff *segs; + if (unlikely(skb_needs_check(skb, tx_path))) { int err; - skb_warn_bad_offload(skb); - + /* We're going to init ->check field in TCP or UDP header */ err = skb_cow_head(skb, 0); if (err < 0) return ERR_PTR(err); @@ -2690,7 +2691,12 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb, skb_reset_mac_header(skb); skb_reset_mac_len(skb); - return skb_mac_gso_segment(skb, features); + segs = skb_mac_gso_segment(skb, features); + + if (unlikely(skb_needs_check(skb, tx_path))) + skb_warn_bad_offload(skb); + + return segs; } EXPORT_SYMBOL(__skb_gso_segment);