aboutsummaryrefslogtreecommitdiff
path: root/net/sched/sch_qfq.c
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2023-07-13 11:12:01 +0200
committerPaolo Abeni <pabeni@redhat.com>2023-07-13 11:12:01 +0200
commit9d23aac8a85f69239e585c8656c6fdb21be65695 (patch)
treef72d8079e682d944c892f2ec455f26a806d91dc8 /net/sched/sch_qfq.c
parentb0b0ab6f013185f25ad0fcd9111802d92d1631dc (diff)
parent137f6219da59903f480a9032b01225e9062f7ae0 (diff)
Merge branch 'net-sched-fixes-for-sch_qfq'
Pedro Tammela says: ==================== net/sched: fixes for sch_qfq Patch 1 fixes a regression introduced in 6.4 where the MTU size could be bigger than 'lmax'. Patch 3 fixes an issue where the code doesn't account for qdisc_pkt_len() returning a size bigger then 'lmax'. Patches 2 and 4 are selftests for the issues above. ==================== Link: https://lore.kernel.org/r/20230711210103.597831-1-pctammela@mojatatu.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'net/sched/sch_qfq.c')
-rw-r--r--net/sched/sch_qfq.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index dfd9a99e6257..befaf74b33ca 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -381,8 +381,13 @@ static int qfq_change_agg(struct Qdisc *sch, struct qfq_class *cl, u32 weight,
u32 lmax)
{
struct qfq_sched *q = qdisc_priv(sch);
- struct qfq_aggregate *new_agg = qfq_find_agg(q, lmax, weight);
+ struct qfq_aggregate *new_agg;
+ /* 'lmax' can range from [QFQ_MIN_LMAX, pktlen + stab overhead] */
+ if (lmax > QFQ_MAX_LMAX)
+ return -EINVAL;
+
+ new_agg = qfq_find_agg(q, lmax, weight);
if (new_agg == NULL) { /* create new aggregate */
new_agg = kzalloc(sizeof(*new_agg), GFP_ATOMIC);
if (new_agg == NULL)
@@ -423,10 +428,17 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
else
weight = 1;
- if (tb[TCA_QFQ_LMAX])
+ if (tb[TCA_QFQ_LMAX]) {
lmax = nla_get_u32(tb[TCA_QFQ_LMAX]);
- else
+ } else {
+ /* MTU size is user controlled */
lmax = psched_mtu(qdisc_dev(sch));
+ if (lmax < QFQ_MIN_LMAX || lmax > QFQ_MAX_LMAX) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "MTU size out of bounds for qfq");
+ return -EINVAL;
+ }
+ }
inv_w = ONE_FP / weight;
weight = ONE_FP / inv_w;