mirror of
https://github.com/torvalds/linux.git
synced 2026-09-11 20:13:02 +02:00
net/sched: act_api: release all action references on NEWACTION failure
When a batched RTM_NEWACTION request replaces an existing action,
tcf_idr_check_alloc() takes a temporary reference on it. If a later
action fails to initialize, tcf_action_destroy() uses strict release
semantics to clean up the actions initialized so far. For an action
bound to a filter, the strict check returns -EPERM without dropping
the temporary reference.
This error also makes tcf_action_destroy() return before releasing
subsequent entries. Any new action initialized between the bound
action and the failing entry is leaked together with its reserved
IDR slot, preventing reuse of its index.
Use tcf_idr_release() to drop each reference held by the batch without
rejecting bound actions. This allows cleanup to continue through all
initialized entries and preserves the module reference release when
an action is destroyed. Explicit action deletion and flushing retain
their separate bind-count checks.
Fixes: 55334a5db5 ("net_sched: act: refuse to remove bound action outside")
Cc: stable@vger.kernel.org
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20260909070336.32979-2-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
fc266a5dd9
commit
478eb5abb5
|
|
@ -1200,18 +1200,13 @@ EXPORT_SYMBOL(tcf_action_exec);
|
|||
|
||||
int tcf_action_destroy(struct tc_action *actions[], int bind)
|
||||
{
|
||||
const struct tc_action_ops *ops;
|
||||
struct tc_action *a;
|
||||
int ret = 0, i;
|
||||
|
||||
tcf_act_for_each_action(i, a, actions) {
|
||||
actions[i] = NULL;
|
||||
ops = a->ops;
|
||||
ret = __tcf_idr_release(a, bind, true);
|
||||
if (ret == ACT_P_DELETED)
|
||||
module_put(ops->owner);
|
||||
else if (ret < 0)
|
||||
return ret;
|
||||
/* Drop our reference even if the action is still bound to a filter. */
|
||||
ret = tcf_idr_release(a, bind);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user