From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from messenger.jmp-e.com ([45.32.25.6]:43611 "EHLO messenger.jmp-e.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932302AbcISSSZ (ORCPT ); Mon, 19 Sep 2016 14:18:25 -0400 Date: Mon, 19 Sep 2016 19:09:51 +0100 From: James To: starblue@users.sourceforge.net Cc: gregkh@linuxfoundation.org, legousb-devel@lists.sourceforge.net, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, security@kernel.org, stable@vger.kernel.org Subject: [PATCH] usb: misc: legousbtower: Fix NULL pointer deference Message-ID: <20160919180950.GA26819@hostname> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="ZPt4rx8FFjLCG7dd" Content-Disposition: inline Sender: stable-owner@vger.kernel.org List-ID: --ZPt4rx8FFjLCG7dd Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline Content-Transfer-Encoding: quoted-printable This patch fixes a NULL pointer dereference caused by a race codition=20 in the probe function of the legousbtower driver. It re-structures the=20 probe function to only register the interface after successfully=20 reading the board's firmware ID. The probe function does not deregister the usb interface after an error receiving the devices firmware ID. The device file registered (/dev/usb/legousbtower%d) may be read/written globally before the probe function returns. When tower_delete is called in the probe function (after an r/w has been initiated), core dev structures are deleted while the file operation functions are still running. If the 0 address is=20 mappable on the machine, this vulnerability can be used to create a=20 Local Priviege Escalation exploit via a write-what-where condition by=20 remapping dev->interrupt_out_buffer in tower_write. A forged USB=20 device and local program execution would be required for LPE. The USB device would have to delay the control message in tower_probe and accept the control urb in tower_open whilst guest code initiated a write to the=20 device file as tower_delete is called from the error in tower_probe. This bug has existed since 2003. Patch tested by emulated device. Signed-off-by: James Patrick-Evans --- drivers/usb/misc/legousbtower.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtowe= r.c index 7771be3..4dd531a 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -898,24 +898,6 @@ static int tower_probe (struct usb_interface *interfac= e, const struct usb_device dev->interrupt_in_interval =3D interrupt_in_interval ? interrupt_in= _interval : dev->interrupt_in_endpoint->bInterval; dev->interrupt_out_interval =3D interrupt_out_interval ? interrupt_= out_interval : dev->interrupt_out_endpoint->bInterval; - /* we can register the device now, as it is ready */ - usb_set_intfdata (interface, dev); - - retval =3D usb_register_dev (interface, &tower_class); - - if (retval) { - /* something prevented us from registering this driver */ - dev_err(idev, "Not able to get a minor for this device.\n"); - usb_set_intfdata (interface, NULL); - goto error; - } - dev->minor =3D interface->minor; - - /* let the user know what node this device is now attached to */ - dev_info(&interface->dev, "LEGO USB Tower #%d now attached to major= " - "%d minor %d\n", (dev->minor - LEGO_USB_TOWER_MINOR_BASE), - USB_MAJOR, dev->minor); - /* get the firmware version and log it */ result =3D usb_control_msg (udev, usb_rcvctrlpipe(udev, 0), @@ -936,6 +918,23 @@ static int tower_probe (struct usb_interface *interfac= e, const struct usb_device get_version_reply.minor, le16_to_cpu(get_version_reply.build_no)); + /* we can register the device now, as it is ready */ + usb_set_intfdata (interface, dev); + + retval =3D usb_register_dev (interface, &tower_class); + + if (retval) { + /* something prevented us from registering this driver */ + dev_err(idev, "Not able to get a minor for this device.\n"); + usb_set_intfdata (interface, NULL); + goto error; + } + dev->minor =3D interface->minor; + + /* let the user know what node this device is now attached to */ + dev_info(&interface->dev, "LEGO USB Tower #%d now attached to major= " + "%d minor %d\n", (dev->minor - LEGO_USB_TOWER_MINOR_BASE), + USB_MAJOR, dev->minor); exit: return retval; -- --ZPt4rx8FFjLCG7dd Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBAgAGBQJX4CnmAAoJEF3Q5OlBOF7i6XcQAIoHNoKaBTafNgZ51md1EVYK UlsoSrwmcEh//pcX0n4opJQWxr0AJtL0oT+bshSxl/10mla3rK/bTnDcPFHPFLby mCLU5sfkZhQKt1FUpVjSz1V0ORH3XypfkhjlRFsLdUm2IMug9OO+HC8Ld0+xsuIt 4DdPxYb3PMPAmGGqrwOL2OVl0aFv9u2sNWGlegdTHN6my8w/GzLXbd1H0ghxxc+q DoTZFhNqEQvYxnGH23sJygGemsTVGNDzdc6iW5jPlc5PR+nTT8X5QuXwH3Dri2E+ HjYUSe7Ecz1QnzbeHWGu6cpUmTMxEQe+gbMBNIND1lADf+5VL4/dPVYpdGqrppiO yFNVGo+eI5EJA0Y6aPyTD8jbvcvV/7lVpI6tAHDJ9AEUlwiFNmcqemkem1xOEZnW RlPfdvG4uzUkBCse6nbil45qad+rBB1K2IuqjrBLwEHOBVQd+GCo9OKr58X0LbU+ HUzPyAgQi12OjBEbBfl+xo/+wRWsPMQRFKRh3dIiXzwzgUxZw7IxgqveKWj9SvAx yR2Ce3DQZ8O8rHHvo/8mm6ILUNwQ0mAXT2CJF6qxBYdsfauoL6SYRVPyyvUgMpZB zWHDr2HEUe7mXiy4xNSbi8X56IuuDrL1NvuFeSzznSQ5vaQoxpohDvffkEV2TRfP zQEMeXLNZ/TuO5pTlj4Y =DMBQ -----END PGP SIGNATURE----- --ZPt4rx8FFjLCG7dd--