|
Takashi Iwai |
3c7925 |
From 76ca8da989c7d97a7f76c75d475fe95a584439d7 Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
3c7925 |
From: Pietro Borrello <borrello@diag.uniroma1.it>
|
|
Takashi Iwai |
3c7925 |
Date: Sun, 12 Feb 2023 19:00:01 +0000
|
|
Takashi Iwai |
3c7925 |
Subject: [PATCH] HID: bigben: use spinlock to safely schedule workers
|
|
Takashi Iwai |
3c7925 |
Git-commit: 76ca8da989c7d97a7f76c75d475fe95a584439d7
|
|
Takashi Iwai |
3c7925 |
Patch-mainline: v6.3-rc1
|
|
Takashi Iwai |
3c7925 |
References: CVE-2023-25012 bsc#1207560
|
|
Takashi Iwai |
3c7925 |
|
|
Takashi Iwai |
3c7925 |
Use spinlocks to deal with workers introducing a wrapper
|
|
Takashi Iwai |
3c7925 |
bigben_schedule_work(), and several spinlock checks.
|
|
Takashi Iwai |
3c7925 |
Otherwise, bigben_set_led() may schedule bigben->worker after the
|
|
Takashi Iwai |
3c7925 |
structure has been freed, causing a use-after-free.
|
|
Takashi Iwai |
3c7925 |
|
|
Takashi Iwai |
3c7925 |
Fixes: 4eb1b01de5b9 ("HID: hid-bigbenff: fix race condition for scheduled work during removal")
|
|
Takashi Iwai |
3c7925 |
Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
|
|
Takashi Iwai |
3c7925 |
Link: https://lore.kernel.org/r/20230125-hid-unregister-leds-v4-3-7860c5763c38@diag.uniroma1.it
|
|
Takashi Iwai |
3c7925 |
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
|
|
Takashi Iwai |
3c7925 |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
3c7925 |
|
|
Takashi Iwai |
3c7925 |
---
|
|
Takashi Iwai |
3c7925 |
drivers/hid/hid-bigbenff.c | 18 ++++++++++++------
|
|
Takashi Iwai |
3c7925 |
1 file changed, 12 insertions(+), 6 deletions(-)
|
|
Takashi Iwai |
3c7925 |
|
|
Takashi Iwai |
3c7925 |
diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c
|
|
Takashi Iwai |
3c7925 |
index b98c5f31c184..9d6560db762b 100644
|
|
Takashi Iwai |
3c7925 |
--- a/drivers/hid/hid-bigbenff.c
|
|
Takashi Iwai |
3c7925 |
+++ b/drivers/hid/hid-bigbenff.c
|
|
Takashi Iwai |
3c7925 |
@@ -185,6 +185,15 @@ struct bigben_device {
|
|
Takashi Iwai |
3c7925 |
struct work_struct worker;
|
|
Takashi Iwai |
3c7925 |
};
|
|
Takashi Iwai |
3c7925 |
|
|
Takashi Iwai |
3c7925 |
+static inline void bigben_schedule_work(struct bigben_device *bigben)
|
|
Takashi Iwai |
3c7925 |
+{
|
|
Takashi Iwai |
3c7925 |
+ unsigned long flags;
|
|
Takashi Iwai |
3c7925 |
+
|
|
Takashi Iwai |
3c7925 |
+ spin_lock_irqsave(&bigben->lock, flags);
|
|
Takashi Iwai |
3c7925 |
+ if (!bigben->removed)
|
|
Takashi Iwai |
3c7925 |
+ schedule_work(&bigben->worker);
|
|
Takashi Iwai |
3c7925 |
+ spin_unlock_irqrestore(&bigben->lock, flags);
|
|
Takashi Iwai |
3c7925 |
+}
|
|
Takashi Iwai |
3c7925 |
|
|
Takashi Iwai |
3c7925 |
static void bigben_worker(struct work_struct *work)
|
|
Takashi Iwai |
3c7925 |
{
|
|
Takashi Iwai |
3c7925 |
@@ -197,9 +206,6 @@ static void bigben_worker(struct work_struct *work)
|
|
Takashi Iwai |
3c7925 |
u32 len;
|
|
Takashi Iwai |
3c7925 |
unsigned long flags;
|
|
Takashi Iwai |
3c7925 |
|
|
Takashi Iwai |
3c7925 |
- if (bigben->removed)
|
|
Takashi Iwai |
3c7925 |
- return;
|
|
Takashi Iwai |
3c7925 |
-
|
|
Takashi Iwai |
3c7925 |
buf = hid_alloc_report_buf(bigben->report, GFP_KERNEL);
|
|
Takashi Iwai |
3c7925 |
if (!buf)
|
|
Takashi Iwai |
3c7925 |
return;
|
|
Takashi Iwai |
3c7925 |
@@ -285,7 +291,7 @@ static int hid_bigben_play_effect(struct input_dev *dev, void *data,
|
|
Takashi Iwai |
3c7925 |
bigben->work_ff = true;
|
|
Takashi Iwai |
3c7925 |
spin_unlock_irqrestore(&bigben->lock, flags);
|
|
Takashi Iwai |
3c7925 |
|
|
Takashi Iwai |
3c7925 |
- schedule_work(&bigben->worker);
|
|
Takashi Iwai |
3c7925 |
+ bigben_schedule_work(bigben);
|
|
Takashi Iwai |
3c7925 |
}
|
|
Takashi Iwai |
3c7925 |
|
|
Takashi Iwai |
3c7925 |
return 0;
|
|
Takashi Iwai |
3c7925 |
@@ -320,7 +326,7 @@ static void bigben_set_led(struct led_classdev *led,
|
|
Takashi Iwai |
3c7925 |
|
|
Takashi Iwai |
3c7925 |
if (work) {
|
|
Takashi Iwai |
3c7925 |
bigben->work_led = true;
|
|
Takashi Iwai |
3c7925 |
- schedule_work(&bigben->worker);
|
|
Takashi Iwai |
3c7925 |
+ bigben_schedule_work(bigben);
|
|
Takashi Iwai |
3c7925 |
}
|
|
Takashi Iwai |
3c7925 |
return;
|
|
Takashi Iwai |
3c7925 |
}
|
|
Takashi Iwai |
3c7925 |
@@ -450,7 +456,7 @@ static int bigben_probe(struct hid_device *hid,
|
|
Takashi Iwai |
3c7925 |
bigben->left_motor_force = 0;
|
|
Takashi Iwai |
3c7925 |
bigben->work_led = true;
|
|
Takashi Iwai |
3c7925 |
bigben->work_ff = true;
|
|
Takashi Iwai |
3c7925 |
- schedule_work(&bigben->worker);
|
|
Takashi Iwai |
3c7925 |
+ bigben_schedule_work(bigben);
|
|
Takashi Iwai |
3c7925 |
|
|
Takashi Iwai |
3c7925 |
hid_info(hid, "LED and force feedback support for BigBen gamepad\n");
|
|
Takashi Iwai |
3c7925 |
|
|
Takashi Iwai |
3c7925 |
--
|
|
Takashi Iwai |
3c7925 |
2.35.3
|
|
Takashi Iwai |
3c7925 |
|