aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorCaleb Connolly2024-04-11 19:52:37 +0200
committerTom Rini2024-04-18 16:37:10 -0600
commit024c95392d5ab5414e455e6f92e06dd063296d77 (patch)
tree366aa0fa6bce92df062eade122b83d5f82262fd5 /drivers
parenta1802b3ce160026e7214cf7c56c529bc6500a898 (diff)
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 <caleb.connolly@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/button_kbd.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/input/button_kbd.c b/drivers/input/button_kbd.c
index 74fadfca8bb..c73d3b18be9 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));