summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerve Codina <herve.codina@bootlin.com>2024-12-02 17:58:19 +0100
committerRob Herring (Arm) <robh@kernel.org>2024-12-03 11:31:19 -0600
commitd7dfa7fde63dde4d2ec0083133efe2c6686c03ff (patch)
tree3b58af54fb67a6e7507c32acff4948f7fd521e9c
parent239521712b2b568b99d5f0ef7c1f874d797f4a29 (diff)
of: Fix error path in of_parse_phandle_with_args_map()
The current code uses some 'goto put;' to cancel the parsing operation and can lead to a return code value of 0 even on error cases. Indeed, some goto calls are done from a loop without setting the ret value explicitly before the goto call and so the ret value can be set to 0 due to operation done in previous loop iteration. For instance match can be set to 0 in the previous loop iteration (leading to a new iteration) but ret can also be set to 0 it the of_property_read_u32() call succeed. In that case if no match are found or if an error is detected the new iteration, the return value can be wrongly 0. Avoid those cases setting the ret value explicitly before the goto calls. Fixes: bd6f2fd5a1d5 ("of: Support parsing phandle argument lists through a nexus node") Cc: stable@vger.kernel.org Signed-off-by: Herve Codina <herve.codina@bootlin.com> Link: https://lore.kernel.org/r/20241202165819.158681-1-herve.codina@bootlin.com Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
-rw-r--r--drivers/of/base.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index a8b0c42bdc8e..44b1c8bf9cc0 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1471,8 +1471,10 @@ int of_parse_phandle_with_args_map(const struct device_node *np,
map_len--;
/* Check if not found */
- if (!new)
+ if (!new) {
+ ret = -EINVAL;
goto put;
+ }
if (!of_device_is_available(new))
match = 0;
@@ -1482,17 +1484,20 @@ int of_parse_phandle_with_args_map(const struct device_node *np,
goto put;
/* Check for malformed properties */
- if (WARN_ON(new_size > MAX_PHANDLE_ARGS))
- goto put;
- if (map_len < new_size)
+ if (WARN_ON(new_size > MAX_PHANDLE_ARGS) ||
+ map_len < new_size) {
+ ret = -EINVAL;
goto put;
+ }
/* Move forward by new node's #<list>-cells amount */
map += new_size;
map_len -= new_size;
}
- if (!match)
+ if (!match) {
+ ret = -ENOENT;
goto put;
+ }
/* Get the <list>-map-pass-thru property (optional) */
pass = of_get_property(cur, pass_name, NULL);