lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Thu, 7 Jul 2022 16:11:39 +0800 From: Liang He <windhl@....com> To: linux-kernel@...r.kernel.org, windhl@....com Subject: [PATCH] arm-cci: Fix refcount leak bugs 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@....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
Powered by blists - more mailing lists