Skip to content

Commit ae9bc49

Browse files
sumeet4linuxUlrich Hecht
authored andcommitted
powercap: fix race condition in register_control_type()
[ Upstream commit 7bda1910c4bccd4b8d4726620bb3d6bbfb62286e ] 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. Signed-off-by: Sumeet Pawnikar <sumeet4linux@gmail.com> [ rjw: Subject adjustment, empty line added ] Link: https://patch.msgid.link/20251205190216.5032-1-sumeet4linux@gmail.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Ulrich Hecht <uli@kernel.org>
1 parent 2d36f6b commit ae9bc49

1 file changed

Lines changed: 11 additions & 5 deletions

File tree

drivers/powercap/powercap_sys.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -637,17 +637,23 @@ struct powercap_control_type *powercap_register_control_type(
637637
INIT_LIST_HEAD(&control_type->node);
638638
control_type->dev.class = &powercap_class;
639639
dev_set_name(&control_type->dev, "%s", name);
640-
result = device_register(&control_type->dev);
641-
if (result) {
642-
put_device(&control_type->dev);
643-
return ERR_PTR(result);
644-
}
645640
idr_init(&control_type->idr);
646641

647642
mutex_lock(&powercap_cntrl_list_lock);
648643
list_add_tail(&control_type->node, &powercap_cntrl_list);
649644
mutex_unlock(&powercap_cntrl_list_lock);
650645

646+
result = device_register(&control_type->dev);
647+
if (result) {
648+
mutex_lock(&powercap_cntrl_list_lock);
649+
list_del(&control_type->node);
650+
mutex_unlock(&powercap_cntrl_list_lock);
651+
652+
idr_destroy(&control_type->idr);
653+
put_device(&control_type->dev);
654+
return ERR_PTR(result);
655+
}
656+
651657
return control_type;
652658
}
653659
EXPORT_SYMBOL_GPL(powercap_register_control_type);

0 commit comments

Comments
 (0)