diff options
author | Zijun Hu <quic_zijuhu@quicinc.com> | 2025-02-09 20:58:57 +0800 |
---|---|---|
committer | Rob Herring (Arm) <robh@kernel.org> | 2025-02-25 07:16:50 -0600 |
commit | ff93e7213d6cc8d9a7b0bc64f70ed26094e168f3 (patch) | |
tree | 62ca3b10205aa37873f9b9e9ddcf050842ea0126 | |
parent | f8647991e07f42d1525c63cfa5a021b3869ef630 (diff) |
of/irq: Fix device node refcount leakage in API of_irq_parse_raw()
if the node @out_irq->np got by of_irq_parse_raw() is a combo node which
consists of both controller and nexus, namely, of_irq_parse_raw() returns
due to condition (@ipar == @newpar), then the node's refcount was increased
twice, hence causes refcount leakage.
Fix by putting @out_irq->np refcount before returning due to the condition.
Also add comments about refcount of node @out_irq->np got by the API.
Fixes: 041284181226 ("of/irq: Allow matching of an interrupt-map local to an interrupt controller")
Cc: stable@vger.kernel.org
Signed-off-by: Zijun Hu <quic_zijuhu@quicinc.com>
Link: https://lore.kernel.org/r/20250209-of_irq_fix-v2-4-93e3a2659aa7@quicinc.com
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
-rw-r--r-- | drivers/of/irq.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 95456e918681..1a018726fb0e 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -166,6 +166,8 @@ const __be32 *of_irq_parse_imap_parent(const __be32 *imap, int len, struct of_ph * the specifier for each map, and then returns the translated map. * * Return: 0 on success and a negative number on error + * + * Note: refcount of node @out_irq->np is increased by 1 on success. */ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) { @@ -311,6 +313,12 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) addrsize = (imap - match_array) - intsize; if (ipar == newpar) { + /* + * We got @ipar's refcount, but the refcount was + * gotten again by of_irq_parse_imap_parent() via its + * alias @newpar. + */ + of_node_put(ipar); pr_debug("%pOF interrupt-map entry to self\n", ipar); return 0; } |