From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Axtens Subject: [PATCH v2 4/4] net: check the size of a packet in validate_xmit_skb Date: Thu, 25 Jan 2018 15:31:09 +1100 Message-ID: <20180125043109.28332-5-dja@axtens.net> References: <20180125043109.28332-1-dja@axtens.net> Cc: Daniel Axtens , Jason Wang , Pravin Shelar , Marcelo Ricardo Leitner , Manish.Chopra@cavium.com, dev@openvswitch.org To: netdev@vger.kernel.org Return-path: Received: from mail-pg0-f66.google.com ([74.125.83.66]:44678 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933369AbeAYEcA (ORCPT ); Wed, 24 Jan 2018 23:32:00 -0500 Received: by mail-pg0-f66.google.com with SMTP id m20so4310209pgc.11 for ; Wed, 24 Jan 2018 20:31:59 -0800 (PST) In-Reply-To: <20180125043109.28332-1-dja@axtens.net> Sender: netdev-owner@vger.kernel.org List-ID: There are a number of paths where an oversize skb could be sent to a driver. The driver should not be required to check for this - the core layer should do it instead. Add a check to validate_xmit_skb that checks both GSO and non-GSO packets and drops them if they are too large. Signed-off-by: Daniel Axtens --- net/core/dev.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 6c96c26aadbf..f09eece2cd21 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1830,13 +1830,11 @@ static inline void net_timestamp_set(struct sk_buff *skb) __net_timestamp(SKB); \ } \ -bool is_skb_forwardable(const struct net_device *dev, const struct sk_buff *skb) +static inline bool skb_mac_len_fits_dev(const struct net_device *dev, + const struct sk_buff *skb) { unsigned int len; - if (!(dev->flags & IFF_UP)) - return false; - len = dev->mtu + dev->hard_header_len + VLAN_HLEN; if (skb->len <= len) return true; @@ -1850,6 +1848,14 @@ bool is_skb_forwardable(const struct net_device *dev, const struct sk_buff *skb) return false; } + +bool is_skb_forwardable(const struct net_device *dev, const struct sk_buff *skb) +{ + if (!(dev->flags & IFF_UP)) + return false; + + return skb_mac_len_fits_dev(dev, skb); +} EXPORT_SYMBOL_GPL(is_skb_forwardable); int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb) @@ -3081,6 +3087,9 @@ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device if (unlikely(!skb)) goto out_null; + if (unlikely(!skb_mac_len_fits_dev(dev, skb))) + goto out_kfree_skb; + if (netif_needs_gso(skb, features)) { struct sk_buff *segs; -- 2.14.1