Skip to content

Commit 848e076

Browse files
committed
Merge tag 'hid-for-linus-2025030501' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID fixes from Jiri Kosina: - power management fix in intel-thc-hid (Even Xu) - nintendo gencon mapping fix (Ryan McClelland) - fix for UAF on device diconnect path in hid-steam (Vicki Pfau) - two fixes for UAF on device disconnect path in intel-ish-hid (Zhang Lixu) - fix for potential NULL dereference in hid-appleir (Daniil Dulov) - few other small cosmetic fixes (e.g. typos) * tag 'hid-for-linus-2025030501' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: Intel-thc-hid: Intel-quickspi: Correct device state after S4 HID: intel-thc-hid: Fix spelling mistake "intput" -> "input" HID: hid-steam: Fix use-after-free when detaching device HID: debug: Fix spelling mistake "Messanger" -> "Messenger" HID: appleir: Fix potential NULL dereference at raw event handle HID: apple: disable Fn key handling on the Omoton KB066 HID: i2c-hid: improve i2c_hid_get_report error message HID: intel-ish-hid: Fix use-after-free issue in ishtp_hid_remove() HID: intel-ish-hid: Fix use-after-free issue in hid_ishtp_cl_remove() HID: google: fix unused variable warning under !CONFIG_ACPI HID: nintendo: fix gencon button events map HID: corsair-void: Update power supply values with a unified work handler
2 parents 0d2d0f3 + db52926 commit 848e076

File tree

12 files changed

+70
-58
lines changed

12 files changed

+70
-58
lines changed

drivers/hid/hid-apple.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,12 @@ static bool apple_is_non_apple_keyboard(struct hid_device *hdev)
378378
return false;
379379
}
380380

381+
static bool apple_is_omoton_kb066(struct hid_device *hdev)
382+
{
383+
return hdev->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI &&
384+
strcmp(hdev->name, "Bluetooth Keyboard") == 0;
385+
}
386+
381387
static inline void apple_setup_key_translation(struct input_dev *input,
382388
const struct apple_key_translation *table)
383389
{
@@ -546,9 +552,6 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
546552
}
547553
}
548554

