device property: fix of node refcount leak in fwnode_graph_get_next_endpoint()

The 'parent' returned by fwnode_graph_get_port_parent()
with refcount incremented when 'prev' is not NULL, it
needs be put when finish using it.

Because the parent is const, introduce a new variable to
store the returned fwnode, then put it before returning
from fwnode_graph_get_next_endpoint().

Fixes: b5b41ab6b0c1 ("device property: Check fwnode->secondary in fwnode_graph_get_next_endpoint()")
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-and-tested-by: Daniel Scally <djrscally@gmail.com>
Link: https://lore.kernel.org/r/20221123022542.2999510-1-yangyingliang@huawei.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by Yang Yingliang and committed by Greg Kroah-Hartman 39af7286 b7bfaa76

+12 -6
+12 -6
drivers/base/property.c
··· 997 997 fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode, 998 998 struct fwnode_handle *prev) 999 999 { 1000 + struct fwnode_handle *ep, *port_parent = NULL; 1000 1001 const struct fwnode_handle *parent; 1001 - struct fwnode_handle *ep; 1002 1002 1003 1003 /* 1004 1004 * If this function is in a loop and the previous iteration returned 1005 1005 * an endpoint from fwnode->secondary, then we need to use the secondary 1006 1006 * as parent rather than @fwnode. 1007 1007 */ 1008 - if (prev) 1009 - parent = fwnode_graph_get_port_parent(prev); 1010 - else 1008 + if (prev) { 1009 + port_parent = fwnode_graph_get_port_parent(prev); 1010 + parent = port_parent; 1011 + } else { 1011 1012 parent = fwnode; 1013 + } 1012 1014 if (IS_ERR_OR_NULL(parent)) 1013 1015 return NULL; 1014 1016 1015 1017 ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev); 1016 1018 if (ep) 1017 - return ep; 1019 + goto out_put_port_parent; 1018 1020 1019 - return fwnode_graph_get_next_endpoint(parent->secondary, NULL); 1021 + ep = fwnode_graph_get_next_endpoint(parent->secondary, NULL); 1022 + 1023 + out_put_port_parent: 1024 + fwnode_handle_put(port_parent); 1025 + return ep; 1020 1026 } 1021 1027 EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint); 1022 1028