Skip to content

Commit b981e9e

Browse files
dtoringomolnar
authored andcommitted
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: 298c9ba ("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
1 parent 917e3ad commit b981e9e

1 file changed

Lines changed: 18 additions & 6 deletions

File tree

arch/x86/platform/geode/geode-common.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ static const struct software_node geode_gpio_keys_node = {
2828
.properties = geode_gpio_keys_props,
2929
};
3030

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),
3335
PROPERTY_ENTRY_U32("linux,code", KEY_RESTART),
3436
PROPERTY_ENTRY_STRING("label", "Reset button"),
3537
PROPERTY_ENTRY_U32("debounce-interval", 100),
@@ -64,8 +66,7 @@ int __init geode_create_restart_key(unsigned int pin)
6466
struct platform_device *pd;
6567
int err;
6668

67-
geode_restart_key_props[0] = PROPERTY_ENTRY_GPIO("gpios",
68-
&geode_gpiochip_node,
69+
geode_restart_gpio_ref = SOFTWARE_NODE_REFERENCE(&geode_gpiochip_node,
6970
pin, GPIO_ACTIVE_LOW);
7071

7172
err = software_node_register_node_group(geode_gpio_keys_swnodes);
@@ -99,6 +100,7 @@ int __init geode_create_leds(const char *label, const struct geode_led *leds,
99100
const struct software_node *group[MAX_LEDS + 2] = { 0 };
100101
struct software_node *swnodes;
101102
struct property_entry *props;
103+
struct software_node_ref_args *gpio_refs;
102104
struct platform_device_info led_info = {
103105
.name = "leds-gpio",
104106
.id = PLATFORM_DEVID_NONE,
@@ -127,6 +129,12 @@ int __init geode_create_leds(const char *label, const struct geode_led *leds,
127129
goto err_free_swnodes;
128130
}
129131

132+
gpio_refs = kzalloc_objs(*gpio_refs, n_leds);
133+
if (!gpio_refs) {
134+
err = -ENOMEM;
135+
goto err_free_props;
136+
}
137+
130138
group[0] = &geode_gpio_leds_node;
131139
for (i = 0; i < n_leds; i++) {
132140
node_name = kasprintf(GFP_KERNEL, "%s:%d", label, i);
@@ -135,9 +143,11 @@ int __init geode_create_leds(const char *label, const struct geode_led *leds,
135143
goto err_free_names;
136144
}
137145

146+
gpio_refs[i] = SOFTWARE_NODE_REFERENCE(&geode_gpiochip_node,
147+
leds[i].pin,
148+
GPIO_ACTIVE_LOW);
138149
props[i * 3 + 0] =
139-
PROPERTY_ENTRY_GPIO("gpios", &geode_gpiochip_node,
140-
leds[i].pin, GPIO_ACTIVE_LOW);
150+
PROPERTY_ENTRY_REF_ARRAY_LEN("gpios", &gpio_refs[i], 1);
141151
props[i * 3 + 1] =
142152
PROPERTY_ENTRY_STRING("linux,default-trigger",
143153
leds[i].default_on ?
@@ -171,6 +181,8 @@ int __init geode_create_leds(const char *label, const struct geode_led *leds,
171181
err_free_names:
172182
while (--i >= 0)
173183
kfree(swnodes[i].name);
184+
kfree(gpio_refs);
185+
err_free_props:
174186
kfree(props);
175187
err_free_swnodes:
176188
kfree(swnodes);

0 commit comments

Comments
 (0)