549-
if (usage->hid == 0xc0301) /* Omoton KB066 quirk */
550-
code = KEY_F6;
551-
552555
if (usage->code != code) {
553556
input_event_with_scancode(input, usage->type, code, usage->hid, value);
554557

@@ -728,7 +731,7 @@ static int apple_input_configured(struct hid_device *hdev,
728731
{
729732
struct apple_sc *asc = hid_get_drvdata(hdev);
730733

731-
if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) {
734+
if (((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) || apple_is_omoton_kb066(hdev)) {
732735
hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n");
733736
asc->quirks &= ~APPLE_HAS_FN;
734737
}

drivers/hid/hid-appleir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ static int appleir_raw_event(struct hid_device *hid, struct hid_report *report,
188188
static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 };
189189
unsigned long flags;
190190

191-
if (len != 5)
191+
if (len != 5 || !(hid->claimed & HID_CLAIMED_INPUT))
192192
goto out;
193193

194194
if (!memcmp(data, keydown, sizeof(keydown))) {

drivers/hid/hid-corsair-void.c

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,9 @@
7171

7272
#include <linux/bitfield.h>
7373
#include <linux/bitops.h>
74-
#include <linux/cleanup.h>
7574
#include <linux/device.h>
7675
#include <linux/hid.h>
7776
#include <linux/module.h>
78-
#include <linux/mutex.h>
7977
#include <linux/power_supply.h>
8078
#include <linux/usb.h>
8179
#include <linux/workqueue.h>
@@ -120,6 +118,12 @@ enum {
120118
CORSAIR_VOID_BATTERY_CHARGING = 5,
121119
};
122120

121+
enum {
122+
CORSAIR_VOID_ADD_BATTERY = 0,
123+
CORSAIR_VOID_REMOVE_BATTERY = 1,
124+
CORSAIR_VOID_UPDATE_BATTERY = 2,
125+
};
126+
123127
static enum power_supply_property corsair_void_battery_props[] = {
124128
POWER_SUPPLY_PROP_STATUS,
125129
POWER_SUPPLY_PROP_PRESENT,
@@ -155,12 +159,12 @@ struct corsair_void_drvdata {
155159

156160
struct power_supply *battery;
157161
struct power_supply_desc battery_desc;
158-
struct mutex battery_mutex;
159162

160163
struct delayed_work delayed_status_work;
161164
struct delayed_work delayed_firmware_work;
162-
struct work_struct battery_remove_work;
163-
struct work_struct battery_add_work;
165+
166+
unsigned long battery_work_flags;
167+
struct work_struct battery_work;
164168
};
165169

166170
/*
@@ -260,11 +264,9 @@ static void corsair_void_process_receiver(struct corsair_void_drvdata *drvdata,
260264

261265
/* Inform power supply if battery values changed */
262266
if (memcmp(&orig_battery_data, battery_data, sizeof(*battery_data))) {
263-
scoped_guard(mutex, &drvdata->battery_mutex) {
264-
if (drvdata->battery) {
265-
power_supply_changed(drvdata->battery);
266-
}
267-
}
267+
set_bit(CORSAIR_VOID_UPDATE_BATTERY,
268+
&drvdata->battery_work_flags);
269+
schedule_work(&drvdata->battery_work);
268270
}
269271
}
270272

@@ -536,29 +538,11 @@ static void corsair_void_firmware_work_handler(struct work_struct *work)
536538

537539
}
538540

539-
static void corsair_void_battery_remove_work_handler(struct work_struct *work)
540-
{
541-
struct corsair_void_drvdata *drvdata;
542-
543-
drvdata = container_of(work, struct corsair_void_drvdata,
544-
battery_remove_work);
545-
scoped_guard(mutex, &drvdata->battery_mutex) {
546-
if (drvdata->battery) {
547-
power_supply_unregister(drvdata->battery);
548-
drvdata->battery = NULL;
549-
}
550-
}
551-
}
552-
553-
static void corsair_void_battery_add_work_handler(struct work_struct *work)
541+
static void corsair_void_add_battery(struct corsair_void_drvdata *drvdata)
554542
{
555-
struct corsair_void_drvdata *drvdata;
556543
struct power_supply_config psy_cfg = {};
557544
struct power_supply *new_supply;
558545

559-
drvdata = container_of(work, struct corsair_void_drvdata,
560-
battery_add_work);
561-
guard(mutex)(&drvdata->battery_mutex);
562546
if (drvdata->battery)
563547
return;
564548

@@ -583,16 +567,42 @@ static void corsair_void_battery_add_work_handler(struct work_struct *work)
583567
drvdata->battery = new_supply;
584568
}
585569

570+
static void corsair_void_battery_work_handler(struct work_struct *work)
571+
{
572+
struct corsair_void_drvdata *drvdata = container_of(work,
573+
struct corsair_void_drvdata, battery_work);
574+
575+
bool add_battery = test_and_clear_bit(CORSAIR_VOID_ADD_BATTERY,
576+
&drvdata->battery_work_flags);
577+
bool remove_battery = test_and_clear_bit(CORSAIR_VOID_REMOVE_BATTERY,
578+
&drvdata->battery_work_flags);
579+
bool update_battery = test_and_clear_bit(CORSAIR_VOID_UPDATE_BATTERY,
580+
&drvdata->battery_work_flags);
581+
582+
if (add_battery && !remove_battery) {
583+
corsair_void_add_battery(drvdata);
584+
} else if (remove_battery && !add_battery && drvdata->battery) {
585+
power_supply_unregister(drvdata->battery);
586+
drvdata->battery = NULL;
587+
}
588+
589+
if (update_battery && drvdata->battery)
590+
power_supply_changed(drvdata->battery);
591+
592+
}
593+
586594
static void corsair_void_headset_connected(struct corsair_void_drvdata *drvdata)
587595
{
588-
schedule_work(&drvdata->battery_add_work);
596+
set_bit(CORSAIR_VOID_ADD_BATTERY, &drvdata->battery_work_flags);
597+
schedule_work(&drvdata->battery_work);
589598
schedule_delayed_work(&drvdata->delayed_firmware_work,
590599
msecs_to_jiffies(100));
591600
}
592601

593602
static void corsair_void_headset_disconnected(struct corsair_void_drvdata *drvdata)
594603
{
595-
schedule_work(&drvdata->battery_remove_work);
604+
set_bit(CORSAIR_VOID_REMOVE_BATTERY, &drvdata->battery_work_flags);
605+
schedule_work(&drvdata->battery_work);
596606

597607
corsair_void_set_unknown_wireless_data(drvdata);
598608
corsair_void_set_unknown_batt(drvdata);
@@ -678,13 +688,7 @@ static int corsair_void_probe(struct hid_device *hid_dev,
678688
drvdata->battery_desc.get_property = corsair_void_battery_get_property;
679689

680690
drvdata->battery = NULL;
681-
INIT_WORK(&drvdata->battery_remove_work,
682-
corsair_void_battery_remove_work_handler);
683-
INIT_WORK(&drvdata->battery_add_work,
684-
corsair_void_battery_add_work_handler);
685-
ret = devm_mutex_init(drvdata->dev, &drvdata->battery_mutex);
686-
if (ret)
687-
return ret;
691+
INIT_WORK(&drvdata->battery_work, corsair_void_battery_work_handler);
688692

689693
ret = sysfs_create_group(&hid_dev->dev.kobj, &corsair_void_attr_group);
690694
if (ret)
@@ -721,8 +725,7 @@ static void corsair_void_remove(struct hid_device *hid_dev)
721725
struct corsair_void_drvdata *drvdata = hid_get_drvdata(hid_dev);
722726

723727
hid_hw_stop(hid_dev);
724-
cancel_work_sync(&drvdata->battery_remove_work);
725-
cancel_work_sync(&drvdata->battery_add_work);
728+
cancel_work_sync(&drvdata->battery_work);
726729
if (drvdata->battery)
727730
power_supply_unregister(drvdata->battery);
728731

drivers/hid/hid-debug.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3450,7 +3450,7 @@ static const char *keys[KEY_MAX + 1] = {
34503450
[KEY_MACRO_RECORD_START] = "MacroRecordStart",
34513451
[KEY_MACRO_RECORD_STOP] = "MacroRecordStop",
34523452
[KEY_MARK_WAYPOINT] = "MarkWayPoint", [KEY_MEDIA_REPEAT] = "MediaRepeat",
3453-
[KEY_MEDIA_TOP_MENU] = "MediaTopMenu", [KEY_MESSENGER] = "Messanger",
3453+
[KEY_MEDIA_TOP_MENU] = "MediaTopMenu", [KEY_MESSENGER] = "Messenger",
34543454
[KEY_NAV_CHART] = "NavChar", [KEY_NAV_INFO] = "NavInfo",
34553455
[KEY_NEWS] = "News", [KEY_NEXT_ELEMENT] = "NextElement",
34563456
[KEY_NEXT_FAVORITE] = "NextFavorite", [KEY_NOTIFICATION_CENTER] = "NotificationCenter",

drivers/hid/hid-google-hammer.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,13 @@ static void cbas_ec_remove(struct platform_device *pdev)
268268
mutex_unlock(&cbas_ec_reglock);
269269
}
270270

271+
#ifdef CONFIG_ACPI
271272
static const struct acpi_device_id cbas_ec_acpi_ids[] = {
272273
{ "GOOG000B", 0 },
273274
{ }
274275
};
275276
MODULE_DEVICE_TABLE(acpi, cbas_ec_acpi_ids);
277+
#endif
276278

277279
#ifdef CONFIG_OF
278280
static const struct of_device_id cbas_ec_of_match[] = {

drivers/hid/hid-nintendo.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -457,13 +457,13 @@ static const struct joycon_ctlr_button_mapping snescon_button_mappings[] = {
457457
};
458458

459459
static const struct joycon_ctlr_button_mapping gencon_button_mappings[] = {
460-
{ BTN_A, JC_BTN_A, },
461-
{ BTN_B, JC_BTN_B, },
462-
{ BTN_C, JC_BTN_R, },
463-
{ BTN_X, JC_BTN_X, }, /* MD/GEN 6B Only */
464-
{ BTN_Y, JC_BTN_Y, }, /* MD/GEN 6B Only */
465-
{ BTN_Z, JC_BTN_L, }, /* MD/GEN 6B Only */
466-
{ BTN_SELECT, JC_BTN_ZR, },
460+
{ BTN_WEST, JC_BTN_A, }, /* A */
461+
{ BTN_SOUTH, JC_BTN_B, }, /* B */
462+
{ BTN_EAST, JC_BTN_R, }, /* C */
463+
{ BTN_TL, JC_BTN_X, }, /* X MD/GEN 6B Only */
464+
{ BTN_NORTH, JC_BTN_Y, }, /* Y MD/GEN 6B Only */
465+
{ BTN_TR, JC_BTN_L, }, /* Z MD/GEN 6B Only */
466+
{ BTN_SELECT, JC_BTN_ZR, }, /* Mode */
467467
{ BTN_START, JC_BTN_PLUS, },
468468
{ BTN_MODE, JC_BTN_HOME, },
469469
{ BTN_Z, JC_BTN_CAP, },

drivers/hid/hid-steam.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1327,11 +1327,11 @@ static void steam_remove(struct hid_device *hdev)
13271327
return;
13281328
}
13291329

1330+
hid_destroy_device(steam->client_hdev);
13301331
cancel_delayed_work_sync(&steam->mode_switch);
13311332
cancel_work_sync(&steam->work_connect);
13321333
cancel_work_sync(&steam->rumble_work);
13331334
cancel_work_sync(&steam->unregister_work);
1334-
hid_destroy_device(steam->client_hdev);
13351335
steam->client_hdev = NULL;
13361336
steam->client_opened = 0;
13371337
if (steam->quirks & STEAM_QUIRK_WIRELESS) {

drivers/hid/i2c-hid/i2c-hid-core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ static int i2c_hid_get_report(struct i2c_hid *ihid,
290290
ihid->rawbuf, recv_len + sizeof(__le16));
291291
if (error) {
292292
dev_err(&ihid->client->dev,
293-
"failed to set a report to device: %d\n", error);
293+
"failed to get a report from device: %d\n", error);
294294
return error;
295295
}
296296

drivers/hid/intel-ish-hid/ishtp-hid-client.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,9 +832,9 @@ static void hid_ishtp_cl_remove(struct ishtp_cl_device *cl_device)
832832
hid_ishtp_cl);
833833

834834
dev_dbg(ishtp_device(cl_device), "%s\n", __func__);
835-
hid_ishtp_cl_deinit(hid_ishtp_cl);
836835
ishtp_put_device(cl_device);
837836
ishtp_hid_remove(client_data);
837+
hid_ishtp_cl_deinit(hid_ishtp_cl);
838838

839839
hid_ishtp_cl = NULL;
840840

drivers/hid/intel-ish-hid/ishtp-hid.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,12 +261,14 @@ int ishtp_hid_probe(unsigned int cur_hid_dev,
261261
*/
262262
void ishtp_hid_remove(struct ishtp_cl_data *client_data)
263263
{
264+
void *data;
264265
int i;
265266

266267
for (i = 0; i < client_data->num_hid_devices; ++i) {
267268
if (client_data->hid_sensor_hubs[i]) {
268-
kfree(client_data->hid_sensor_hubs[i]->driver_data);
269+
data = client_data->hid_sensor_hubs[i]->driver_data;
269270
hid_destroy_device(client_data->hid_sensor_hubs[i]);
271+
kfree(data);
270272
client_data->hid_sensor_hubs[i] = NULL;
271273
}
272274
}

0 commit comments

Comments
 (0)