[PATCH 3/3] Input: xpad - add sdata_check() to xpad360 branches
Griffin Kroah-Hartman <[email protected]> Mon, 03 Aug 2026 17:07:26 +0200
| Newsgroups | org.kernel.vger.linux-input,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Add the sdata_check() safety wrapper to the xpad360_process_packet() and xpad360w_process_packet() functions, covering the Xbox 360 wired and wireless controllers. Suggested-by: Ingo Molnar <[email protected]> Suggested-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Griffin Kroah-Hartman <[email protected]> --- drivers/input/joystick/xpad.c | 75 +++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 319a4c4a695f..304229782e45 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -891,19 +891,24 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d */ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev, - u16 cmd, unsigned char *data) + u16 cmd, unsigned char *data, u32 len) { + struct safe_data sdata; + + sdata.data = data; + sdata.len = len; + /* valid pad data */ - if (data[0] != 0x00) + if (sdata_check(&sdata, 0) != 0x00) return; /* digital pad */ if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { /* dpad as buttons (left, right, up, down) */ - input_report_key(dev, BTN_DPAD_LEFT, data[2] & BIT(2)); - input_report_key(dev, BTN_DPAD_RIGHT, data[2] & BIT(3)); - input_report_key(dev, BTN_DPAD_UP, data[2] & BIT(0)); - input_report_key(dev, BTN_DPAD_DOWN, data[2] & BIT(1)); + input_report_key(dev, BTN_DPAD_LEFT, sdata_check(&sdata, 2) & BIT(2)); + input_report_key(dev, BTN_DPAD_RIGHT, sdata_check(&sdata, 2) & BIT(3)); + input_report_key(dev, BTN_DPAD_UP, sdata_check(&sdata, 2) & BIT(0)); + input_report_key(dev, BTN_DPAD_DOWN, sdata_check(&sdata, 2) & BIT(1)); } /* @@ -915,27 +920,29 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev, if (!(xpad->mapping & MAP_DPAD_TO_BUTTONS) || xpad->xtype == XTYPE_XBOX360W) { input_report_abs(dev, ABS_HAT0X, - !!(data[2] & 0x08) - !!(data[2] & 0x04)); + !!(sdata_check(&sdata, 2) & 0x08) - + !!(sdata_check(&sdata, 2) & 0x04)); input_report_abs(dev, ABS_HAT0Y, - !!(data[2] & 0x02) - !!(data[2] & 0x01)); + !!(sdata_check(&sdata, 2) & 0x02) - + !!(sdata_check(&sdata, 2) & 0x01)); } /* start/back buttons */ - input_report_key(dev, BTN_START, data[2] & BIT(4)); - input_report_key(dev, BTN_SELECT, data[2] & BIT(5)); + input_report_key(dev, BTN_START, sdata_check(&sdata, 2) & BIT(4)); + input_report_key(dev, BTN_SELECT, sdata_check(&sdata, 2) & BIT(5)); /* stick press left/right */ - input_report_key(dev, BTN_THUMBL, data[2] & BIT(6)); - input_report_key(dev, BTN_THUMBR, data[2] & BIT(7)); + input_report_key(dev, BTN_THUMBL, sdata_check(&sdata, 2) & BIT(6)); + input_report_key(dev, BTN_THUMBR, sdata_check(&sdata, 2) & BIT(7)); /* buttons A,B,X,Y,TL,TR and MODE */ - input_report_key(dev, BTN_A, data[3] & BIT(4)); - input_report_key(dev, BTN_B, data[3] & BIT(5)); - input_report_key(dev, BTN_X, data[3] & BIT(6)); - input_report_key(dev, BTN_Y, data[3] & BIT(7)); - input_report_key(dev, BTN_TL, data[3] & BIT(0)); - input_report_key(dev, BTN_TR, data[3] & BIT(1)); - input_report_key(dev, BTN_MODE, data[3] & BIT(2)); + input_report_key(dev, BTN_A, sdata_check(&sdata, 3) & BIT(4)); + input_report_key(dev, BTN_B, sdata_check(&sdata, 3) & BIT(5)); + input_report_key(dev, BTN_X, sdata_check(&sdata, 3) & BIT(6)); + input_report_key(dev, BTN_Y, sdata_check(&sdata, 3) & BIT(7)); + input_report_key(dev, BTN_TL, sdata_check(&sdata, 3) & BIT(0)); + input_report_key(dev, BTN_TR, sdata_check(&sdata, 3) & BIT(1)); + input_report_key(dev, BTN_MODE, sdata_check(&sdata, 3) & BIT(2)); if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { /* left stick */ @@ -953,11 +960,11 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev, /* triggers left/right */ if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { - input_report_key(dev, BTN_TL2, data[4]); - input_report_key(dev, BTN_TR2, data[5]); + input_report_key(dev, BTN_TL2, sdata_check(&sdata, 4)); + input_report_key(dev, BTN_TR2, sdata_check(&sdata, 5)); } else { - input_report_abs(dev, ABS_Z, data[4]); - input_report_abs(dev, ABS_RZ, data[5]); + input_report_abs(dev, ABS_Z, sdata_check(&sdata, 4)); + input_report_abs(dev, ABS_RZ, sdata_check(&sdata, 5)); } input_sync(dev); @@ -973,7 +980,7 @@ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev, } /* mode button down/up */ - if (data[3] & BIT(2)) + if (sdata_check(&sdata, 3) & BIT(2)) xpad->mode_btn_down_ts = ktime_get_seconds(); else xpad->mode_btn_down_ts = 0; @@ -1019,14 +1026,18 @@ static void xpad_presence_work(struct work_struct *work) * 01.1 - Pad state (Bytes 4+) valid * */ -static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) +static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, u32 len) { struct input_dev *dev; + struct safe_data sdata; bool present; + sdata.data = data; + sdata.len = len; + /* Presence change */ - if (data[0] & 0x08) { - present = (data[1] & 0x80) != 0; + if (sdata_check(&sdata, 0) & 0x08) { + present = (sdata_check(&sdata, 1) & 0x80) != 0; if (xpad->pad_present != present) { xpad->pad_present = present; @@ -1035,13 +1046,13 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha } /* Valid pad data */ - if (data[1] != 0x1) + if (sdata_check(&sdata, 1) != 0x1) return; rcu_read_lock(); dev = rcu_dereference(xpad->x360w_dev); - if (dev) - xpad360_process_packet(xpad, dev, cmd, &data[4]); + if (dev && len > 4) + xpad360_process_packet(xpad, dev, cmd, &data[4], len - 4); rcu_read_unlock(); } @@ -1262,10 +1273,10 @@ static void xpad_irq_in(struct urb *urb) switch (xpad->xtype) { case XTYPE_XBOX360: - xpad360_process_packet(xpad, xpad->dev, 0, xpad->idata); + xpad360_process_packet(xpad, xpad->dev, 0, xpad->idata, urb->actual_length); break; case XTYPE_XBOX360W: - xpad360w_process_packet(xpad, 0, xpad->idata); + xpad360w_process_packet(xpad, 0, xpad->idata, urb->actual_length); break; case XTYPE_XBOXONE: xpadone_process_packet(xpad, 0, xpad->idata, urb->actual_length); -- 2.55.0