From nobody Thu Sep 11 12:54:40 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 E9C69EB64DD for ; Fri, 4 Aug 2023 01:38:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231397AbjHDBix (ORCPT ); Thu, 3 Aug 2023 21:38:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53330 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229513AbjHDBiv (ORCPT ); Thu, 3 Aug 2023 21:38:51 -0400 X-Greylist: delayed 2702 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Thu, 03 Aug 2023 18:38:49 PDT Received: from sender4-of-o50.zoho.com (sender4-of-o50.zoho.com [136.143.188.50]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F0EE2423F; Thu, 3 Aug 2023 18:38:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691110419; cv=none; d=zohomail.com; s=zohoarc; b=Fg9X9UvLF8+SRneMqQ/G5RozikPMr77zZ8JuukEY51+w0mAOkIUoFAMVIcNAz9gTgadhEL2JsxrnkAXxjsVua4jw6M4MtKlY08gvHp1jcYXcUBH2lZL2+/yi3w0fJfEFE3cRoLSh40VYpJLow4TA08KthVOKnfVUndQojUbjKrw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1691110419; h=Content-Type:Content-Transfer-Encoding:Date:From:MIME-Version:Message-ID:Subject:To; bh=CgF7acTqP7qFlr5Qba5M3iybNkb7FVjw+xpTqeOdCzs=; b=OLJT+CNZWdX5PavarRiih19c35nqJQ3aihqM4y9v+jt3Os+nDCWzacbNPI/vDwM+AYhGn4DTfdtyOz4gLI5MzyJg3iNGFE1LVDTIVu4oDPbP+kFWuqOxM9RY0DU4RkAZ9t1KcmNw7IaVcC/ZwWOsmWSHjYBbmo17/f2kdNuIhyg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=mitchellaugustin.com; spf=pass smtp.mailfrom=mitchell@mitchellaugustin.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1691110419; s=zoho; d=mitchellaugustin.com; i=mitchell@mitchellaugustin.com; h=Message-ID:Date:Date:MIME-Version:To:To:From:From:Subject:Subject:Content-Type:Content-Transfer-Encoding:Message-Id:Reply-To:Cc; bh=CgF7acTqP7qFlr5Qba5M3iybNkb7FVjw+xpTqeOdCzs=; b=c7c8lFkZDolQNwXJq7sqHZhFpBXJDJRfVBTwOLEhypfLtraLSGEIoOa6oFO7s+Yi HVZg6Ng0XFAIeJrrhsN5uSyAeCl5E6cfZN2LmFj2XMy/qZHY5u3QW9Iw7NVeOt6vmJe Z/ZIkwk0ESZjGTfSX7rplGrMCDi9/YfLuIrltlFY= Received: from [192.168.10.116] (xpress10810.htc.net [216.114.108.10]) by mx.zohomail.com with SMTPS id 169111041747214.423010192525567; Thu, 3 Aug 2023 17:53:37 -0700 (PDT) Message-ID: Date: Thu, 3 Aug 2023 19:53:36 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.13.0 Content-Language: en-US To: Jamal Hadi Salim , Cong Wang , Jiri Pirko , "David S. Miller" , netdev@vger.kernel.org, linux-kernel@vger.kernel.org From: Mitchell Augustin Subject: [PATCH] net/sched: sch_qfq: account for stab overhead in qfq_enqueue Content-Type: text/plain; charset="utf-8"; format="flowed" Content-Transfer-Encoding: quoted-printable X-ZohoMailClient: External Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From cb3f87086b7d412df344f120ecd324412103c903 Thu Aug 3 19:28:04 2023 From: Mitchell Augustin Date: Thu, 3 Aug 2023 19:28:04 -0500 Subject: [PATCH] net/sched: sch_qfq: account for stab overhead in=20 qfq_enqueue [ Upstream commit 3e337087c3b5805fe0b8a46ba622a962880b5d64 ] I'm backporting this patch from the mainline 6.5-rc4 branch (the above=20 commit). This is my first "real" kernel patch, so please let me know if=20 I have done anything incorrect here. Thanks! Lion says: ------- In the QFQ scheduler a similar issue to CVE-2023-31436 persists. Consider the following code in net/sched/sch_qfq.c: static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 struct sk_buff **to_free) { =C2=A0=C2=A0=C2=A0=C2=A0 unsigned int len =3D qdisc_pkt_len(skb), gso_segs; =C2=A0=C2=A0=C2=A0 // ... =C2=A0=C2=A0=C2=A0=C2=A0 if (unlikely(cl->agg->lmax < len)) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 pr_debug("qfq: increasing= maxpkt from %u to %u for class %u", =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 cl->agg->lmax, len, cl->common.classid); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 err =3D qfq_change_agg(sc= h, cl, cl->agg->class_weight, len); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (err) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 c= l->qstats.drops++; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 r= eturn qdisc_drop(skb, sch, to_free); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0 // ... =C2=A0=C2=A0=C2=A0=C2=A0 } Similarly to CVE-2023-31436, "lmax" is increased without any bounds checks according to the packet length "len". Usually this would not impose a problem because packet sizes are naturally limited. This is however not the actual packet length, rather the "qdisc_pkt_len(skb)" which might apply size transformations according to "struct qdisc_size_table" as created by "qdisc_get_stab()" in net/sched/sch_api.c if the TCA_STAB option was set when modifying the qdisc. A user may choose virtually any size using such a table. As a result the same issue as in CVE-2023-31436 can occur, allowing heap out-of-bounds read / writes in the kmalloc-8192 cache. ------- We can create the issue with the following commands: tc qdisc add dev $DEV root handle 1: stab mtu 2048 tsize 512 mpu 0 \ overhead 999999999 linklayer ethernet qfq tc class add dev $DEV parent 1: classid 1:1 htb rate 6mbit burst 15k tc filter add dev $DEV parent 1: matchall classid 1:1 ping -I $DEV 1.1.1.2 This is caused by incorrectly assuming that qdisc_pkt_len() returns a length within the QFQ_MIN_LMAX < len < QFQ_MAX_LMAX. --- =C2=A0net/sched/sch_qfq.c | 8 +++++++- =C2=A01 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index c2a68f6e427e..81ebe7741463 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -116,6 +116,7 @@ =C2=A0#define QFQ_MTU_SHIFT=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 16=C2=A0= =C2=A0=C2=A0 /* to support TSO/GSO */ =C2=A0#define QFQ_MIN_LMAX=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 512=C2=A0= =C2=A0=C2=A0 /* see qfq_slot_insert */ +#define QFQ_MAX_LMAX=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 (1UL << QFQ_MTU_= SHIFT) =C2=A0#define QFQ_MAX_AGG_CLASSES=C2=A0=C2=A0=C2=A0 8 /* max num classes p= er aggregate=20 allowed */ @@ -387,8 +388,13 @@ static int qfq_change_agg(struct Qdisc *sch, struct=20 qfq_class *cl, u32 weight, =C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2= =A0 u32 lmax) =C2=A0{ =C2=A0=C2=A0=C2=A0=C2=A0 struct qfq_sched *q =3D qdisc_priv(sch); -=C2=A0=C2=A0=C2=A0 struct qfq_aggregate *new_agg =3D qfq_find_agg(q, lmax,= weight); +=C2=A0=C2=A0=C2=A0 struct qfq_aggregate *new_agg; +=C2=A0=C2=A0=C2=A0 /* 'lmax' can range from [QFQ_MIN_LMAX, pktlen + stab o= verhead] */ +=C2=A0=C2=A0=C2=A0 if (lmax > QFQ_MAX_LMAX) +=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 return -EINVAL; + +=C2=A0=C2=A0=C2=A0 new_agg =3D qfq_find_agg(q, lmax, weight); =C2=A0=C2=A0=C2=A0=C2=A0 if (new_agg =3D=3D NULL) { /* create new aggregat= e */ =C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 new_agg =3D kzalloc(sizeof(*ne= w_agg), GFP_ATOMIC); =C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 if (new_agg =3D=3D NULL) --=20 2.34.1