From nobody Sun Sep 7 15:29:03 2025 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 C2508C54EE9 for ; Tue, 13 Sep 2022 15:04:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233917AbiIMPEv (ORCPT ); Tue, 13 Sep 2022 11:04:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45554 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235030AbiIMPCO (ORCPT ); Tue, 13 Sep 2022 11:02:14 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 52A07BC0; Tue, 13 Sep 2022 07:29:26 -0700 (PDT) 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 ams.source.kernel.org (Postfix) with ESMTPS id 9F857B80F6F; Tue, 13 Sep 2022 14:29:05 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 16850C433C1; Tue, 13 Sep 2022 14:29:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1663079344; bh=XZ7QZ5fLq/vpZtWqyZMpef7Tz7QP4R97XcrSYVDojN8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sQUMqmEjjX2eJ/M/i+YrmEvtcr1jhQ3AlEKUM4vbdsrpVsGpQxqSoallziT1iGIyU k+LDNACaezqEkDfBxcs7wY0Dc6mxtQY5FP3vL7i2uj7q7dxPpLeDColvGblK8ZOH9h Vt5YW+3wZGkrK3ODfzeL7ngJC6QTTHkpQwSdi7+I= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= , "David S. Miller" , Sasha Levin , zdi-disclosures@trendmicro.com Subject: [PATCH 5.4 098/108] sch_sfb: Dont assume the skb is still around after enqueueing to child Date: Tue, 13 Sep 2022 16:07:09 +0200 Message-Id: <20220913140357.832371776@linuxfoundation.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220913140353.549108748@linuxfoundation.org> References: <20220913140353.549108748@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Toke H=C3=B8iland-J=C3=B8rgensen [ Upstream commit 9efd23297cca530bb35e1848665805d3fcdd7889 ] The sch_sfb enqueue() routine assumes the skb is still alive after it has been enqueued into a child qdisc, using the data in the skb cb field in the increment_qlen() routine after enqueue. However, the skb may in fact have been freed, causing a use-after-free in this case. In particular, this happens if sch_cake is used as a child of sfb, and the GSO splitting mode of CAKE is enabled (in which case the skb will be split into segments and the original skb freed). Fix this by copying the sfb cb data to the stack before enqueueing the skb, and using this stack copy in increment_qlen() instead of the skb pointer itself. Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-18231 Fixes: e13e02a3c68d ("net_sched: SFB flow scheduler") Signed-off-by: Toke H=C3=B8iland-J=C3=B8rgensen Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/sched/sch_sfb.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c index 4074c50ac3d73..085fe06da2a68 100644 --- a/net/sched/sch_sfb.c +++ b/net/sched/sch_sfb.c @@ -135,15 +135,15 @@ static void increment_one_qlen(u32 sfbhash, u32 slot,= struct sfb_sched_data *q) } } =20 -static void increment_qlen(const struct sk_buff *skb, struct sfb_sched_dat= a *q) +static void increment_qlen(const struct sfb_skb_cb *cb, struct sfb_sched_d= ata *q) { u32 sfbhash; =20 - sfbhash =3D sfb_hash(skb, 0); + sfbhash =3D cb->hashes[0]; if (sfbhash) increment_one_qlen(sfbhash, 0, q); =20 - sfbhash =3D sfb_hash(skb, 1); + sfbhash =3D cb->hashes[1]; if (sfbhash) increment_one_qlen(sfbhash, 1, q); } @@ -283,6 +283,7 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdis= c *sch, struct sfb_sched_data *q =3D qdisc_priv(sch); struct Qdisc *child =3D q->qdisc; struct tcf_proto *fl; + struct sfb_skb_cb cb; int i; u32 p_min =3D ~0; u32 minqlen =3D ~0; @@ -399,11 +400,12 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qd= isc *sch, } =20 enqueue: + memcpy(&cb, sfb_skb_cb(skb), sizeof(cb)); ret =3D qdisc_enqueue(skb, child, to_free); if (likely(ret =3D=3D NET_XMIT_SUCCESS)) { qdisc_qstats_backlog_inc(sch, skb); sch->q.qlen++; - increment_qlen(skb, q); + increment_qlen(&cb, q); } else if (net_xmit_drop_count(ret)) { q->stats.childdrop++; qdisc_qstats_drop(sch); --=20 2.35.1