Skip to content

Commit f8600e0

Browse files
committed
ACPI: button: Fix lid_device value leak past driver removal
Static variable lid_device is set when the ACPI button driver probes the last lid device (under the assumptions that there will be only one lid device in the system) and never cleared, but in principle it should be reset when the driver unbinds from the lid device pointed to by it. Address that and add locking that is needed to clear and set that variable safely. Fixes: 7e12715 ("ACPI button: provide lid status functions") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://patch.msgid.link/6281379.lOV4Wx5bFT@rafael.j.wysocki
1 parent e43ffb6 commit f8600e0

1 file changed

Lines changed: 24 additions & 2 deletions

File tree

drivers/acpi/button.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ struct acpi_button {
182182
bool gpe_enabled;
183183
};
184184

185-
static struct acpi_device *lid_device;
186185
static long lid_init_state = -1;
187186

188187
static unsigned long lid_report_interval __read_mostly = 500;
@@ -378,9 +377,29 @@ static int acpi_button_remove_fs(struct acpi_button *button)
378377
return 0;
379378
}
380379

380+
static struct acpi_device *lid_device;
381+
static DEFINE_MUTEX(acpi_lid_lock);
382+
383+
static void acpi_lid_save(struct acpi_device *adev)
384+
{
385+
guard(mutex)(&acpi_lid_lock);
386+
387+
lid_device = adev;
388+
}
389+
390+
static void acpi_lid_forget(struct acpi_device *adev)
391+
{
392+
guard(mutex)(&acpi_lid_lock);
393+
394+
if (lid_device == adev)
395+
lid_device = NULL;
396+
}
397+
381398
/* Driver Interface */
382399
int acpi_lid_open(void)
383400
{
401+
guard(mutex)(&acpi_lid_lock);
402+
384403
if (!lid_device)
385404
return -ENODEV;
386405

@@ -674,7 +693,7 @@ static int acpi_button_probe(struct platform_device *pdev)
674693
* This assumes there's only one lid device, or if there are
675694
* more we only care about the last one...
676695
*/
677-
lid_device = device;
696+
acpi_lid_save(device);
678697
}
679698

680699
pr_info("%s [%s]\n", name, acpi_device_bid(device));
@@ -696,6 +715,9 @@ static void acpi_button_remove(struct platform_device *pdev)
696715
struct acpi_button *button = platform_get_drvdata(pdev);
697716
struct acpi_device *adev = button->adev;
698717

718+
if (button->type == ACPI_BUTTON_TYPE_LID)
719+
acpi_lid_forget(adev);
720+
699721
switch (adev->device_type) {
700722
case ACPI_BUS_TYPE_POWER_BUTTON:
701723
acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,

0 commit comments

Comments
 (0)