powercap: fix race condition in register_control_type
PATCH 1/1 powercap: fix race condition in register_control_type
The device becomes visible to userspace via device_register() even before it fully initialized by idr_init(). If userspace or another thread tries to register a zone immediately after device_register(), the control_type_valid() will fail because the control_type is not yet in the list. The IDR is not yet initialized, so this race condition causes zone registration failure.
Move idr_init() and list addition before device_register() fix the race condition.
--- drivers/powercap/powercap_sys.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/powercap/powercap_sys.c +10 -5
@@ -625,17 +625,22 @@ struct powercap_control_type *powercap_register_control_type(INIT_LIST_HEAD (&control_type->node); control_type->dev.class = &powercap_class;dev_set_name (&control_type->dev,"%s" , name); - result =device_register (&control_type->dev); -if (result) { -put_device (&control_type->dev); -return ERR_PTR (result); - }idr_init (&control_type->idr);mutex_lock (&powercap_cntrl_list_lock);list_add_tail (&control_type->node, &powercap_cntrl_list);mutex_unlock (&powercap_cntrl_list_lock); + result =device_register (&control_type->dev); +if (result) { +mutex_lock (&powercap_cntrl_list_lock); +list_del (&control_type->node); +mutex_unlock (&powercap_cntrl_list_lock); +idr_destroy (&control_type->idr); +put_device (&control_type->dev); +return ERR_PTR (result); + } +return control_type; }EXPORT_SYMBOL_GPL (powercap_register_control_type);
Signature · 1 line
2.43.0
Quoted 40 lines · Sumeet Pawnikar
The device becomes visible to userspace via
device_register()even before it fully initialized byidr_init(). If userspace or another thread tries to register a zone immediately afterdevice_register(), thecontrol_type_valid()will fail because thecontrol_typeis not yet in the list. The IDR is not yet initialized, so this race condition causes zone registration failure.Move
idr_init()and list addition beforedevice_register()fix the race condition.Signed-off-by Sumeet Pawnikar <[email protected]>--- drivers/powercap/powercap_sys.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)drivers/powercap/powercap_sys.c +4
-5@@ -625,17 +625,22 @@ struct powercap_control_type *powercap_register_control_type(INIT_LIST_HEAD (&control_type->node); control_type->dev.class = &powercap_class;dev_set_name (&control_type->dev,"%s" , name); - result =device_register (&control_type->dev); -if (result) { -put_device (&control_type->dev); -return ERR_PTR (result); - }idr_init (&control_type->idr);mutex_lock (&powercap_cntrl_list_lock);list_add_tail (&control_type->node, &powercap_cntrl_list);mutex_unlock (&powercap_cntrl_list_lock); + result =device_register (&control_type->dev); +if (result) { +mutex_lock (&powercap_cntrl_list_lock); +list_del (&control_type->node);
drivers/powercap/powercap_sys.c struct powercap_control_type *powercap_register_control_type(
Quoted 10 lines
drivers/powercap/powercap_sys.c +6
-1+mutex_unlock (&powercap_cntrl_list_lock); +idr_destroy (&control_type->idr); +put_device (&control_type->dev); +return ERR_PTR (result); + } +return control_type; }EXPORT_SYMBOL_GPL (powercap_register_control_type); --
Applied as 6.19-rc material, thanks!