From mboxrd@z Thu Jan 1 00:00:00 1970 From: Cong Wang Subject: [Patch net] mlx5: check for malformed packets Date: Sat, 1 Dec 2018 12:38:36 -0800 Message-ID: <20181201203837.3306-1-xiyou.wangcong@gmail.com> Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Cc: Cong Wang , Tariq Toukan , Saeed Mahameed To: netdev@vger.kernel.org Return-path: Received: from mail-pf1-f193.google.com ([209.85.210.193]:38958 "EHLO mail-pf1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725726AbeLBHwM (ORCPT ); Sun, 2 Dec 2018 02:52:12 -0500 Received: by mail-pf1-f193.google.com with SMTP id c72so4458658pfc.6 for ; Sat, 01 Dec 2018 12:38:50 -0800 (PST) Sender: netdev-owner@vger.kernel.org List-ID: is_last_ethertype_ip() is used to check IP/IPv6 protocol before parsing IP/IPv6 headers. But __vlan_get_protocol() is only bound to skb->len, a malicious packet could exhaust all skb->len by inserting sufficient ETH_P_8021AD headers, and it may not even contain an IP/IPv6 header at all, so we have to check if we are still safe to continue to parse IP/IPv6 header. If not, treat it as non-IP packet. This should not cause any crash as we stil have tail room in skb, but we can't just rely on it either. Cc: Tariq Toukan Cc: Saeed Mahameed Signed-off-by: Cong Wang --- drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index 624eed345b5d..1e505013ebfd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c @@ -693,7 +693,18 @@ static inline bool is_last_ethertype_ip(struct sk_buff *skb, int *network_depth, { *proto = ((struct ethhdr *)skb->data)->h_proto; *proto = __vlan_get_protocol(skb, *proto, network_depth); - return (*proto == htons(ETH_P_IP) || *proto == htons(ETH_P_IPV6)); + + if (*proto == htons(ETH_P_IP)) { + if (unlikely(*network_depth > skb->len - sizeof(struct iphdr))) + return false; + return true; + } else if (*proto == htons(ETH_P_IPV6)) { + if (unlikely(*network_depth > skb->len - sizeof(struct ipv6hdr))) + return false; + return true; + } + + return false; } static inline void mlx5e_enable_ecn(struct mlx5e_rq *rq, struct sk_buff *skb) -- 2.19.1