Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp1982485imu; Fri, 14 Dec 2018 04:03:49 -0800 (PST) X-Google-Smtp-Source: AFSGD/XxTJWalcr4trHC3VvQJMQkjbB51W6ZpHomuQLKpW6Z83vIyyJppYHW3y7cJcQDdBtAvYM6 X-Received: by 2002:a62:190e:: with SMTP id 14mr2578275pfz.70.1544789029552; Fri, 14 Dec 2018 04:03:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544789029; cv=none; d=google.com; s=arc-20160816; b=KTyit+BkP4fqdTaul/sgIN/jTy5m0i8q4drmbTiDknvS7dNbwc4LG5LwFGyOiis1XY dw7BXi+bmfi5r034zL6IHNeir2WuXWwL2lQ71El1vg6DtbGiCgIkHEPchztK4yXkyFdt N0+Qpu2xYvRNfBelBklz6OAKZpubpivvjLyPsYp+G+usvLraFLdxY/J9EVzgZnbhPDuY FkJ1RS0EYqKWdWAZafYJk2w+NldOKdFVi/uc7BDxc9Pa6Y2om88yjgc9FWDSuWc0Ga9q N9MAQdtVJzkBOHoC78KTDC0YHeIq/qpN3RV9Q4v3cxsjVkRF4qHWfBQE8rx3/FcLWOOq gUeA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=WF8gj14bMWxaF1m17O1T8CjknxpnyU4GxxCO746i62c=; b=M+IgdfM2OM3isPo8IST4FFse16tVAwbiyE280OortLDY4Lj1da/U26ezaZpUnmJI9Y hHqPHB4jPqXrHDlCp+Ge+IhBdUiELq867HD+mVLxns4V2KdDjSNnW9lLWWTYiHPakbtb W5Fi1JKzltaKGTEXREyYVV9Za6sHwwb6Di88ESRk7zHrUe4gDBU7luay+AitNRBXCG0U TH+FNNI144N3pEK8l2Ib4AZqiWFIZQrYEpkIMcC7H2oJX8PK/A2jwQsC78kghkhIoGZm HOFUm1V6Lb90U8V2USdLJoXdMat1ydJkHda5eyxOWP/toRAX7d3KHlnfy/+xBDo3RSVa EQkg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=nlhLiN36; 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 e7si3883748pgv.499.2018.12.14.04.03.13; Fri, 14 Dec 2018 04:03:49 -0800 (PST) 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=@kernel.org header.s=default header.b=nlhLiN36; 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 S1729845AbeLNMBs (ORCPT + 99 others); Fri, 14 Dec 2018 07:01:48 -0500 Received: from mail.kernel.org ([198.145.29.99]:44320 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729805AbeLNMBp (ORCPT ); Fri, 14 Dec 2018 07:01:45 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (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 D94982146F; Fri, 14 Dec 2018 12:01:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1544788904; bh=WZDayLfETHJhfdrZqdHI3yMJrTPemdFOSg/CvcMmYe8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nlhLiN36NPwDJFZbAOqmQzf1H21WkSdki2tOps484e3qWjqw1agN+i1G5wmUDyLzv EeRTqaZ5OhEmHiSB1mxkyFCSkQ8BASkaDXrDhwtsHt3dILtSCWnbUf6VbYkNiVAKlh OOv0/rHahlwYty7xkNvOM+bsaBQD6rq5ZF6iINmU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Stefano Brivio , "David S. Miller" Subject: [PATCH 4.19 003/142] neighbour: Avoid writing before skb->head in neigh_hh_output() Date: Fri, 14 Dec 2018 12:58:08 +0100 Message-Id: <20181214115747.193957366@linuxfoundation.org> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181214115747.053633987@linuxfoundation.org> References: <20181214115747.053633987@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: Stefano Brivio [ Upstream commit e6ac64d4c4d095085d7dd71cbd05704ac99829b2 ] While skb_push() makes the kernel panic if the skb headroom is less than the unaligned hardware header size, it will proceed normally in case we copy more than that because of alignment, and we'll silently corrupt adjacent slabs. In the case fixed by the previous patch, "ipv6: Check available headroom in ip6_xmit() even without options", we end up in neigh_hh_output() with 14 bytes headroom, 14 bytes hardware header and write 16 bytes, starting 2 bytes before the allocated buffer. Always check we're not writing before skb->head and, if the headroom is not enough, warn and drop the packet. v2: - instead of panicking with BUG_ON(), WARN_ON_ONCE() and drop the packet (Eric Dumazet) - if we avoid the panic, though, we need to explicitly check the headroom before the memcpy(), otherwise we'll have corrupted slabs on a running kernel, after we warn - use __skb_push() instead of skb_push(), as the headroom check is already implemented here explicitly (Eric Dumazet) Signed-off-by: Stefano Brivio Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/net/neighbour.h | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -453,6 +453,7 @@ static inline int neigh_hh_bridge(struct static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb) { + unsigned int hh_alen = 0; unsigned int seq; unsigned int hh_len; @@ -460,16 +461,33 @@ static inline int neigh_hh_output(const seq = read_seqbegin(&hh->hh_lock); hh_len = hh->hh_len; if (likely(hh_len <= HH_DATA_MOD)) { - /* this is inlined by gcc */ - memcpy(skb->data - HH_DATA_MOD, hh->hh_data, HH_DATA_MOD); + hh_alen = HH_DATA_MOD; + + /* skb_push() would proceed silently if we have room for + * the unaligned size but not for the aligned size: + * check headroom explicitly. + */ + if (likely(skb_headroom(skb) >= HH_DATA_MOD)) { + /* this is inlined by gcc */ + memcpy(skb->data - HH_DATA_MOD, hh->hh_data, + HH_DATA_MOD); + } } else { - unsigned int hh_alen = HH_DATA_ALIGN(hh_len); + hh_alen = HH_DATA_ALIGN(hh_len); - memcpy(skb->data - hh_alen, hh->hh_data, hh_alen); + if (likely(skb_headroom(skb) >= hh_alen)) { + memcpy(skb->data - hh_alen, hh->hh_data, + hh_alen); + } } } while (read_seqretry(&hh->hh_lock, seq)); - skb_push(skb, hh_len); + if (WARN_ON_ONCE(skb_headroom(skb) < hh_alen)) { + kfree_skb(skb); + return NET_XMIT_DROP; + } + + __skb_push(skb, hh_len); return dev_queue_xmit(skb); }