summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Nogueira <victor@mojatatu.com>2026-08-24 12:39:01 -0300
committerJakub Kicinski <kuba@kernel.org>2026-08-28 15:56:06 -0700
commite9ca46ebc3262b498626c4095826b8fa034bbf21 (patch)
tree859d11104876fd60473a0de397cb873234934dd5
parent13eb543cebef6d6c3ec42e31afe3856f51b7126b (diff)
net/sched: act_api: size the RTM_GETACTION reply from the actions
tca_action_gd() already walks every requested action and accumulates attr_size += tcf_action_fill_size(act), then wraps the result in tcf_action_full_attrs_size(). For RTM_DELACTION that value is handed to tcf_del_notify_msg(), which allocates max(attr_size, NLMSG_GOODSIZE). For RTM_GETACTION it is silently discarded and tcf_get_notify() allocates a fixed NLMSG_GOODSIZE skb instead. Any action whose dump exceeds that fixed budget therefore cannot be read back. For example, act_pedit overruns the budget with 32 actions of four munge keys each, act_police with 32 policers once the optional rate/peakrate/result/avrate attributes are present Fix this by passing attr_size through and allocate the reply the way the add and delete paths do. Note on exposure: RTM_GETACTION is the only one of the three action commands that is not capability checked - tc_ctl_action() requires CAP_NET_ADMIN for RTM_NEWACTION and RTM_DELACTION only - so this turns a fixed NLMSG_GOODSIZE reply into a user sized allocation on an unprivileged path. It is bounded by TCA_ACT_MAX_PRIO actions per request, and tca_action_gd() does not reject duplicate indices, so a single large action can be requested 32 times; an act_bpf program near BPF_MAXINSNS is about 32KB of dump, or roughly 1MB for one request. Creating such an action still requires CAP_NET_ADMIN, and the add and delete paths have sized their skbs this way since the Fixes commit. Should this ever need bounding, GFP_KERNEL_ACCOUNT would charge the reply to the caller's memcg. Fixes: 4e76e75d6aba ("net sched actions: calculate add/delete event message size") Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260810164357.1653956-1-victor%40mojatatu.com Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Victor Nogueira <victor@mojatatu.com> Link: https://patch.msgid.link/20260824153903.4143642-3-victor@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--net/sched/act_api.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 766162b0b810..20b6501fd33b 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -1697,12 +1697,12 @@ out_nlmsg_trim:
static int
tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
- struct tc_action *actions[], int event,
+ struct tc_action *actions[], size_t attr_size, int event,
struct netlink_ext_ack *extack)
{
struct sk_buff *skb;
- skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
+ skb = alloc_skb(max(attr_size, NLMSG_GOODSIZE), GFP_KERNEL);
if (!skb)
return -ENOBUFS;
if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
@@ -2053,7 +2053,8 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
attr_size = tcf_action_full_attrs_size(attr_size);
if (event == RTM_GETACTION)
- ret = tcf_get_notify(net, portid, n, actions, event, extack);
+ ret = tcf_get_notify(net, portid, n, actions, attr_size, event,
+ extack);
else { /* delete */
ret = tcf_del_notify(net, n, actions, portid, attr_size, extack);
if (ret)