From mboxrd@z Thu Jan 1 00:00:00 1970 From: Al Viro Subject: Re: [PATCH] net: sched: Fix memory exposure from short TCA_U32_SEL Date: Sun, 26 Aug 2018 07:15:43 +0100 Message-ID: <20180826061534.GT6515@ZenIV.linux.org.uk> References: <20180826055801.GA42063@beast> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: linux-kernel@vger.kernel.org, Jamal Hadi Salim , Cong Wang , Jiri Pirko , "David S. Miller" , netdev@vger.kernel.org To: Kees Cook Return-path: Received: from zeniv.linux.org.uk ([195.92.253.2]:56088 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726324AbeHZJ53 (ORCPT ); Sun, 26 Aug 2018 05:57:29 -0400 Content-Disposition: inline In-Reply-To: <20180826055801.GA42063@beast> Sender: netdev-owner@vger.kernel.org List-ID: On Sat, Aug 25, 2018 at 10:58:01PM -0700, Kees Cook wrote: > Via u32_change(), TCA_U32_SEL has an unspecified type in the netlink > policy, so max length isn't enforced, only minimum. This means nkeys > (from userspace) was being trusted without checking the actual size of > nla_len(), which could lead to a memory over-read, and ultimately an > exposure via a call to u32_dump(). Reachability is CAP_NET_ADMIN within > a namespace. > > Reported-by: Al Viro > Cc: Jamal Hadi Salim > Cc: Cong Wang > Cc: Jiri Pirko > Cc: "David S. Miller" > Cc: netdev@vger.kernel.org > Signed-off-by: Kees Cook > --- > This should go through -stable please, but I have left off the "Cc: > stable" as per netdev patch policy. Note that use of struct_size() > will need manual expansion in backports, such as: > sel_size = sizeof(*s) + sizeof(*s->keys) * s->nkeys; Saner approach would be sel_size = offsetof(struct tc_u32_sel, keys[s->nkeys])... > + sel_size = struct_size(s, keys, s->nkeys); > + if (nla_len(tb[TCA_U32_SEL]) < sel_size) { > + err = -EINVAL; > + goto erridr; > + } > > - n = kzalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL); > + n = kzalloc(offsetof(typeof(*n), sel) + sel_size, GFP_KERNEL); ITYM n = kzalloc(offsetof(struct tc_u_common, sel.keys[s->nkeys]), GFP_KERNEL);