[PATCH v2] net: mscc: ocelot: release the mirror reference on policer failure

From: Wentao Liang

Date: Sun Nov 08 2026 - 06:00:55 EST


ocelot_vcap_filter_add_aux_resources() takes a reference on the mirror
before setting up the policer. If ocelot_vcap_policer_add() fails, the
function returns without dropping that reference. The filter is not
added to the block, so the deletion path never releases it.

Release the mirror reference on this error path. Use a goto-based
unwind ladder so that a failure added to this function later does not
have to repeat the cleanup.

The issue was found by a static analysis tool; the candidate was then
audited and the fix was prepared with the help of DeepSeek and
GPT-6.1 Sol. It was identified by code inspection only and was not
triggered; this patch was compile-tested, not tested on hardware.

Fixes: f2a0e216bee5 ("net: mscc: ocelot: offload per-flow mirroring using tc-mirred and VCAP IS2")
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
Changes in v2:
- Sorry for the very late follow-up to the review.
- Use a goto-based unwind ladder, as suggested by Simon Horman,
instead of an inline ocelot_mirror_put() call.
- Describe how the issue was found and how it was tested, as
requested by netdev-bot.
- Drop Cc: stable@xxxxxxxxxxxxxxx: the leak is only reachable when
the policer allocation fails.

drivers/net/ethernet/mscc/ocelot_vcap.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_vcap.c b/drivers/net/ethernet/mscc/ocelot_vcap.c
index 25e533e91d71..ce4a3da38c58 100644
--- a/drivers/net/ethernet/mscc/ocelot_vcap.c
+++ b/drivers/net/ethernet/mscc/ocelot_vcap.c
@@ -957,7 +957,7 @@ ocelot_vcap_filter_add_aux_resources(struct ocelot *ocelot,
struct ocelot_vcap_filter *filter,
struct netlink_ext_ack *extack)
{
- struct ocelot_mirror *m;
+ struct ocelot_mirror *m = NULL;
int ret;

if (filter->block_id == VCAP_IS2 && filter->action.mirror_ena) {
@@ -971,10 +971,15 @@ ocelot_vcap_filter_add_aux_resources(struct ocelot *ocelot,
ret = ocelot_vcap_policer_add(ocelot, filter->action.pol_ix,
&filter->action.pol);
if (ret)
- return ret;
+ goto err_mirror_put;
}

return 0;
+
+err_mirror_put:
+ if (m)
+ ocelot_mirror_put(ocelot);
+ return ret;
}

static void
--
2.34.1