mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
net/sched: act_gate: cap the number of scheduling entries
parse_gate_list() accepts _any number_ of TCA_GATE_ONE_ENTRY elements.
The only bound/cap is the enclosing nlattr u16 nla_len (~5460
minimal 12-byte entries). Each entry is a separate GFP_ATOMIC
allocation, and the dump of a large list grows one action's reply well
past NLMSG_GOODSIZE.
The bugs:
1. A single gate can make tcf_dump_walker() silently truncate
"tc actions ls" ("net/sched: act_api: report an oversized action dump
instead of silently truncating it" makes such an action report -EMSGSIZE
instead of dropping the rest of the list).
2. Lack of capping pins memory for as long as the action lives: the
largest representable minimal list is roughly 5460 entries, each a
separate GFP_ATOMIC allocation, with a per-entry offload array on top in
full offload. The held-reply RTM_GETACTION amplification demonstrated in
the original posting of this series (Link below) is a generic netlink
property this cap does not remove; the bound added here is the install-side
pin.
So we need to provide an upper bound cap of TCA_GATE_ONE_ENTRY elements.
Some context:
The gate action offloads through FLOW_ACTION_GATE. The offload
interface passes the priority, base time, cycle time, cycle-time
extension, the complete entry count and an array holding each entry's
gate state, interval, IPV and maximum-octet value. The in-tree SJA1105
DSA driver forwards that complete list to sja1105_vl_gate() without any
entry cap check, and composes every supplied entry into the hardware
schedule table.
Act gate challenges:
SJA1105 and SJA1110 are two device families in the one sja1105 driver.
They expose different schedule-table capacities: SJA1105 provides up to
1024 schedule entries and SJA1110 up to 4096. These are total table
capacities shared with other schedules, so they are upper bounds, not a
guaranteed per-action budget. Software gate actions with _a lot more_
entries install and serialize today, so a low cap would reject working
configurations and would look like a UAPI breakage; but an infinite size
of entries is a bogus choice; a 65-entry configuration was verified
during this work to install and dump well-formed.
Netlink Challenges:
Netlink attributes record their total size, including the four-byte
header, in a 16-bit nla_len, so a nested attribute can describe at most
65532 bytes. A minimal accepted input entry is 12 bytes, which puts the
max we can fit at roughly 5460 entries; a dumped entry occupies 36 bytes,
or 40 bytes when it carries the gate-open flag.
1024 entries therefore serialize to 36868-40964 bytes, which fits
inside one nested attribute, while a 4096-entry schedule would need
roughly 144-160 KiB which _cannot fit_ at the moment due to the 16bit
length.
Note: This represents challenges primarily with netlink.
The Cap:
Cap the list at 1024 entries. This value is based on the existing
SJA1105 schedule-table capacity and preserves the verified 65-entry
configuration while providing a substantial headroom, and keeps the
complete gate list inside the current 16-bit TLV format. It
deliberately declines to expose SJA1110's 1025-4096 range through
an interface that cannot serialize it, and deliberately rejects
software-only schedules above 1024.
Why 1024 despite the dump budget:
1024 is a SJA1105 schedule-table capacity, not a dump-budget value. The
kernel clamps a dump skb to SKB_WITH_OVERHEAD(32768), so only ~800-890
entries of this list fit "tc actions ls"; the top of the admitted band
therefore installs but is not listed. That is accepted deliberately:
a unicast RTM_GETACTION reply is pre-sized from the action's advertised
size (budgeted per entry since the parent fix), so "tc actions get"
enumerates the whole band, and "net/sched: act_api: report an oversized
action dump instead of silently truncating it" makes the list view fail
loudly with -EMSGSIZE and an extack rather than silently truncating. A
filter whose action list contains such a gate also stops "tc filter show"
for that chain with -EMSGSIZE (loud), through tc_dump_tfilter()'s
no-progress path.
This is an operational cap on a configuration the uAPI accepted before,
so it is net-next hardening; if we made this a stable backport then
it would start rejecting gate configurations that install today (even
though those settings would be totally bogus).
Conditions to recreate the bug:
CAP_NET_ADMIN with CONFIG_NET_ACT_GATE=y. Install a gate
action with 1025 or more minimal TCA_GATE_ONE_ENTRY elements over a raw
netlink RTM_NEWACTION request. The cap rejects the list with -E2BIG and
an extack naming the limit; 1024 entries install and an indexed
RTM_GETACTION returns a well-formed reply.
Link: https://lore.kernel.org/netdev/QDISC-H19Z.v1.20261001053234@mojatatu.com/
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-H19Z.v3.r0.20261012193813-3@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
1a49567560
commit
150167ea4d
|
|
@ -18,6 +18,13 @@
|
|||
|
||||
static struct tc_action_ops act_gate_ops;
|
||||
|
||||
/* A nested attribute's u16 nla_len caps it at 65532 bytes. tcf_gate_dump()
|
||||
* emits each entry as 36 bytes (40 with the gate-open flag), so 4096 entries
|
||||
* would need ~144-160 KiB and cannot be represented. 1024 matches the
|
||||
* SJA1105 schedule-table capacity (SJA1110 provides 4096).
|
||||
*/
|
||||
#define GATE_ENTRIES_MAX 1024U
|
||||
|
||||
static ktime_t gate_get_time(struct tcf_gate *gact)
|
||||
{
|
||||
ktime_t mono = ktime_get();
|
||||
|
|
@ -277,6 +284,14 @@ static int parse_gate_list(struct nlattr *list_attr,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (i >= GATE_ENTRIES_MAX) {
|
||||
NL_SET_ERR_MSG_FMT(extack,
|
||||
"Too many schedule entries, at most %u are supported",
|
||||
GATE_ENTRIES_MAX);
|
||||
err = -E2BIG;
|
||||
goto release_list;
|
||||
}
|
||||
|
||||
entry = kzalloc_obj(*entry, GFP_ATOMIC);
|
||||
if (!entry) {
|
||||
NL_SET_ERR_MSG(extack, "Not enough memory for entry");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user