gpio: shared: fix use-after-free bug when adding shared proxies

The GPIO lookup table can stay alive for longer than the kobject whose
name string's address we're assigning to lookup->dev_id. Fix a potential
UAF by duplicating the string.

Cc: [email protected]
Fixes: a060b8c511 ("gpiolib: implement low-level, shared GPIO support")
Reviewed-by: Linus Walleij <[email protected]>
Link: https://patch.msgid.link/20261014-gpio-shared-fwnode-lookup-v4-1-2253ad645fd6@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <[email protected]>
This commit is contained in:
Bartosz Golaszewski committed 2026-10-15 14:05:28 +02:00
1 parent 52336337f1
commit bd22f7e635
1 file changed
+8 -4
+8 -4
View File
@@ -450,7 +450,6 @@ int gpio_shared_add_proxy_lookup(struct device *consumer, struct fwnode_handle *
const char *con_id, unsigned long lflags)
{
const char *dev_id = dev_name(consumer);
struct gpiod_lookup_table *lookup;
struct gpio_shared_entry *entry;
struct gpio_shared_ref *ref;
@@ -480,18 +479,22 @@ int gpio_shared_add_proxy_lookup(struct device *consumer, struct fwnode_handle *
if (!key)
return -ENOMEM;
lookup = kzalloc_flex(*lookup, table, 2);
struct gpiod_lookup_table *lookup __free(kfree) =
kzalloc_flex(*lookup, table, 2);
if (!lookup)
return -ENOMEM;
pr_debug("Adding machine lookup entry for a shared GPIO for consumer %s, with key '%s' and con_id '%s'\n",
dev_id, key, ref->con_id ?: "none");
lookup->dev_id = dev_id;
lookup->dev_id = kstrdup(dev_id, GFP_KERNEL);
if (!lookup->dev_id)
return -ENOMEM;
lookup->table[0] = GPIO_LOOKUP(no_free_ptr(key), 0,
ref->con_id, lflags);
ref->lookup = lookup;
ref->lookup = no_free_ptr(lookup);
gpiod_add_lookup_table(ref->lookup);
return 0;
@@ -611,6 +614,7 @@ void gpio_device_teardown_shared(struct gpio_device *gdev)
if (ref->lookup) {
gpiod_remove_lookup_table(ref->lookup);
kfree(ref->lookup->table[0].key);
kfree(ref->lookup->dev_id);
kfree(ref->lookup);
ref->lookup = NULL;
}