lkml.org 
[lkml]   [2022]   [Jul]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] arm-cci: Fix refcount leak bugs
Date
In fact, there are several bugs:

(1) In cci_probe(), we should call of_node_put() for the refernece
returned by of_find_matching_node() which has increased the refcount.

(2) In __cci_ace_get_port(), we should call of_node_put() in fail path
or when the reference is not used anymore as the reference is returned
by of_parse_phandle() which has increased the refcount.

(3) In cci_ace_init_ports(), we should call of_node_put() when the
referne is not used anymore as the of_get_cpu_node() will increase
the refcount.

(4) In cci_probe_ports(), we should call of_node_put() when breaking
out of for_each_available_child_of_node() which will automatically
increase and decrease refcount. Besides, we should also call
of_node_get() for the new reference created in 'ports[i].dn'.

Fixes: ed69bdd8fd9b ("drivers: bus: add ARM CCI support")
Signed-off-by: Liang He <windhl@126.com>
---

For bug(4), I have not found when the global 'ports' is destroyed,
so I cannot use 'of_node_put()' for its 'dn'. Please check it carefully.

drivers/bus/arm-cci.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index b8184a903583..d8e66022de5c 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -167,9 +167,12 @@ static int __cci_ace_get_port(struct device_node *dn, int type)
cci_portn = of_parse_phandle(dn, "cci-control-port", 0);
for (i = 0; i < nb_cci_ports; i++) {
ace_match = ports[i].type == type;
- if (ace_match && cci_portn == ports[i].dn)
+ if (ace_match && cci_portn == ports[i].dn) {
+ of_node_put(cci_portn);
return i;
+ }
}
+ of_node_put(cci_portn);
return -ENODEV;
}

@@ -199,6 +202,7 @@ static void cci_ace_init_ports(void)
continue;

port = __cci_ace_get_port(cpun, ACE_PORT);
+ of_node_put(cpun);
if (port < 0)
continue;

@@ -461,8 +465,10 @@ static int cci_probe_ports(struct device_node *np)

i = nb_ace + nb_ace_lite;

- if (i >= nb_cci_ports)
+ if (i >= nb_cci_ports) {
+ of_node_put(cp);
break;
+ }

if (of_property_read_string(cp, "interface-type",
&match_str)) {
@@ -498,7 +504,7 @@ static int cci_probe_ports(struct device_node *np)
ports[i].type = ACE_LITE_PORT;
++nb_ace_lite;
}
- ports[i].dn = cp;
+ ports[i].dn = of_node_get(cp);
}

/*
@@ -551,7 +557,9 @@ static int cci_probe(void)
return -ENXIO;
}

- return cci_probe_ports(np);
+ ret = cci_probe_ports(np);
+ of_node_put(np);
+ return ret;
}

static int cci_init_status = -EAGAIN;
--
2.25.1
\
 
 \ /
  Last update: 2022-07-07 10:13    [W:0.032 / U:0.028 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site