Received: by 10.213.65.68 with SMTP id h4csp1674203imn; Mon, 19 Mar 2018 10:13:32 -0700 (PDT) X-Google-Smtp-Source: AG47ELuWrZD0tgHVbLYnf/cOQsLAjvxx0Acgqq23055JJGuO6YKrsuCLGN2FmP3FjIki037SytMD X-Received: by 10.99.156.17 with SMTP id f17mr9668490pge.102.1521479612073; Mon, 19 Mar 2018 10:13:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521479612; cv=none; d=google.com; s=arc-20160816; b=GaqWb/IZMZKg90ktrgnXoQwmqPmKtxnClCKwX0CMQFBRtstCnrfy73bM7+a+uFIWae P9kCjA0+QTwayLw/KOHBj4H2K0yVXdRvuu5zVzBiYZV6T9d53jATwZOncBNVsu2Jd/MC /13ilPvhZXuFzXF2yi/9Wk8CmHHiH/XKLU68UhMXwn84ZyFAcvrwiomq8vBlaYH8wuE0 2P5zgnrE0SalpIr0gXpEh6lQJQG9IXLZ51EoL9QewF/nY0Fj2deErQo7tQbDxoEvYfz1 udPJK4wId8qq1XC8sBzOYHFSrGkv/oJOTUiEgI88rxI1b5DMacYmHU640RdzVcI2+rNL iR7A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:content-transfer-encoding :spamdiagnosticmetadata:spamdiagnosticoutput:content-language :accept-language:in-reply-to:references:message-id:date:thread-index :thread-topic:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=1O0BNp6d6TqsPyruCSHEcXQq99WsGMltaG5ijaENWM4=; b=HlCW2PGKwH2Uk5N0XSdbws69UdlZ3Tf/NimZP3BOI1STCnDOwVECPAE99iRMW6WL5m BQaCIB3urQuC9ZnNCwXNq5pf3vg1gUrkE1MBLYU9C69rF14AVGjpKbw5vWZuquM8z9n7 4if2gOBdk8l0/FgcTUYiAbg8Ba5IeEfFEbM1b7tctWuBcdDoKtpMVp+5cgsw4TEPEsaU IuGsdrTXcK4K0IHOf6JM7wJHWrAsMaCHlPvhMWYsYAtWlUGK/6pnPN3mNUr0qmOqaEMj OBtDO2mcqDxXLwarQoKWv6titQ2HZ38/YCJKKM2b/Ofr/GdheT8uvBcrx9FTrf8tGeja 5Rig== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@microsoft.com header.s=selector1 header.b=T6cUP3/G; 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; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=microsoft.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r68si256717pfi.413.2018.03.19.10.13.17; Mon, 19 Mar 2018 10:13:32 -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; dkim=pass header.i=@microsoft.com header.s=selector1 header.b=T6cUP3/G; 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; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=microsoft.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S967704AbeCSRMO (ORCPT + 99 others); Mon, 19 Mar 2018 13:12:14 -0400 Received: from mail-bn3nam01on0125.outbound.protection.outlook.com ([104.47.33.125]:62326 "EHLO NAM01-BN3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S966255AbeCSQKg (ORCPT ); Mon, 19 Mar 2018 12:10:36 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=1O0BNp6d6TqsPyruCSHEcXQq99WsGMltaG5ijaENWM4=; b=T6cUP3/G1qptpjd5bhTU55HwIgaRmASh+plbDaqBbOt5xtgL62YEJUIGjoWF+KaavfR3KzSrh0FCY3+xDJ8dFN7sAgwFo3RjVZbubOwF4PfbdrvC3JdEvXBELUH/AhGbkCatdRAVGESF5bDcvJwcU6+mADQB1NeB14ZaCKf7wQE= Received: from DM5PR2101MB1032.namprd21.prod.outlook.com (52.132.128.13) by DM5PR2101MB1045.namprd21.prod.outlook.com (52.132.128.14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.631.0; Mon, 19 Mar 2018 16:10:34 +0000 Received: from DM5PR2101MB1032.namprd21.prod.outlook.com ([fe80::3d9b:79e7:94eb:5d62]) by DM5PR2101MB1032.namprd21.prod.outlook.com ([fe80::3d9b:79e7:94eb:5d62%5]) with mapi id 15.20.0631.004; Mon, 19 Mar 2018 16:10:33 +0000 From: Sasha Levin To: "linux-kernel@vger.kernel.org" , "stable@vger.kernel.org" CC: "Jason A. Donenfeld" , Steffen Klassert , Herbert Xu , "David S. Miller" , David Howells , Sabrina Dubroca , "Michael S. Tsirkin" , Jason Wang , Sasha Levin Subject: [PATCH AUTOSEL for 4.4 121/167] skbuff: return -EMSGSIZE in skb_to_sgvec to prevent overflow Thread-Topic: [PATCH AUTOSEL for 4.4 121/167] skbuff: return -EMSGSIZE in skb_to_sgvec to prevent overflow Thread-Index: AQHTv5xwvtKs8cK1nEqevVHrbU0ZYA== Date: Mon, 19 Mar 2018 16:07:54 +0000 Message-ID: <20180319160513.16384-121-alexander.levin@microsoft.com> References: <20180319160513.16384-1-alexander.levin@microsoft.com> In-Reply-To: <20180319160513.16384-1-alexander.levin@microsoft.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [52.168.54.252] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1;DM5PR2101MB1045;7:qgEHI6uT3G6Deb9XkDX+KsIMwaWQ/JMC9AhpShFShS5VZJRRI5NNOm9WEpz+jAESLw+Sztanp2HGLPf5XmHrKs9d25TTu2ABflKwtcI/mCKSOyMPv8hVdcP9dECoH2x4KR9bDtEVEH3lQqfOATcreVSv+STpjx7i3+/xOy2B25Boa9XBMEuUI7/JGipTlQeXTPTrM6UCgVXvC3jIFbFUSqu7/aLajkCsjJdjHzBvJhbhNbzL/R2299PaQZH4SJ6J;20:66+/pE9Qe5hw/Kdj+WwY8/vHgGvL5THTzNomnSethZ8gopQoGbzwFNoU6QGkvVL4ZqgENKT9MffaALb7NFTUs2jU9khJ2kY4V/gz4E27+mRNDqqh8uuNEp1+kj0M6utXHX/58ornhs9Hxrkjde/kG7YKvdDR6XW1ZU3FNjAf3S4= x-ms-office365-filtering-ht: Tenant x-ms-office365-filtering-correlation-id: 2fc801f1-6156-4591-3948-08d58db3f1e6 x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:(7020095)(4652020)(48565401081)(5600026)(4604075)(3008032)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7193020);SRVR:DM5PR2101MB1045; x-ms-traffictypediagnostic: DM5PR2101MB1045: authentication-results: spf=none (sender IP is ) smtp.mailfrom=Alexander.Levin@microsoft.com; x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(28532068793085)(89211679590171); x-exchange-antispam-report-cfa-test: BCL:0;PCL:0;RULEID:(8211001083)(61425038)(6040522)(2401047)(5005006)(8121501046)(3231221)(944501300)(52105095)(3002001)(93006095)(93001095)(10201501046)(6055026)(61426038)(61427038)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123562045)(20161123564045)(20161123558120)(6072148)(201708071742011);SRVR:DM5PR2101MB1045;BCL:0;PCL:0;RULEID:;SRVR:DM5PR2101MB1045; x-forefront-prvs: 06167FAD59 x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(346002)(376002)(366004)(39380400002)(39860400002)(396003)(199004)(189003)(86612001)(66066001)(6436002)(76176011)(5890100001)(10290500003)(6666003)(2950100002)(305945005)(8676002)(97736004)(6486002)(86362001)(25786009)(26005)(575784001)(102836004)(8936002)(6512007)(7736002)(3280700002)(106356001)(107886003)(110136005)(68736007)(81156014)(22452003)(6506007)(186003)(54906003)(10090500001)(2900100001)(4326008)(2906002)(14454004)(81166006)(316002)(105586002)(6116002)(3846002)(5660300001)(36756003)(72206003)(1076002)(59450400001)(53936002)(7416002)(3660700001)(99286004)(2501003)(5250100002)(478600001)(22906009)(217873001);DIR:OUT;SFP:1102;SCL:1;SRVR:DM5PR2101MB1045;H:DM5PR2101MB1032.namprd21.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;A:1;MX:1; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: urX0wXq49G66dOw5ikHjlAt7KavbRMTVX8Jv+Nv+b4gdbVUvrutfKCJsAFdCyOZjqG30OTTdPy4K5vDLNZBmCjC6pKUPpmBdUmwxxjiD8M5xpMz1a1+AGEcGV7ugVRxOi6eHF4zq9H6uMpSwWJtaMCFoeT731t3pnIlqGeUDhXw9Am1ZtFjdw4JAiMokVfzRsn1SLNOwJEH8y23zvPoqOiGKW9aI3KPBn7RwPfx66Tg5Ii+mPl6rmSKdKL0DLWbfjcwidCYMT4NgwTD2fr2/gaoMkuMeQ92sAFf9809XwxTnNG5/RH0NKtnLFji45gDl9O1tgUBRHSUvARWi1/Jyhw== spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2fc801f1-6156-4591-3948-08d58db3f1e6 X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Mar 2018 16:07:54.3371 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR2101MB1045 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Jason A. Donenfeld" [ Upstream commit 48a1df65334b74bd7531f932cca5928932abf769 ] This is a defense-in-depth measure in response to bugs like 4d6fa57b4dab ("macsec: avoid heap overflow in skb_to_sgvec"). There's not only a potential overflow of sglist items, but also a stack overflow potential, so we fix this by limiting the amount of recursion this function is allowed to do. Not actually providing a bounded base case is a future disaster that we can easily avoid here. As a small matter of house keeping, we take this opportunity to move the documentation comment over the actual function the documentation is for. While this could be implemented by using an explicit stack of skbuffs, when implementing this, the function complexity increased considerably, and I don't think such complexity and bloat is actually worth it. So, instead I built this and tested it on x86, x86_64, ARM, ARM64, and MIPS, and measured the stack usage there. I also reverted the recent MIPS changes that give it a separate IRQ stack, so that I could experience some worst-case situations. I found that limiting it to 24 layers deep yielded a good stack usage with room for safety, as well as being much deeper than any driver actually ever creates. Signed-off-by: Jason A. Donenfeld Cc: Steffen Klassert Cc: Herbert Xu Cc: "David S. Miller" Cc: David Howells Cc: Sabrina Dubroca Cc: "Michael S. Tsirkin" Cc: Jason Wang Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/linux/skbuff.h | 8 +++---- net/core/skbuff.c | 65 ++++++++++++++++++++++++++++++++--------------= ---- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index b5421f6f155a..a6da214d0584 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -879,10 +879,10 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *= skb, unsigned int headroom); struct sk_buff *skb_copy_expand(const struct sk_buff *skb, int newheadroom= , int newtailroom, gfp_t priority); -int skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg, - int offset, int len); -int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, - int len); +int __must_check skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterli= st *sg, + int offset, int len); +int __must_check skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, + int offset, int len); int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trail= er); int skb_pad(struct sk_buff *skb, int pad); #define dev_kfree_skb(a) consume_skb(a) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 86b619501350..02f0a705ee96 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3329,24 +3329,18 @@ void __init skb_init(void) NULL); } =20 -/** - * skb_to_sgvec - Fill a scatter-gather list from a socket buffer - * @skb: Socket buffer containing the buffers to be mapped - * @sg: The scatter-gather list to map into - * @offset: The offset into the buffer's contents to start mapping - * @len: Length of buffer space to be mapped - * - * Fill the specified scatter-gather list with mappings/pointers into a - * region of the buffer space attached to a socket buffer. - */ static int -__skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, in= t len) +__skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, in= t len, + unsigned int recursion_level) { int start =3D skb_headlen(skb); int i, copy =3D start - offset; struct sk_buff *frag_iter; int elt =3D 0; =20 + if (unlikely(recursion_level >=3D 24)) + return -EMSGSIZE; + if (copy > 0) { if (copy > len) copy =3D len; @@ -3365,6 +3359,8 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlis= t *sg, int offset, int len) end =3D start + skb_frag_size(&skb_shinfo(skb)->frags[i]); if ((copy =3D end - offset) > 0) { skb_frag_t *frag =3D &skb_shinfo(skb)->frags[i]; + if (unlikely(elt && sg_is_last(&sg[elt - 1]))) + return -EMSGSIZE; =20 if (copy > len) copy =3D len; @@ -3379,16 +3375,22 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterl= ist *sg, int offset, int len) } =20 skb_walk_frags(skb, frag_iter) { - int end; + int end, ret; =20 WARN_ON(start > offset + len); =20 end =3D start + frag_iter->len; if ((copy =3D end - offset) > 0) { + if (unlikely(elt && sg_is_last(&sg[elt - 1]))) + return -EMSGSIZE; + if (copy > len) copy =3D len; - elt +=3D __skb_to_sgvec(frag_iter, sg+elt, offset - start, - copy); + ret =3D __skb_to_sgvec(frag_iter, sg+elt, offset - start, + copy, recursion_level + 1); + if (unlikely(ret < 0)) + return ret; + elt +=3D ret; if ((len -=3D copy) =3D=3D 0) return elt; offset +=3D copy; @@ -3399,6 +3401,31 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterli= st *sg, int offset, int len) return elt; } =20 +/** + * skb_to_sgvec - Fill a scatter-gather list from a socket buffer + * @skb: Socket buffer containing the buffers to be mapped + * @sg: The scatter-gather list to map into + * @offset: The offset into the buffer's contents to start mapping + * @len: Length of buffer space to be mapped + * + * Fill the specified scatter-gather list with mappings/pointers into a + * region of the buffer space attached to a socket buffer. Returns either + * the number of scatterlist items used, or -EMSGSIZE if the contents + * could not fit. + */ +int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, = int len) +{ + int nsg =3D __skb_to_sgvec(skb, sg, offset, len, 0); + + if (nsg <=3D 0) + return nsg; + + sg_mark_end(&sg[nsg - 1]); + + return nsg; +} +EXPORT_SYMBOL_GPL(skb_to_sgvec); + /* As compared with skb_to_sgvec, skb_to_sgvec_nomark only map skb to give= n * sglist without mark the sg which contain last skb data as the end. * So the caller can mannipulate sg list as will when padding new data aft= er @@ -3421,19 +3448,11 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterl= ist *sg, int offset, int len) int skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) { - return __skb_to_sgvec(skb, sg, offset, len); + return __skb_to_sgvec(skb, sg, offset, len, 0); } EXPORT_SYMBOL_GPL(skb_to_sgvec_nomark); =20 -int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, = int len) -{ - int nsg =3D __skb_to_sgvec(skb, sg, offset, len); =20 - sg_mark_end(&sg[nsg - 1]); - - return nsg; -} -EXPORT_SYMBOL_GPL(skb_to_sgvec); =20 /** * skb_cow_data - Check that a socket buffer's data buffers are writable --=20 2.14.1