Received: by 10.192.165.148 with SMTP id m20csp779031imm; Fri, 27 Apr 2018 07:23:52 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrR7Tb9HndCO9JeO840XyWeR8VS5lAAtZeqDcxhFcRa+mb2N9HwCDI1Xmx22fkYyenAXFlr X-Received: by 2002:a17:902:7601:: with SMTP id k1-v6mr2461346pll.1.1524839032520; Fri, 27 Apr 2018 07:23:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524839032; cv=none; d=google.com; s=arc-20160816; b=eKaroaOvebzEikSEXoQXMPCo0+gKkcrQb/289oXUx0AhJ4a5brIfSRiQKsiC8oWWmH MfXgWTmTBykWHwpgIJGeSWSpK9YkHq1i2UDL2yChROBzO+PQUTRCP12xggLByawR3bnd HHp9536U3VYkIrWgQSdjte+QvXqDRLvouTIcfVdd81GblgLxbPjizZc8MmIgovbO6PHA 4P28lrThTEieQa/SwAsrOCycdHjv2XV/vZIZaiwbdjcYmju0u3NDz2fKuW2Y//3xeFFn uao0Yr3VRYmEuv5Wf8VD+goO6b7Sx1QCuZyqXdrIgaMsfq+NZuHX001a2t5NYOyOX+xq QPiw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from:dmarc-filter :arc-authentication-results; bh=17mZ6jlgc4NvWJwU7gLZxTU5RHJcSSOKT5DyXqEyd4E=; b=bdGbRszlzXKTbANsmF5+MZM7nC7MUhBNtiYDdJx/Zu4xlyf2WCz+HNsjlY8EdLtfAP 0P94hZsqLCYJKLOz1YNmHXD0f5to+hN3B8F9DZf5E4sMDN2oE7bTJQN+QHzBkSzB93q0 ekxOfPvd+Y/wg/aTpOghDoXb48n8dB2W7ZVibVKfGb1XzusNN6TBxpmlHHuO1SC49yO6 DMNqO0WHcdrF1hO+WbIAi0tBeN/m0jBYC4oFFRGw6lv03/zH/Ue53FhlzPXpIurgdiO3 I9XadTPBXyF6OVcdA995grbmXZ9L30nO0EV2+BTMNnf3y49FRHg8KBv4P7U33JGYZ1x8 M8uA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g17si1334461pfj.349.2018.04.27.07.23.38; Fri, 27 Apr 2018 07:23:52 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935209AbeD0OMd (ORCPT + 99 others); Fri, 27 Apr 2018 10:12:33 -0400 Received: from mail.kernel.org ([198.145.29.99]:57006 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935193AbeD0OM3 (ORCPT ); Fri, 27 Apr 2018 10:12:29 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C33B821895; Fri, 27 Apr 2018 14:12:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C33B821895 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=linuxfoundation.org Authentication-Results: mail.kernel.org; spf=fail smtp.mailfrom=gregkh@linuxfoundation.org From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Alexander Aring , Yotam Gigi , Jamal Hadi Salim , "David S. Miller" Subject: [PATCH 4.16 39/81] net: sched: ife: handle malformed tlv length Date: Fri, 27 Apr 2018 15:58:41 +0200 Message-Id: <20180427135745.362555965@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180427135743.216853156@linuxfoundation.org> References: <20180427135743.216853156@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.16-stable review patch. If anyone has any objections, please let me know. ------------------ From: Alexander Aring [ Upstream commit cc74eddd0ff325d57373cea99f642b787d7f76f5 ] There is currently no handling to check on a invalid tlv length. This patch adds such handling to avoid killing the kernel with a malformed ife packet. Signed-off-by: Alexander Aring Reviewed-by: Yotam Gigi Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/net/ife.h | 3 ++- net/ife/ife.c | 35 +++++++++++++++++++++++++++++++++-- net/sched/act_ife.c | 7 ++++++- 3 files changed, 41 insertions(+), 4 deletions(-) --- a/include/net/ife.h +++ b/include/net/ife.h @@ -12,7 +12,8 @@ void *ife_encode(struct sk_buff *skb, u16 metalen); void *ife_decode(struct sk_buff *skb, u16 *metalen); -void *ife_tlv_meta_decode(void *skbdata, u16 *attrtype, u16 *dlen, u16 *totlen); +void *ife_tlv_meta_decode(void *skbdata, const void *ifehdr_end, u16 *attrtype, + u16 *dlen, u16 *totlen); int ife_tlv_meta_encode(void *skbdata, u16 attrtype, u16 dlen, const void *dval); --- a/net/ife/ife.c +++ b/net/ife/ife.c @@ -92,12 +92,43 @@ struct meta_tlvhdr { __be16 len; }; +static bool __ife_tlv_meta_valid(const unsigned char *skbdata, + const unsigned char *ifehdr_end) +{ + const struct meta_tlvhdr *tlv; + u16 tlvlen; + + if (unlikely(skbdata + sizeof(*tlv) > ifehdr_end)) + return false; + + tlv = (const struct meta_tlvhdr *)skbdata; + tlvlen = ntohs(tlv->len); + + /* tlv length field is inc header, check on minimum */ + if (tlvlen < NLA_HDRLEN) + return false; + + /* overflow by NLA_ALIGN check */ + if (NLA_ALIGN(tlvlen) < tlvlen) + return false; + + if (unlikely(skbdata + NLA_ALIGN(tlvlen) > ifehdr_end)) + return false; + + return true; +} + /* Caller takes care of presenting data in network order */ -void *ife_tlv_meta_decode(void *skbdata, u16 *attrtype, u16 *dlen, u16 *totlen) +void *ife_tlv_meta_decode(void *skbdata, const void *ifehdr_end, u16 *attrtype, + u16 *dlen, u16 *totlen) { - struct meta_tlvhdr *tlv = (struct meta_tlvhdr *) skbdata; + struct meta_tlvhdr *tlv; + + if (!__ife_tlv_meta_valid(skbdata, ifehdr_end)) + return NULL; + tlv = (struct meta_tlvhdr *)skbdata; *dlen = ntohs(tlv->len) - NLA_HDRLEN; *attrtype = ntohs(tlv->type); --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c @@ -682,7 +682,12 @@ static int tcf_ife_decode(struct sk_buff u16 mtype; u16 dlen; - curr_data = ife_tlv_meta_decode(tlv_data, &mtype, &dlen, NULL); + curr_data = ife_tlv_meta_decode(tlv_data, ifehdr_end, &mtype, + &dlen, NULL); + if (!curr_data) { + qstats_drop_inc(this_cpu_ptr(ife->common.cpu_qstats)); + return TC_ACT_SHOT; + } if (find_decode_metaid(skb, ife, mtype, dlen, curr_data)) { /* abuse overlimits to count when we receive metadata