Skip to content

Commit e82ae34

Browse files
antheasij-intel
authored andcommitted
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>
1 parent 6a293b6 commit e82ae34

1 file changed

Lines changed: 30 additions & 4 deletions

File tree

drivers/hid/hid-asus.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
4949
#define FEATURE_REPORT_ID 0x0d
5050
#define INPUT_REPORT_ID 0x5d
5151
#define FEATURE_KBD_REPORT_ID 0x5a
52-
#define FEATURE_KBD_REPORT_SIZE 16
52+
#define FEATURE_KBD_REPORT_SIZE 64
5353
#define FEATURE_KBD_LED_REPORT_ID1 0x5d
5454
#define FEATURE_KBD_LED_REPORT_ID2 0x5e
5555

@@ -395,15 +395,41 @@ static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t bu
395395

396396
static int asus_kbd_init(struct hid_device *hdev, u8 report_id)
397397
{
398+
/*
399+
* The handshake is first sent as a set_report, then retrieved
400+
* from a get_report. They should be equal.
401+
*/
398402
const u8 buf[] = { report_id, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
399403
0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
400404
int ret;
401405

402406
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+
}
405412

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;
407433
}
408434

409435
static int asus_kbd_get_functions(struct hid_device *hdev,

0 commit comments

Comments
 (0)