mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
net/sched: hhf: cap hh_flows_limit at change time
hhf_change() stores TCA_HHF_HH_FLOWS_LIMIT with no upper bound. A huge hh_flows_limit lets each new heavy-hitter flow pass the hh_flows_current_cnt check in alloc_new_hh() and forces a fixed-size kzalloc(GFP_ATOMIC) per flow under spoofed traffic, for unbounded memory growth. Bound the attribute with NLA_POLICY_MAX() at 2*HH_FLOWS_CNT (the hhf_init() default) and report the rejected value via extack. The deprecated nested parse is kept: legacy tc does not set NLA_F_NESTED on TCA_OPTIONS. Configs relying on hh_limit above the default were relying on unbounded, unsafe behaviour and are not supported going forward. hhf_init() also ran hhf_change() before setting the default hh_flows_limit, so a user-supplied hh_limit at add time was clobbered back to 2048. Set the default before hhf_change() so the configured value sticks. This is a follow-up to commiteb56a495f5("net/sched: hhf: clamp quantum in change and init paths"), which bounded the quantum of the same qdisc; the hh_flows_limit bound is the remaining unbounded knob of that series' scope. Conditions to recreate the bug: CAP_NET_ADMIN in a user namespace; tc qdisc change dev X root hhf hh_limit 4294967295 succeeds and the value is echoed by tc qdisc show, unbounding heavy-hitter flow allocations; also tc qdisc add dev X root hhf hh_limit 500 stores 2048 instead of 500. Fixes:10239edf86("net-qdisc-hhf: Heavy-Hitter Filter (HHF) qdisc") Cc: stable@vger.kernel.org Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260822195509.112717-1-jhs@mojatatu.com Reviewed-by: Victor Nogueira <victor@mojatatu.com> Tested-by: hybris <hybris@mojatatu.ai> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/QDISC-B855.v1.20260911153152@mojatatu.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
18a6fe05fb
commit
2cef2588c9
|
|
@ -527,7 +527,7 @@ static void hhf_destroy(struct Qdisc *sch)
|
|||
static const struct nla_policy hhf_policy[TCA_HHF_MAX + 1] = {
|
||||
[TCA_HHF_BACKLOG_LIMIT] = { .type = NLA_U32 },
|
||||
[TCA_HHF_QUANTUM] = { .type = NLA_U32 },
|
||||
[TCA_HHF_HH_FLOWS_LIMIT] = { .type = NLA_U32 },
|
||||
[TCA_HHF_HH_FLOWS_LIMIT] = NLA_POLICY_MAX(NLA_U32, 2 * HH_FLOWS_CNT),
|
||||
[TCA_HHF_RESET_TIMEOUT] = { .type = NLA_U32 },
|
||||
[TCA_HHF_ADMIT_BYTES] = { .type = NLA_U32 },
|
||||
[TCA_HHF_EVICT_TIMEOUT] = { .type = NLA_U32 },
|
||||
|
|
@ -546,7 +546,7 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt,
|
|||
u32 new_hhf_non_hh_weight = q->hhf_non_hh_weight;
|
||||
|
||||
err = nla_parse_nested_deprecated(tb, TCA_HHF_MAX, opt, hhf_policy,
|
||||
NULL);
|
||||
extack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
@ -624,6 +624,9 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt,
|
|||
q->hhf_evict_timeout = HZ; /* 1 sec */
|
||||
q->hhf_non_hh_weight = 2;
|
||||
|
||||
/* Cap max active HHs at twice len of hh_flows table. */
|
||||
q->hh_flows_limit = 2 * HH_FLOWS_CNT;
|
||||
|
||||
if (opt) {
|
||||
int err = hhf_change(sch, opt, extack);
|
||||
|
||||
|
|
@ -639,8 +642,6 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt,
|
|||
for (i = 0; i < HH_FLOWS_CNT; i++)
|
||||
INIT_LIST_HEAD(&q->hh_flows[i]);
|
||||
|
||||
/* Cap max active HHs at twice len of hh_flows table. */
|
||||
q->hh_flows_limit = 2 * HH_FLOWS_CNT;
|
||||
q->hh_flows_overlimit = 0;
|
||||
q->hh_flows_total_cnt = 0;
|
||||
q->hh_flows_current_cnt = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user