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 --- 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@vger.kernel.org: 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