Message ID | 20231013151057.2611860-3-pctammela@mojatatu.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net/sched: sch_hfsc: safely allow 'rt' inner curves | expand |
On Fri, 13 Oct 2023 12:10:57 -0300 Pedro Tammela wrote: > 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. Perfect, thank you. > Users checking the `tc class ls [...]` or `tc class get [...]` dumps would > observe the curve change and are potentially breaking with this change. > > Cc: Christian Theune <ct@flyingcircus.io> > Cc: Budimir Markovic <markovicbudimir@gmail.com> > Fixes: 0c9570eeed69 ("net/sched: sch_hfsc: upgrade 'rt' to 'sc' when it becomes a inner curve") git says this SHA does not exist. From the title I'm guessing this is the patch itself, some mis-automation, perhaps? All in all I think you can squash the revert into this and use b3d26c5702c7d6c45 for Fixes. I don't think there's a reason to keep the revert separate, given how small it is. And if the revert is first what if someone backports just the revert..
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 98805303218d..880c5f16b29c 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -902,6 +902,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) }, @@ -1061,6 +1069,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)
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. Cc: Christian Theune <ct@flyingcircus.io> Cc: Budimir Markovic <markovicbudimir@gmail.com> Fixes: 0c9570eeed69 ("net/sched: sch_hfsc: upgrade 'rt' to 'sc' when it becomes a inner curve") Signed-off-by: Pedro Tammela <pctammela@mojatatu.com> --- net/sched/sch_hfsc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)