Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

HID: asus: fortify keyboard handshake

Handshaking with an Asus device involves sending it a feature report
with the string "ASUS Tech.Inc." and then reading it back to verify the
handshake was successful, under the feature ID the interaction will
take place.

Currently, the driver only does the first part. Add the readback to
verify the handshake was successful. As this could cause breakages,
allow the verification to fail with a dmesg error until we verify
all devices work with it (they seem to).

Since the response is more than 16 bytes, increase the buffer size
to 64 as well to avoid overflow errors. In addition, add the report
ID to prints, to help identify failed handshakes.

Reviewed-by: Benjamin Tissoires <bentiss@kernel.org>
Reviewed-by: Denis Benato <benato.denis96@gmail.com>
Acked-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
Link: https://patch.msgid.link/20260122075044.5070-5-lkml@antheas.dev
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

authored by

Antheas Kapenekakis and committed by
Ilpo Järvinen
e82ae34a 6a293b6e

+30 -4
+30 -4
drivers/hid/hid-asus.c
··· 49 49 #define FEATURE_REPORT_ID 0x0d 50 50 #define INPUT_REPORT_ID 0x5d 51 51 #define FEATURE_KBD_REPORT_ID 0x5a 52 - #define FEATURE_KBD_REPORT_SIZE 16 52 + #define FEATURE_KBD_REPORT_SIZE 64 53 53 #define FEATURE_KBD_LED_REPORT_ID1 0x5d 54 54 #define FEATURE_KBD_LED_REPORT_ID2 0x5e 55 55 ··· 395 395 396 396 static int asus_kbd_init(struct hid_device *hdev, u8 report_id) 397 397 { 398 + /* 399 + * The handshake is first sent as a set_report, then retrieved 400 + * from a get_report. They should be equal. 401 + */ 398 402 const u8 buf[] = { report_id, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, 399 403 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; 400 404 int ret; 401 405 402 406 ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); 403 - if (ret < 0) 404 - hid_err(hdev, "Asus failed to send init command: %d\n", ret); 407 + if (ret < 0) { 408 + hid_err(hdev, "Asus handshake %02x failed to send: %d\n", 409 + report_id, ret); 410 + return ret; 411 + } 405 412 406 - return ret; 413 + u8 *readbuf __free(kfree) = kzalloc(FEATURE_KBD_REPORT_SIZE, GFP_KERNEL); 414 + if (!readbuf) 415 + return -ENOMEM; 416 + 417 + ret = hid_hw_raw_request(hdev, report_id, readbuf, 418 + FEATURE_KBD_REPORT_SIZE, HID_FEATURE_REPORT, 419 + HID_REQ_GET_REPORT); 420 + if (ret < 0) { 421 + hid_warn(hdev, "Asus handshake %02x failed to receive ack: %d\n", 422 + report_id, ret); 423 + } else if (memcmp(readbuf, buf, sizeof(buf)) != 0) { 424 + hid_warn(hdev, "Asus handshake %02x returned invalid response: %*ph\n", 425 + report_id, FEATURE_KBD_REPORT_SIZE, readbuf); 426 + } 427 + 428 + /* 429 + * Do not return error if handshake is wrong until this is 430 + * verified to work for all devices. 431 + */ 432 + return 0; 407 433 } 408 434 409 435 static int asus_kbd_get_functions(struct hid_device *hdev,