lkml.org 
[lkml]   [2019]   [Dec]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.19 059/177] usb: usbfs: Suppress problematic bind and unbind uevents.
    Date
    From: Ingo Rohloff <ingo.rohloff@lauterbach.com>

    [ Upstream commit abb0b3d96a1f9407dd66831ae33985a386d4200d ]

    commit 1455cf8dbfd0 ("driver core: emit uevents when device is bound
    to a driver") added bind and unbind uevents when a driver is bound or
    unbound to a physical device.

    For USB devices which are handled via the generic usbfs layer (via
    libusb for example), this is problematic:
    Each time a user space program calls
    ioctl(usb_fd, USBDEVFS_CLAIMINTERFACE, &usb_intf_nr);
    and then later
    ioctl(usb_fd, USBDEVFS_RELEASEINTERFACE, &usb_intf_nr);
    The kernel will now produce a bind or unbind event, which does not
    really contain any useful information.

    This allows a user space program to run a DoS attack against programs
    which listen to uevents (in particular systemd/eudev/upowerd):
    A malicious user space program just has to call in a tight loop

    ioctl(usb_fd, USBDEVFS_CLAIMINTERFACE, &usb_intf_nr);
    ioctl(usb_fd, USBDEVFS_RELEASEINTERFACE, &usb_intf_nr);

    With this loop the malicious user space program floods the kernel and
    all programs listening to uevents with tons of bind and unbind
    events.

    This patch suppresses uevents for ioctls USBDEVFS_CLAIMINTERFACE and
    USBDEVFS_RELEASEINTERFACE.

    Signed-off-by: Ingo Rohloff <ingo.rohloff@lauterbach.com>
    Link: https://lore.kernel.org/r/20191011115518.2801-1-ingo.rohloff@lauterbach.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/usb/core/devio.c | 15 ++++++++++++++-
    1 file changed, 14 insertions(+), 1 deletion(-)

    diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
    index 29c6414f48f13..00204824bffd8 100644
    --- a/drivers/usb/core/devio.c
    +++ b/drivers/usb/core/devio.c
    @@ -739,8 +739,15 @@ static int claimintf(struct usb_dev_state *ps, unsigned int ifnum)
    intf = usb_ifnum_to_if(dev, ifnum);
    if (!intf)
    err = -ENOENT;
    - else
    + else {
    + unsigned int old_suppress;
    +
    + /* suppress uevents while claiming interface */
    + old_suppress = dev_get_uevent_suppress(&intf->dev);
    + dev_set_uevent_suppress(&intf->dev, 1);
    err = usb_driver_claim_interface(&usbfs_driver, intf, ps);
    + dev_set_uevent_suppress(&intf->dev, old_suppress);
    + }
    if (err == 0)
    set_bit(ifnum, &ps->ifclaimed);
    return err;
    @@ -760,7 +767,13 @@ static int releaseintf(struct usb_dev_state *ps, unsigned int ifnum)
    if (!intf)
    err = -ENOENT;
    else if (test_and_clear_bit(ifnum, &ps->ifclaimed)) {
    + unsigned int old_suppress;
    +
    + /* suppress uevents while releasing interface */
    + old_suppress = dev_get_uevent_suppress(&intf->dev);
    + dev_set_uevent_suppress(&intf->dev, 1);
    usb_driver_release_interface(&usbfs_driver, intf);
    + dev_set_uevent_suppress(&intf->dev, old_suppress);
    err = 0;
    }
    return err;
    --
    2.20.1
    \
     
     \ /
      Last update: 2019-12-10 22:44    [W:4.510 / U:0.072 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site