Re: [PATCH 1/1] HID: wacom: Fix OOB write in wacom_hid_set_device_mode()

From: Ping Cheng

Date: Wed May 13 2026 - 12:33:12 EST


On Wed, May 13, 2026 at 1:05 AM Lee Jones <lee@xxxxxxxxxx> wrote:
>
> wacom_hid_set_device_mode() currently assumes that the HID_DG_INPUTMODE
> usage is always located in the first field (field[0]) of the feature report.
> However, a device can specify HID_DG_INPUTMODE in a different field.
>
> If HID_DG_INPUTMODE is in a field other than the first one and the first
> field has a report_count smaller than the usage_index of HID_DG_INPUTMODE,
> this leads to an out-of-bounds write to r->field[0]->value.
>
> Fix this by storing the field index of HID_DG_INPUTMODE in 'struct
> hid_data' during feature mapping. In wacom_hid_set_device_mode(), use
> this stored field index to access the correct field and add bounds
> checks to ensure both the field index and the value index are within
> valid ranges before writing.
>
> Cc: stable@xxxxxxxxxxxxxxx
> Fixes: 5ae6e89f7409 ("HID: wacom: implement the finger part of the HID generic handling")
> Signed-off-by: Lee Jones <lee@xxxxxxxxxx>

Patch looks sensible to me. Thank you for your effort, Lee!

Tested-by: Ping Cheng <ping.cheng@xxxxxxxxx>
Reviewed-by: Ping Cheng <ping.cheng@xxxxxxxxx>

Cheers,
Ping

> ---
> drivers/hid/wacom_sys.c | 13 ++++++++++---
> drivers/hid/wacom_wac.h | 1 +
> 2 files changed, 11 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
> index 1b1112772777..a6c5281afa06 100644
> --- a/drivers/hid/wacom_sys.c
> +++ b/drivers/hid/wacom_sys.c
> @@ -341,6 +341,7 @@ static void wacom_feature_mapping(struct hid_device *hdev,
>
> hid_data->inputmode = field->report->id;
> hid_data->inputmode_index = usage->usage_index;
> + hid_data->inputmode_field_index = field->index;
> break;
>
> case HID_UP_DIGITIZER:
> @@ -556,9 +557,14 @@ static int wacom_hid_set_device_mode(struct hid_device *hdev)
>
> re = &(hdev->report_enum[HID_FEATURE_REPORT]);
> r = re->report_id_hash[hid_data->inputmode];
> - if (r) {
> - r->field[0]->value[hid_data->inputmode_index] = 2;
> - hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
> + if (r && hid_data->inputmode_field_index >= 0 &&
> + hid_data->inputmode_field_index < r->maxfield) {
> + struct hid_field *field = r->field[hid_data->inputmode_field_index];
> +
> + if (field && hid_data->inputmode_index < field->report_count) {
> + field->value[hid_data->inputmode_index] = 2;
> + hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
> + }
> }
> return 0;
> }
> @@ -2819,6 +2825,7 @@ static int wacom_probe(struct hid_device *hdev,
> return error;
>
> wacom_wac->hid_data.inputmode = -1;
> + wacom_wac->hid_data.inputmode_field_index = -1;
> wacom_wac->mode_report = -1;
>
> if (hid_is_usb(hdev)) {
> diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
> index c8803d5c6a71..b2e74d7ab3c4 100644
> --- a/drivers/hid/wacom_wac.h
> +++ b/drivers/hid/wacom_wac.h
> @@ -298,6 +298,7 @@ struct wacom_shared {
> struct hid_data {
> __s16 inputmode; /* InputMode HID feature, -1 if non-existent */
> __s16 inputmode_index; /* InputMode HID feature index in the report */
> + __s16 inputmode_field_index; /* InputMode HID feature field index in the report */
> bool sense_state;
> bool inrange_state;
> bool invert_state;
> --
> 2.54.0.563.g4f69b47b94-goog
>
>