Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

x86/platform/geode: Fix on-stack property data use-after-return bug

The PROPERTY_ENTRY_GPIO macro (and by extension PROPERTY_ENTRY_REF)
creates a temporary software_node_ref_args structure on the stack
when used in a runtime assignment. This results in the property
pointing to data that is invalid once the function returns.

Fix this by ensuring the GPIO reference data is not stored on stack and
using PROPERTY_ENTRY_REF_ARRAY_LEN() to point directly to the persistent
reference data.

Fixes: 298c9babadb8 ("x86/platform/geode: switch GPIO buttons and LEDs to software properties")
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Rafael J. Wysocki <rafael@kernel.org>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Daniel Scally <djrscally@gmail.com>
Cc: Danilo Krummrich <dakr@kernel.org>
Cc: Hans de Goede <hansg@kernel.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260329-property-gpio-fix-v2-1-3cca5ba136d8@gmail.com

authored by

Dmitry Torokhov and committed by
Ingo Molnar
b981e9e9 917e3ad3

+18 -6
+18 -6
arch/x86/platform/geode/geode-common.c
··· 28 28 .properties = geode_gpio_keys_props, 29 29 }; 30 30 31 - static struct property_entry geode_restart_key_props[] = { 32 - { /* Placeholder for GPIO property */ }, 31 + static struct software_node_ref_args geode_restart_gpio_ref; 32 + 33 + static const struct property_entry geode_restart_key_props[] = { 34 + PROPERTY_ENTRY_REF_ARRAY_LEN("gpios", &geode_restart_gpio_ref, 1), 33 35 PROPERTY_ENTRY_U32("linux,code", KEY_RESTART), 34 36 PROPERTY_ENTRY_STRING("label", "Reset button"), 35 37 PROPERTY_ENTRY_U32("debounce-interval", 100), ··· 66 64 struct platform_device *pd; 67 65 int err; 68 66 69 - geode_restart_key_props[0] = PROPERTY_ENTRY_GPIO("gpios", 70 - &geode_gpiochip_node, 67 + geode_restart_gpio_ref = SOFTWARE_NODE_REFERENCE(&geode_gpiochip_node, 71 68 pin, GPIO_ACTIVE_LOW); 72 69 73 70 err = software_node_register_node_group(geode_gpio_keys_swnodes); ··· 100 99 const struct software_node *group[MAX_LEDS + 2] = { 0 }; 101 100 struct software_node *swnodes; 102 101 struct property_entry *props; 102 + struct software_node_ref_args *gpio_refs; 103 103 struct platform_device_info led_info = { 104 104 .name = "leds-gpio", 105 105 .id = PLATFORM_DEVID_NONE, ··· 129 127 goto err_free_swnodes; 130 128 } 131 129 130 + gpio_refs = kzalloc_objs(*gpio_refs, n_leds); 131 + if (!gpio_refs) { 132 + err = -ENOMEM; 133 + goto err_free_props; 134 + } 135 + 132 136 group[0] = &geode_gpio_leds_node; 133 137 for (i = 0; i < n_leds; i++) { 134 138 node_name = kasprintf(GFP_KERNEL, "%s:%d", label, i); ··· 143 135 goto err_free_names; 144 136 } 145 137 138 + gpio_refs[i] = SOFTWARE_NODE_REFERENCE(&geode_gpiochip_node, 139 + leds[i].pin, 140 + GPIO_ACTIVE_LOW); 146 141 props[i * 3 + 0] = 147 - PROPERTY_ENTRY_GPIO("gpios", &geode_gpiochip_node, 148 - leds[i].pin, GPIO_ACTIVE_LOW); 142 + PROPERTY_ENTRY_REF_ARRAY_LEN("gpios", &gpio_refs[i], 1); 149 143 props[i * 3 + 1] = 150 144 PROPERTY_ENTRY_STRING("linux,default-trigger", 151 145 leds[i].default_on ? ··· 181 171 err_free_names: 182 172 while (--i >= 0) 183 173 kfree(swnodes[i].name); 174 + kfree(gpio_refs); 175 + err_free_props: 184 176 kfree(props); 185 177 err_free_swnodes: 186 178 kfree(swnodes);