From patchwork Sun Jun 5 05:10:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cameron Gutman X-Patchwork-Id: 9155067 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 00C3960573 for ; Sun, 5 Jun 2016 05:10:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E6D0A281AA for ; Sun, 5 Jun 2016 05:10:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DA077281FE; Sun, 5 Jun 2016 05:10:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 76C9F281AA for ; Sun, 5 Jun 2016 05:10:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751699AbcFEFKN (ORCPT ); Sun, 5 Jun 2016 01:10:13 -0400 Received: from mail-oi0-f66.google.com ([209.85.218.66]:35957 "EHLO mail-oi0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751342AbcFEFKM (ORCPT ); Sun, 5 Jun 2016 01:10:12 -0400 Received: by mail-oi0-f66.google.com with SMTP id n3so3469916oig.3 for ; Sat, 04 Jun 2016 22:10:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=to:from:subject:message-id:date:user-agent:mime-version :content-transfer-encoding; bh=VYnc8hDikY2teOvwdwModY/z0MWeRZAp9yPlnDDhaPo=; b=oHGe6FiGt5eU/sOU+OVSYByBawJxYGl3dd6GSJ6cmiSsw0etAcb2i3IrOJfTAl7636 MKfeVvcXZDZtSfHjvArsnY8CJ7XuHEO3jbaDlzb+wSSPayYFsADwZKY4dWu0y/NGerMc juVt95iBSqvuneq4PpuIO1sATeVX8XwrxN/OF9KOfA4hKsv9H67xiK9kPxRVHe36zpDC QdeKic+/SDk4srKqJVSeC6DmnmwXlTedz2+zmLbDWgUpbg8f9WmiaJLR0BYt0RbCPhvV hPd3H7Ajfp6lFH1QwtzI6bfgn5uVAZk03Q//JltqavK7mxtY/QNhxswXNV8jKq5IIsyT PViA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version:content-transfer-encoding; bh=VYnc8hDikY2teOvwdwModY/z0MWeRZAp9yPlnDDhaPo=; b=hAXQ4VPOc1OBMCLD/sQvUaOLjc/7oIwJlBM9WmsgAte5el9723Ss8yFKWl5861Pe/O zui2Y2YgZxBva1libDDmdo9dpx1WIgv6SxMdp287Z0UxxkI5ww1GWcldiwApZg9/pTbG LiAZXnGIFXtfF+wirfqK2hV8zyRIHSFWeJ2219GtjHQRIvWkkErRQNw2lmzYx1Y3cg5w x5XKQt1zBVSV0hlN5s/X6po/8F7GnWtelNx8Fb7F4qFilgMgzfVG9yduACxp2gdC0J5L hn8fgGqkEWwyfoYEMqyist36A7tlUFzruLDqzRUO3aaA6+ficlpRkqvNOTWkqW8FnCvi 4HFg== X-Gm-Message-State: ALyK8tKFboMw5zPLY9FXfpMR4p03AGKmkInuhXN48SRxuA9V+patAQNdYbyUZfqSq1OQdg== X-Received: by 10.202.225.8 with SMTP id y8mr6021280oig.192.1465103411345; Sat, 04 Jun 2016 22:10:11 -0700 (PDT) Received: from ?IPv6:2601:2c6:c000:f778:e53d:f848:c172:2f3c? ([2601:2c6:c000:f778:e53d:f848:c172:2f3c]) by smtp.gmail.com with ESMTPSA id t23sm7479773ota.14.2016.06.04.22.10.10 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 04 Jun 2016 22:10:10 -0700 (PDT) To: linux-input@vger.kernel.org, dmitry.torokhov@gmail.com From: Cameron Gutman Subject: [PATCH] Input: xpad - fix oops when attaching an unknown Xbox One gamepad Message-ID: <5753B431.2040908@gmail.com> Date: Sun, 5 Jun 2016 00:10:09 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.8.0 MIME-Version: 1.0 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Xbox One controllers have multiple interfaces which all have the same class, subclass, and protocol. One of the these interfaces has only a single endpoint. When Xpad attempts to bind to this interface, it causes an oops when trying initialize the output URB by trying to access the second endpoint's descriptor. This situation was avoided for known Xbox One devices by checking the XTYPE constant associated with the VID and PID tuple. However, this breaks when new or previously unknown Xbox One controllers are attached to the system. This change addresses the problem by deriving the XTYPE for Xbox One controllers based on the interface protocol before checking the interface number. Fixes: 1a48ff81b391 ("Input: xpad - add support for Xbox One controllers") Signed-off-by: Cameron Gutman Cc: stable@vger.kernel.org --- This bug affects kernels since 3.18. Controllers upgraded to the 2015 firmware will trigger the oops on affected kernels (up to 4.4 when the new device ID was added). The Xbox One Elite controller will likely also trigger the oops up to 4.6 (though I've not tested myself) along with any new third-party Xbox One controllers that are released. There are a few ways we could address it, but this one seems nice because it allows the controller to work correctly (as opposed to simply kicking out interfaces without enough endpoints). --- drivers/input/joystick/xpad.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 923c572..3438e98 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -1437,16 +1437,6 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id break; } - if (xpad_device[i].xtype == XTYPE_XBOXONE && - intf->cur_altsetting->desc.bInterfaceNumber != 0) { - /* - * The Xbox One controller lists three interfaces all with the - * same interface class, subclass and protocol. Differentiate by - * interface number. - */ - return -ENODEV; - } - xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); if (!xpad) return -ENOMEM; @@ -1478,6 +1468,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) xpad->xtype = XTYPE_XBOX360W; + else if (intf->cur_altsetting->desc.bInterfaceProtocol == 208) + xpad->xtype = XTYPE_XBOXONE; else xpad->xtype = XTYPE_XBOX360; } else { @@ -1492,6 +1484,17 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->mapping |= MAP_STICKS_TO_NULL; } + if (xpad->xtype == XTYPE_XBOXONE && + intf->cur_altsetting->desc.bInterfaceNumber != 0) { + /* + * The Xbox One controller lists three interfaces all with the + * same interface class, subclass and protocol. Differentiate by + * interface number. + */ + error = -ENODEV; + goto err_free_in_urb; + } + error = xpad_init_output(intf, xpad); if (error) goto err_free_in_urb;