Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2740177pxj; Mon, 31 May 2021 09:32:38 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxfweJExjfZHSYPo1ALQjmgJU/ANonlDMtHbTOup0GiN0ocMAZR5hQqK0FhQSoUeTZJYC3I X-Received: by 2002:a05:6402:220e:: with SMTP id cq14mr25246293edb.57.1622478758153; Mon, 31 May 2021 09:32:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622478758; cv=none; d=google.com; s=arc-20160816; b=BWQNlc9hBKyP/oEv+/gKEzlgsCmQOz/+xG89C76zAbzIgVeexeQ3lyI4U3sopjwmBg 2tYXeuwacPapa2KjcMOZ6X5rhgXmc7jYWOP6HoGS+DjTzKfpbAKMk4pwukt9KUwnZ59b zYWaCZb89tRSFhk3J/VsAu7xWNMr/STRLbUn8svKT3m0evkBsWwxXNhyiOento3GCzEm liwaDBsbcPLVb8Aod5fvSiydo0zbDyusrGYQ4f95yrlWulc6M+Yh2gLoBJl1eBMvZtGl KYz3vJY2+9+KogaasowhyI5jCUwdlcSVRR9QNvirX+Ra03LsdndyuYEtCqJxdbUa0lRa 8cMg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=CZCs8CxnYoygmNFNq4p5EsrBYOFdYoq5pOXbDayoaPk=; b=SXUuukn8xK+xCtn2pYK8+XDtZoILcMg8x7NJK9mbpf4M6bvzSL2kmxndiijEjyvpVe h/tsvXaDjSBBz4pjhAAD9yQSTHYEhzHe3MHcYg49HsJmFW+zQCOCWQWHuoLA0z2t/I+X iya2+5ylbBh/wuV1ax+gl0lEdBdB4A6Xjf0UatywQq/JlgUKvjU8AxTlnVjbqq1LdkWa x8OuJt+/X7xao3/CImuH9bR6DXZaHyTwCasJRKrJWkeQU5wenX4JuemOJ6gtxRXijW0A Tz7sYOK6Ne/zKoeVUTfisrsKdWxUnpyoQBimuGh5mELLgl0uXueWQCMukzZswSLb8oet Aygw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=PYfkEIih; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d10si3130472ejc.427.2021.05.31.09.32.12; Mon, 31 May 2021 09:32:38 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=PYfkEIih; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230032AbhEaQcB (ORCPT + 99 others); Mon, 31 May 2021 12:32:01 -0400 Received: from mail.kernel.org ([198.145.29.99]:40318 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233479AbhEaOrL (ORCPT ); Mon, 31 May 2021 10:47:11 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 1E6F861C8E; Mon, 31 May 2021 13:56:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1622469365; bh=eRBxc7NHp9jocJUg3QklbHyB/j/9smgc35aa0U9yAME=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PYfkEIihU3ieB8Xz1n0aZfDCpQ1Jc0b1roJhdl3H/2Pbk6bEG7I9tAhGrM6dCOmM3 jSl4yEpfmmUbXlaFUWxF5XFiSeWxlYOoWQY7dtb4GG5/c0n0H6OoKEP2gaYUkihlZg WtCCV+omVlMlIgMcU4DeGVj6YA+CjEpSf9dW0h2g= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Li Shuang , Xin Long , Jon Maloy , "David S. Miller" Subject: [PATCH 5.12 135/296] tipc: skb_linearize the head skb when reassembling msgs Date: Mon, 31 May 2021 15:13:10 +0200 Message-Id: <20210531130708.427730238@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210531130703.762129381@linuxfoundation.org> References: <20210531130703.762129381@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Xin Long commit b7df21cf1b79ab7026f545e7bf837bd5750ac026 upstream. It's not a good idea to append the frag skb to a skb's frag_list if the frag_list already has skbs from elsewhere, such as this skb was created by pskb_copy() where the frag_list was cloned (all the skbs in it were skb_get'ed) and shared by multiple skbs. However, the new appended frag skb should have been only seen by the current skb. Otherwise, it will cause use after free crashes as this appended frag skb are seen by multiple skbs but it only got skb_get called once. The same thing happens with a skb updated by pskb_may_pull() with a skb_cloned skb. Li Shuang has reported quite a few crashes caused by this when doing testing over macvlan devices: [] kernel BUG at net/core/skbuff.c:1970! [] Call Trace: [] skb_clone+0x4d/0xb0 [] macvlan_broadcast+0xd8/0x160 [macvlan] [] macvlan_process_broadcast+0x148/0x150 [macvlan] [] process_one_work+0x1a7/0x360 [] worker_thread+0x30/0x390 [] kernel BUG at mm/usercopy.c:102! [] Call Trace: [] __check_heap_object+0xd3/0x100 [] __check_object_size+0xff/0x16b [] simple_copy_to_iter+0x1c/0x30 [] __skb_datagram_iter+0x7d/0x310 [] __skb_datagram_iter+0x2a5/0x310 [] skb_copy_datagram_iter+0x3b/0x90 [] tipc_recvmsg+0x14a/0x3a0 [tipc] [] ____sys_recvmsg+0x91/0x150 [] ___sys_recvmsg+0x7b/0xc0 [] kernel BUG at mm/slub.c:305! [] Call Trace: [] [] kmem_cache_free+0x3ff/0x400 [] __netif_receive_skb_core+0x12c/0xc40 [] ? kmem_cache_alloc+0x12e/0x270 [] netif_receive_skb_internal+0x3d/0xb0 [] ? get_rx_page_info+0x8e/0xa0 [be2net] [] be_poll+0x6ef/0xd00 [be2net] [] ? irq_exit+0x4f/0x100 [] net_rx_action+0x149/0x3b0 ... This patch is to fix it by linearizing the head skb if it has frag_list set in tipc_buf_append(). Note that we choose to do this before calling skb_unshare(), as __skb_linearize() will avoid skb_copy(). Also, we can not just drop the frag_list either as the early time. Fixes: 45c8b7b175ce ("tipc: allow non-linear first fragment buffer") Reported-by: Li Shuang Signed-off-by: Xin Long Acked-by: Jon Maloy Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/tipc/msg.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -149,18 +149,13 @@ int tipc_buf_append(struct sk_buff **hea if (unlikely(head)) goto err; *buf = NULL; + if (skb_has_frag_list(frag) && __skb_linearize(frag)) + goto err; frag = skb_unshare(frag, GFP_ATOMIC); if (unlikely(!frag)) goto err; head = *headbuf = frag; TIPC_SKB_CB(head)->tail = NULL; - if (skb_is_nonlinear(head)) { - skb_walk_frags(head, tail) { - TIPC_SKB_CB(head)->tail = tail; - } - } else { - skb_frag_list_init(head); - } return 0; }