mirror of
https://github.com/torvalds/linux.git
synced 2026-10-28 09:35:02 +01:00
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: stable@vger.kernel.org
Fixes: a060b8c511 ("gpiolib: implement low-level, shared GPIO support")
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20261014-gpio-shared-fwnode-lookup-v4-1-2253ad645fd6@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
This commit is contained in:
parent
52336337f1
commit
bd22f7e635
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user