Received: by 10.192.165.148 with SMTP id m20csp797006imm; Fri, 27 Apr 2018 07:40:26 -0700 (PDT) X-Google-Smtp-Source: AB8JxZo9XsKPPAqnNDKEgrbiAzPoeWBzgU0lbbADMpMvFnc3guu5bOsuQoUXqP+O5UepRE3SdcLZ X-Received: by 2002:a17:902:bf41:: with SMTP id u1-v6mr2568010pls.257.1524840026229; Fri, 27 Apr 2018 07:40:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524840026; cv=none; d=google.com; s=arc-20160816; b=MqwY5z3PK5DX+FfCGSaFBnIXTQS/JUbGL/CqcT48xWya2SXubNA0dwTHduVd3AU3rm 7NfYXhhmw1K4c28CpN9rcOEqSFFT836Kb3wUEf6+JR1fFk0AjCLpuzU7gvxFV3LqVUO9 WlPEjQ6oVx0mVmfIk7Xf1qjTvksX0x6ii9wV3Wa5ECaEa+cjIUJNURxQt6NMKAAwsgAU 1BX2EtrGr6IWn+zbLrX5RryPiv1NW2d3JdIMskXOjYK80N4pSzvQH2rLHfvnvy7s0x2p 5fl80+gBczxHRD6DbR/VDlAacyTbGxrYLJjHjcCCrW/f2bBvLNkEHEbuefaCTvcf0AmH gDnw== 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=vioIWAzm5tRF+B4KNS/NGVs78XuX1n6qe0Z52nRLcP4=; b=nvzOps34Vx2QFjd/oCv01ptIqx1kxEZsePbs7XfiNCFvNcS/vwqpav5ky98FfIYNxv 3EKhHfRdYPlqqLw2aayjb5iCPyejVhIuMJS5COBhtAdG7k2zV0+jwW9mMoVIpI5ejcph 3AgTZJnhght2pgJqFezUO9RQ3AJYXVCH0OPn207kOw4H1FHfGgB9P0Rqin6/m5rE/I+2 OLYJsd3CrOvjcti9ggFmHOVV0+SUu0cDhf2MoeKlS3dcCouCHJRn2rUhaVlhDjX4MN3V le5yog2v1SBe4oGSQtqjeFzF5J2RNUJ85YysOoRjX+J68n/9vg7+B1m7IW8XZqXqFvZt Lfnw== 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 a2si1366960pfa.148.2018.04.27.07.40.11; Fri, 27 Apr 2018 07:40:26 -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 S934795AbeD0OjG (ORCPT + 99 others); Fri, 27 Apr 2018 10:39:06 -0400 Received: from mail.kernel.org ([198.145.29.99]:54522 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934337AbeD0OJF (ORCPT ); Fri, 27 Apr 2018 10:09:05 -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 A701E21892; Fri, 27 Apr 2018 14:09:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A701E21892 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.14 34/80] net: sched: ife: handle malformed tlv length Date: Fri, 27 Apr 2018 15:58:27 +0200 Message-Id: <20180427135734.704177687@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180427135732.928644313@linuxfoundation.org> References: <20180427135732.928644313@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.14-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 @@ -639,7 +639,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