From: Caleb Connolly Date: Thu, 11 Apr 2024 17:52:37 +0000 (+0200) Subject: input: button_kbd: gracefully handle buttons that fail probe X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=024c95392d5ab5414e455e6f92e06dd063296d77;p=u-boot.git input: button_kbd: gracefully handle buttons that fail probe If a button device fails to probe, it will still be added to the uclass device list, and therefore will still be iterated over in button_read_keys() resulting in a UAF on the buttons private data. Resolve this by unbinding button devices that aren't active after probing, and print a warning so it's clear that the button is broken. Fixes: e8779962898e ("dm: input: add button_kbd driver") Signed-off-by: Caleb Connolly --- diff --git a/drivers/input/button_kbd.c b/drivers/input/button_kbd.c index 74fadfca8b..c73d3b18be 100644 --- a/drivers/input/button_kbd.c +++ b/drivers/input/button_kbd.c @@ -34,7 +34,8 @@ static int button_kbd_start(struct udevice *dev) { struct button_kbd_priv *priv = dev_get_priv(dev); int i = 0; - struct udevice *button_gpio_devp; + struct udevice *button_gpio_devp, *next_devp; + struct uclass *uc; uclass_foreach_dev_probe(UCLASS_BUTTON, button_gpio_devp) { struct button_uc_plat *uc_plat = dev_get_uclass_plat(button_gpio_devp); @@ -46,6 +47,21 @@ static int button_kbd_start(struct udevice *dev) i++; } + if (uclass_get(UCLASS_BUTTON, &uc)) + return -ENOENT; + + /* + * Unbind any buttons that failed to probe so we don't iterate over + * them when polling. + */ + uclass_foreach_dev_safe(button_gpio_devp, next_devp, uc) { + if (!(dev_get_flags(button_gpio_devp) & DM_FLAG_ACTIVATED)) { + log_warning("Button %s failed to probe\n", + button_gpio_devp->name); + device_unbind(button_gpio_devp); + } + } + priv->button_size = i; priv->old_state = calloc(i, sizeof(int));