Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2006757imu; Fri, 14 Dec 2018 04:24:15 -0800 (PST) X-Google-Smtp-Source: AFSGD/Vnf/W2xtms6W+hQ+42UUQoN0hzf+iWAQ7awKjV29VJ3a/PZRejDleE3xcbhjj2qbudxqvT X-Received: by 2002:a62:931a:: with SMTP id b26mr2756684pfe.65.1544790255889; Fri, 14 Dec 2018 04:24:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544790255; cv=none; d=google.com; s=arc-20160816; b=BLjzdJBCqmSK631l/HjizhILndmtkgmdAZoZZalNir6l1Om1Oaim23+ZIL/V4Hmd37 hYzzIDBEsf0FWYjzL/aXnSHjnMe4bxoRWeGdbbH+FI+a7/cRPEuyWWbKZRQi19KQIesU 3u3yGjJauppDjLWAUpeOmB6vwcZP3SB6tlNValBLeCoqC243J8cXZdijOtOzy4+kil9e y3XXYQA1ez/uEfPWcExVcCNH2/yEN2keZIohidsFZNx9imTucZVOROQ4lXTVFw4LyYDd bd4hWkoCq8CnhHp24b8XqQVSCMsLoQ9TAcvx7tMwHEyOECEYVRNZmDmUx5+m48xiNguV UYpQ== 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=FwpzsaxOz2wGmMuCXu8DANwSRjnkBzNlT9cqFbq2/hU=; b=ZNhMIbecf+tSSOonT+7JAUbOHxLHSpw5I62fAZQtY3HfnZMYHhr101ayTy3xmpYMK5 E5HRrL9Y8iJej1VpIdFO9rx7cvecioEBzebybYziPo7YcIa8FCrOPIex2yj06hBef3qS DTxZct3o5v6tRqwO/u5h0JEBRQUYVs3h7yWuYeDRBm1czEDtokRstMgyl+pk/CT40wR4 2PizOuRAo3Uc78k9Jp1Qk6UuuDO1Y/OjNRvlWrjRtpPSe2YzzfNB08+Zxa5PV6hfU1dU Dg2ByWCu5pErtcoGI1kEosW4eAhN9Xl6Qp54PheLLGpmJeD/AoIo8bcVctQv5+brIWuq xegw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=a2wln5L3; 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 x11si3737724plv.321.2018.12.14.04.24.01; Fri, 14 Dec 2018 04:24:15 -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=a2wln5L3; 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 S1731599AbeLNMXE (ORCPT + 99 others); Fri, 14 Dec 2018 07:23:04 -0500 Received: from mail.kernel.org ([198.145.29.99]:33344 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731934AbeLNMNw (ORCPT ); Fri, 14 Dec 2018 07:13:52 -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 7FE2920892; Fri, 14 Dec 2018 12:13:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1544789631; bh=/KQr6O95+oxwhZkYPhoys3D3RR9Lzrmcbegtxu7sReY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a2wln5L3CFy9K0rbZ+ypznDpBUgE9hXoR41BQKPCdhlWcEeWGOv/tviXBXL6Q6XFS NX10E7T+3zk9veMUNhL8k4allZex245yaCicuGU+xKq6IJMUlh722MCJUMDvwZvnRw JRtp8gBetKGrlLfjDuak+YVCnbrcgYlTTE0TFIaw= 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.4 08/88] neighbour: Avoid writing before skb->head in neigh_hh_output() Date: Fri, 14 Dec 2018 12:59:42 +0100 Message-Id: <20181214115702.774030045@linuxfoundation.org> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181214115702.151309521@linuxfoundation.org> References: <20181214115702.151309521@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.4-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 @@ -448,6 +448,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; int hh_len; @@ -455,16 +456,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 { - 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); }