pinctrl: fix deadlock in create_pinctrl() when handling -EPROBE_DEFER
[ Upstream commit adec57ff8e66aee632f3dd1f93787c13d112b7a1 ]
In create_pinctrl(), pinctrl_maps_mutex is acquired before calling
add_setting(). If add_setting() returns -EPROBE_DEFER, create_pinctrl()
calls pinctrl_free(). However, pinctrl_free() attempts to acquire
pinctrl_maps_mutex, which is already held by create_pinctrl(), leading to
a potential deadlock.
This patch resolves the issue by releasing pinctrl_maps_mutex before
calling pinctrl_free(), preventing the deadlock.
This bug was discovered and resolved using Coverity Static Analysis
Security Testing (SAST) by Synopsys, Inc.
Fixes: 42fed7ba44
("pinctrl: move subsystem mutex to pinctrl_dev struct")
Suggested-by: Maximilian Heyne <mheyne@amazon.de>
Signed-off-by: Hagar Hemdan <hagarhem@amazon.com>
Link: https://lore.kernel.org/r/20240604085838.3344-1-hagarhem@amazon.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
b6be2b025c
commit
b813e3fd10
@@ -1092,8 +1092,8 @@ static struct pinctrl *create_pinctrl(struct device *dev,
|
|||||||
* an -EPROBE_DEFER later, as that is the worst case.
|
* an -EPROBE_DEFER later, as that is the worst case.
|
||||||
*/
|
*/
|
||||||
if (ret == -EPROBE_DEFER) {
|
if (ret == -EPROBE_DEFER) {
|
||||||
pinctrl_free(p, false);
|
|
||||||
mutex_unlock(&pinctrl_maps_mutex);
|
mutex_unlock(&pinctrl_maps_mutex);
|
||||||
|
pinctrl_free(p, false);
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user