Blob Blame History Raw
From e42a36dc8c4dfa5eb51abe028d5dbf7ccc1f5a6f Mon Sep 17 00:00:00 2001
From: Joe Lawrence <joe.lawrence@redhat.com>
Date: Mon, 27 Nov 2023 13:25:03 -0500
Subject: [KPATCH CVE-2023-4623] kpatch fixes for CVE-2023-4623

Kernels:
3.10.0-1160.92.1.el7
3.10.0-1160.95.1.el7
3.10.0-1160.99.1.el7
3.10.0-1160.102.1.el7
3.10.0-1160.105.1.el7


Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-7/-/merge_requests/63
Changes since last build:
[x86_64]:
af_unix.o: changed function: unix_stream_sendpage
sch_hfsc.o: changed function: hfsc_change_class

[ppc64le]:
af_unix.o: changed function: unix_stream_sendpage

---------------------------

Modifications: none

commit 85dbd5b056f6c63f122abbf6b07974adb66c8c10
Author: Davide Caratti <dcaratti@redhat.com>
Date:   Tue Nov 21 18:08:36 2023 +0100

    net/sched: sch_hfsc: Ensure inner classes have fsc curve

    JIRA: https://issues.redhat.com/browse/RHEL-16458
    CVE: CVE-2023-4623
    Upstream Status: net.git commit b3d26c5702c7d6c45456326e56d2ccf3f103e60f

    commit b3d26c5702c7d6c45456326e56d2ccf3f103e60f
    Author: Budimir Markovic <markovicbudimir@gmail.com>
    Date:   Thu Aug 24 01:49:05 2023 -0700

        net/sched: sch_hfsc: Ensure inner classes have fsc curve

        HFSC assumes that inner classes have an fsc curve, but it is currently
        possible for classes without an fsc curve to become parents. This leads
        to bugs including a use-after-free.

        Don't allow non-root classes without HFSC_FSC to become parents.

        Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
        Reported-by: Budimir Markovic <markovicbudimir@gmail.com>
        Signed-off-by: Budimir Markovic <markovicbudimir@gmail.com>
        Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
        Link: https://lore.kernel.org/r/20230824084905.422-1-markovicbudimir@gmail.com
        Signed-off-by: Jakub Kicinski <kuba@kernel.org>

    Signed-off-by: Davide Caratti <dcaratti@redhat.com>

commit d5ca9824c050deefa376decdba70e7f992397a58
Author: Davide Caratti <dcaratti@redhat.com>
Date:   Tue Nov 21 18:08:37 2023 +0100

    net/sched: sch_hfsc: upgrade 'rt' to 'sc' when it becomes a inner curve

    JIRA: https://issues.redhat.com/browse/RHEL-16458
    CVE: CVE-2023-4623
    Upstream Status: net.git commit a13b67c9a015c4e21601ef9aa4ec9c5d972df1b4

    commit a13b67c9a015c4e21601ef9aa4ec9c5d972df1b4
    Author: Pedro Tammela <pctammela@mojatatu.com>
    Date:   Tue Oct 17 11:36:02 2023 -0300

        net/sched: sch_hfsc: upgrade 'rt' to 'sc' when it becomes a inner curve

        Christian Theune says:
           I upgraded from 6.1.38 to 6.1.55 this morning and it broke my traffic shaping script,
           leaving me with a non-functional uplink on a remote router.

        A 'rt' curve cannot be used as a inner curve (parent class), but we were
        allowing such configurations since the qdisc was introduced. Such
        configurations would trigger a UAF as Budimir explains:
           The parent will have vttree_insert() called on it in init_vf(),
           but will not have vttree_remove() called on it in update_vf()
           because it does not have the HFSC_FSC flag set.

        The qdisc always assumes that inner classes have the HFSC_FSC flag set.
        This is by design as it doesn't make sense 'qdisc wise' for an 'rt'
        curve to be an inner curve.

        Budimir's original patch disallows users to add classes with a 'rt'
        parent, but this is too strict as it breaks users that have been using
        'rt' as a inner class. Another approach, taken by this patch, is to
        upgrade the inner 'rt' into a 'sc', warning the user in the process.
        It avoids the UAF reported by Budimir while also being more permissive
        to bad scripts/users/code using 'rt' as a inner class.

        Users checking the `tc class ls [...]` or `tc class get [...]` dumps would
        observe the curve change and are potentially breaking with this change.

        v1->v2: https://lore.kernel.org/all/20231013151057.2611860-1-pctammela@mojatatu.com/
        - Correct 'Fixes' tag and merge with revert (Jakub)

        Cc: Christian Theune <ct@flyingcircus.io>
        Cc: Budimir Markovic <markovicbudimir@gmail.com>
        Fixes: b3d26c5702c7 ("net/sched: sch_hfsc: Ensure inner classes have fsc curve")
        Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
        Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
        Link: https://lore.kernel.org/r/20231017143602.3191556-1-pctammela@mojatatu.com
        Signed-off-by: Jakub Kicinski <kuba@kernel.org>

    Signed-off-by: Davide Caratti <dcaratti@redhat.com>

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
 net/sched/sch_hfsc.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index fb14b551f65d..63e768f5ce21 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -913,6 +913,14 @@ hfsc_change_usc(struct hfsc_class *cl, struct tc_service_curve *usc,
 	cl->cl_flags |= HFSC_USC;
 }
 
+static void
+hfsc_upgrade_rt(struct hfsc_class *cl)
+{
+	cl->cl_fsc = cl->cl_rsc;
+	rtsc_init(&cl->cl_virtual, &cl->cl_fsc, cl->cl_vt, cl->cl_total);
+	cl->cl_flags |= HFSC_FSC;
+}
+
 static const struct nla_policy hfsc_policy[TCA_HFSC_MAX + 1] = {
 	[TCA_HFSC_RSC]	= { .len = sizeof(struct tc_service_curve) },
 	[TCA_HFSC_FSC]	= { .len = sizeof(struct tc_service_curve) },
@@ -1072,6 +1080,12 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 	cl->cf_tree = RB_ROOT;
 
 	sch_tree_lock(sch);
+	/* Check if the inner class is a misconfigured 'rt' */
+	if (!(parent->cl_flags & HFSC_FSC) && parent != &q->root) {
+		NL_SET_ERR_MSG(extack,
+			       "Forced curve change on parent 'rt' to 'sc'");
+		hfsc_upgrade_rt(parent);
+	}
 	qdisc_class_hash_insert(&q->clhash, &cl->cl_common);
 	list_add_tail(&cl->siblings, &parent->children);
 	if (parent->level == 0)
-- 
2.44.0