From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EBACAC433EF for ; Mon, 7 Mar 2022 10:04:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236957AbiCGKFA (ORCPT ); Mon, 7 Mar 2022 05:05:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239866AbiCGKDk (ORCPT ); Mon, 7 Mar 2022 05:03:40 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 805D875201; Mon, 7 Mar 2022 01:51:59 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5F89160A28; Mon, 7 Mar 2022 09:51:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 47310C340F3; Mon, 7 Mar 2022 09:51:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1646646718; bh=MWNdMjbNh4UhiYgSJBEtVbNiySIpwKPjsIXuqTbu7D0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LIgtMHSoOR0itYiRiFzja7Fi1FtV6X5rpCTBtQ3sz0dKW57e+Bd3sSLNyQMsjrQJ4 rHWaz1sS8JhgbHkwHXnXumD3c/bF/1ezzBi+bZ9o3e/96uB+H5AUc/j4FNXOhEMH7y eHvDqiUKFJDHQljkhSL5Izi6La+zibq3eWxIKdvY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, lena wang , Paolo Abeni , Eric Dumazet , Jakub Kicinski Subject: [PATCH 5.16 072/186] net: fix up skbs delta_truesize in UDP GRO frag_list Date: Mon, 7 Mar 2022 10:18:30 +0100 Message-Id: <20220307091656.103893732@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220307091654.092878898@linuxfoundation.org> References: <20220307091654.092878898@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: stable@vger.kernel.org From: lena wang commit 224102de2ff105a2c05695e66a08f4b5b6b2d19c upstream. The truesize for a UDP GRO packet is added by main skb and skbs in main skb's frag_list: skb_gro_receive_list p->truesize += skb->truesize; The commit 53475c5dd856 ("net: fix use-after-free when UDP GRO with shared fraglist") introduced a truesize increase for frag_list skbs. When uncloning skb, it will call pskb_expand_head and trusesize for frag_list skbs may increase. This can occur when allocators uses __netdev_alloc_skb and not jump into __alloc_skb. This flow does not use ksize(len) to calculate truesize while pskb_expand_head uses. skb_segment_list err = skb_unclone(nskb, GFP_ATOMIC); pskb_expand_head if (!skb->sk || skb->destructor == sock_edemux) skb->truesize += size - osize; If we uses increased truesize adding as delta_truesize, it will be larger than before and even larger than previous total truesize value if skbs in frag_list are abundant. The main skb truesize will become smaller and even a minus value or a huge value for an unsigned int parameter. Then the following memory check will drop this abnormal skb. To avoid this error we should use the original truesize to segment the main skb. Fixes: 53475c5dd856 ("net: fix use-after-free when UDP GRO with shared fraglist") Signed-off-by: lena wang Acked-by: Paolo Abeni Reviewed-by: Eric Dumazet Link: https://lore.kernel.org/r/1646133431-8948-1-git-send-email-lena.wang@mediatek.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- net/core/skbuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3854,6 +3854,7 @@ struct sk_buff *skb_segment_list(struct list_skb = list_skb->next; err = 0; + delta_truesize += nskb->truesize; if (skb_shared(nskb)) { tmp = skb_clone(nskb, GFP_ATOMIC); if (tmp) { @@ -3878,7 +3879,6 @@ struct sk_buff *skb_segment_list(struct tail = nskb; delta_len += nskb->len; - delta_truesize += nskb->truesize; skb_push(nskb, -skb_network_offset(nskb) + offset);