linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrey Konovalov <andreyknvl@google.com>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Henrik Rydberg <rydberg@bitmath.org>,
	"linux-input@vger.kernel.org" <linux-input@vger.kernel.org>,
	Felipe Balbi <balbi@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Johan Hovold <johan@kernel.org>, Peter Chen <peter.chen@nxp.com>,
	Yuyang Du <yuyang.du@intel.com>,
	USB list <linux-usb@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Dmitry Vyukov <dvyukov@google.com>,
	Kostya Serebryany <kcc@google.com>,
	syzkaller <syzkaller@googlegroups.com>
Subject: Re: usb/gadget: stalls in dummy_timer
Date: Tue, 19 Sep 2017 15:17:13 +0200	[thread overview]
Message-ID: <CAAeHK+ww_=YHBpCTf1kisLADR2DPNoE7OGNs4N9L_aee9X-MpQ@mail.gmail.com> (raw)
In-Reply-To: <Pine.LNX.4.44L0.1709151452090.26654-100000@netrider.rowland.org>

[-- Attachment #1: Type: text/plain, Size: 1896 bytes --]

On Fri, Sep 15, 2017 at 8:57 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Thu, 14 Sep 2017, Andrey Konovalov wrote:
>
>> On Thu, Sep 14, 2017 at 7:49 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
>> > On Thu, 14 Sep 2017, Andrey Konovalov wrote:
>> >
>> >> Looked at this a little more.
>> >>
>> >> dummy_timer() stucks in an infinite loop. It calls
>> >> usb_hcd_giveback_urb(), which in turn calls usbtouch_irq(), which
>> >> calls usb_submit_urb(), which calls dummy_urb_enqueue() and puts urb
>> >> back into dummy urb queue. dummy_timer() then does goto restart, finds
>> >> the urb and calls usb_hcd_giveback_urb() again. And this process goes
>> >> on again and again. It seems that something should either process the
>> >> urb and set urb->status or it should just expire.
>> >
>> > There is some throttling code, but it applies only to bulk transfers.
>> > Probably because the bandwidth limits for other types are slightly
>> > different.  However, I don't think we need to worry about this level of
>> > detail, since the driver makes a number of other approximations anyway.
>> >
>> > Try the patch below; it should fix the problem.
>>
>> Hi Alan,
>>
>> Just tried your patch, my reproducer still hangs the kernel until all
>> memory is exhausted.
>>
>> Thanks!
>
> Hmmm.  Your reproducer doesn't run on my system.  The mmap system call
> fails, perhaps because this laptop has a 32-bit kernel.  So I can't
> tell what's going on.
>
> Can you collect a usbmon trace that shows what happens while the
> reproducer runs?  If it turns out to be extremely large, just post an
> initial portion of it.

I've attached the usbmon trace. It's actually quite short, probably
due to the fact that the kernel enters infinite loop.

I've also attached a reproducer that should compile on a 32 bit
system, however I haven't tested whether it reproduces the issue.

>
> Alan Stern
>

[-- Attachment #2: dummy_timer-stall-usbmon --]
[-- Type: application/octet-stream, Size: 3154 bytes --]

# cat /sys/kernel/debug/usb/usbmon/0u
ffff8800677b8000 20592537 S Ci:1:001:0 s a3 00 0000 0001 0004 4 <
ffff8800677b8000 20592694 C Ci:1:001:0 0 4 = 01010100
ffff8800677b8100 20592772 S Co:1:001:0 s 23 01 0010 0001 0000 0
ffff8800677b8100 20592804 C Co:1:001:0 0 0
ffff880067664300 20695137 S Ii:1:001:1 -115:2048 4 <
ffff8800676e5400 20695211 S Ci:1:001:0 s a3 00 0000 0001 0004 4 <
ffff8800676e5400 20695248 C Ci:1:001:0 0 4 = 01010000
ffff8800676e5200 20695429 S Co:1:001:0 s 23 03 0004 0001 0000 0
ffff8800676e5200 20695489 C Co:1:001:0 0 0
ffff8800676e5300 20757138 S Ci:1:001:0 s a3 00 0000 0001 0004 4 <
ffff880067664300 20757192 C Ii:1:001:1 0:2048 1 = 02
ffff880067664300 20757205 S Ii:1:001:1 -115:2048 4 <
ffff8800676e5300 20757212 C Ci:1:001:0 0 4 = 03011000
ffff8800676e5600 20757384 S Co:1:001:0 s 23 01 0014 0001 0000 0
ffff8800676e5600 20757418 C Co:1:001:0 0 0
ffff8800676e5800 20810593 S Ci:1:000:0 s 80 06 0100 0000 0040 64 <
ffff8800676e5800 20812812 C Ci:1:000:0 0 18 = 12010002 fd040340 0304e9f9 04000408 ff01
ffff8800676e5900 20812929 S Co:1:001:0 s 23 03 0004 0001 0000 0
ffff8800676e5900 20814427 C Co:1:001:0 0 0
ffff8800676e5a00 20876140 S Ci:1:001:0 s a3 00 0000 0001 0004 4 <
ffff880067664300 20876198 C Ii:1:001:1 0:2048 1 = 02
ffff880067664300 20876206 S Ii:1:001:1 -115:2048 4 <
ffff8800676e5a00 20876213 C Ci:1:001:0 0 4 = 03011000
ffff880067e98f00 20876252 S Co:1:001:0 s 23 01 0014 0001 0000 0
ffff880067e98f00 20876275 C Co:1:001:0 0 0
ffff880067063b00 20928128 S Co:1:000:0 s 00 05 0002 0000 0000 0
ffff880067063b00 20930067 C Co:1:000:0 0 0
ffff880067063600 20942140 S Ci:1:002:0 s 80 06 0100 0000 0012 18 <
ffff880067063600 20944761 C Ci:1:002:0 0 18 = 12010002 fd040340 0304e9f9 04000408 ff01
ffff880067063500 20944833 S Ci:1:002:0 s 80 06 0600 0000 000a 10 <
ffff880067063500 20946092 C Ci:1:002:0 -32 0
ffff880067063a00 20946216 S Ci:1:002:0 s 80 06 0600 0000 000a 10 <
ffff880067063a00 20948081 C Ci:1:002:0 -32 0
ffff880067063400 20948211 S Ci:1:002:0 s 80 06 0600 0000 000a 10 <
ffff880067063400 20950065 C Ci:1:002:0 -32 0
ffff880067063700 20950216 S Ci:1:002:0 s 80 06 0200 0000 0009 9 <
ffff880067063700 20952094 C Ci:1:002:0 0 9 = 09023600 01080080 08
ffff880067063800 20952249 S Ci:1:002:0 s 80 06 0200 0000 0036 54 <
ffff880067063800 20954044 C Ci:1:002:0 0 54 = 09023600 01080080 08090400 0904ff03 00070905 09100100 0500ba09 058f0347
ffff880067063900 20962526 S Ci:1:002:0 s 80 06 0300 0000 00ff 255 <
ffff880067063900 20966043 C Ci:1:002:0 0 4 = 04030904
ffff880067345d00 20966155 S Ci:1:002:0 s 80 06 0308 0409 00ff 255 <
ffff880067345d00 20970091 C Ci:1:002:0 0 4 = 04036100
ffff88006a991f00 20970243 S Ci:1:002:0 s 80 06 0304 0409 00ff 255 <
ffff88006a991f00 20974091 C Ci:1:002:0 0 4 = 04036100
ffff88006a991e00 20974240 S Ci:1:002:0 s 80 06 03ff 0409 00ff 255 <
ffff88006a991e00 20978095 C Ci:1:002:0 0 4 = 04036100
ffff88006a991b00 20984396 S Co:1:002:0 s 00 09 0008 0000 0000 0
ffff88006a991b00 20988071 C Co:1:002:0 0 0
ffff88006a991500 20988382 S Ci:1:002:0 s 80 06 0307 0409 00ff 255 <
ffff88006a991500 20992040 C Ci:1:002:0 0 4 = 04036100
ffff880066891700 20996254 S Ii:1:002:15 -115:8 8 <

[-- Attachment #3: usbtouchscreen-hang-poc-x32.c --]
[-- Type: text/x-csrc, Size: 7297 bytes --]

// autogenerated by syzkaller (http://github.com/google/syzkaller)

#define _GNU_SOURCE

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadgetfs.h>
#include <poll.h>
#include <sched.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/inotify.h>
#include <sys/mount.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>

void gadgetfs_mkdir()
{
        mkdir("/dev/gadget", 0755) != 0;
}

void gadgetfs_mount()
{
        while (mount("none", "/dev/gadget", "gadgetfs", 0, NULL) != 0) {
                usleep(10 * 1000);
                umount2("/dev/gadget", MNT_FORCE | MNT_DETACH);
        }
}

static int
gfs_handle_event_setup_get_descriptor(int fd,
                                      struct usb_ctrlrequest* setup)
{
        char buffer[128];
        int rv;
        switch (setup->wValue >> 8) {
        case USB_DT_STRING:
                buffer[0] = 4;
                buffer[1] = USB_DT_STRING;
                if ((setup->wValue & 0x0ff) == 0) {
                        buffer[2] = 0x09;
                        buffer[3] = 0x04;
                } else {
                        buffer[2] = 0x61;
                        buffer[3] = 0x00;
                }
                rv = write(fd, &buffer[0], 4);
                if (rv != 4) {
                        return -1;
                }
                break;
        default:
                break;
        }
        return 0;
}

static int
gfs_handle_event_setup_set_configuration(int fd,
                                         struct usb_ctrlrequest* setup)
{
        int rv = read(fd, &rv, 0);
        if (rv != 0) {
                return -1;
        }
        return 0;
}

static int gfs_handle_event_setup(int fd, struct usb_ctrlrequest* setup)
{
        switch (setup->bRequest) {
        case USB_REQ_GET_DESCRIPTOR:
                gfs_handle_event_setup_get_descriptor(fd, setup);
                break;
        case USB_REQ_SET_CONFIGURATION:
                gfs_handle_event_setup_set_configuration(fd, setup);
                break;
        case USB_REQ_GET_INTERFACE:
                break;
        case USB_REQ_SET_INTERFACE:
                break;
        default:
                break;
        }
        return 0;
}

static int gfs_handle_event(int fd, struct usb_gadgetfs_event* event)
{
        switch (event->type) {
        case GADGETFS_NOP:
                break;
        case GADGETFS_CONNECT:
                break;
        case GADGETFS_SETUP:
                gfs_handle_event_setup(fd, &event->u.setup);
                break;
        case GADGETFS_DISCONNECT:
                break;
        case GADGETFS_SUSPEND:
                break;
        default:
                break;
        }
        return 0;
}

#define GFS_MAX_EVENTS 1

static int gfs_handle_ep0(int fd)
{
        struct pollfd pfd;
        struct usb_gadgetfs_event events[GFS_MAX_EVENTS];

        pfd.fd = fd;
        pfd.events = POLLIN | POLLOUT | POLLHUP;

        int i;
        for (i = 0; i < 15; i++) {
                int rv = poll(&pfd, 1, 100);
                if (rv < 0) {
                        return -1;
                }
                if (rv == 0)
                        continue;
                rv = read(fd, &events[0], sizeof(events));
                if (rv < 0) {
                        return -2;
                }
                if (rv == 0)
                        continue;
                gfs_handle_event(fd, &events[0]);
        }

        return 0;
}

static uintptr_t syz_usb_config(uintptr_t a0, uintptr_t a1)
{
        int fd = open("/dev/gadget/dummy_udc", O_RDWR);
        if (fd < 0)
                return -1;

        usleep(30 * 1000);

        int64_t length = a0;
        char* data = (char*)a1;
        int rv = write(fd, data, length);
        if (rv < 0) {
                return -2;
        }

        gfs_handle_ep0(fd);

        return fd;
}

long r[66];

void loop()
{
        memset(r, -1, sizeof(r));
        r[0] = (long)mmap((void*)0x23000ul, 0x1000ul, 0x3ul, 0x32ul,
                       0xfffffffful, 0x0ul);
        *(uint32_t*)0x23000 = (uint32_t)0x0;
        *(uint8_t*)0x23004 = (uint8_t)0x9;
        *(uint8_t*)0x23005 = (uint8_t)0x2;
        *(uint16_t*)0x23006 = (uint16_t)0x36;
        *(uint8_t*)0x23008 = (uint8_t)0x1;
        *(uint8_t*)0x23009 = (uint8_t)0x8;
        *(uint8_t*)0x2300a = (uint8_t)0x600;
        *(uint8_t*)0x2300b = (uint8_t)0x80;
        *(uint8_t*)0x2300c = (uint8_t)0x8;
        *(uint8_t*)0x2300d = (uint8_t)0x9;
        *(uint8_t*)0x2300e = (uint8_t)0x4;
        *(uint8_t*)0x2300f = (uint8_t)0x0;
        *(uint8_t*)0x23010 = (uint8_t)0x9;
        *(uint8_t*)0x23011 = (uint8_t)0x4;
        *(uint8_t*)0x23012 = (uint8_t)0xff;
        *(uint8_t*)0x23013 = (uint8_t)0x3;
        *(uint8_t*)0x23014 = (uint8_t)0x0;
        *(uint8_t*)0x23015 = (uint8_t)0x7;
        *(uint8_t*)0x23016 = (uint8_t)0x9;
        *(uint8_t*)0x23017 = (uint8_t)0x5;
        *(uint8_t*)0x23018 = (uint8_t)0x9;
        *(uint8_t*)0x23019 = (uint8_t)0x10;
        *(uint16_t*)0x2301a = (uint16_t)0x1;
        *(uint8_t*)0x2301c = (uint8_t)0x5;
        *(uint8_t*)0x2301d = (uint8_t)0xfffff800;
        *(uint8_t*)0x2301e = (uint8_t)0x2bba;
        *(uint8_t*)0x2301f = (uint8_t)0x9;
        *(uint8_t*)0x23020 = (uint8_t)0x5;
        *(uint8_t*)0x23021 = (uint8_t)0x898f;
        *(uint8_t*)0x23022 = (uint8_t)0x3;
        *(uint16_t*)0x23023 = (uint16_t)0x7c113347;
        *(uint8_t*)0x23025 = (uint8_t)0x0;
        *(uint8_t*)0x23026 = (uint8_t)0xbc;
        *(uint8_t*)0x23027 = (uint8_t)0x5;
        *(uint8_t*)0x23028 = (uint8_t)0x9;
        *(uint8_t*)0x23029 = (uint8_t)0x5;
        *(uint8_t*)0x2302a = (uint8_t)0x7;
        *(uint8_t*)0x2302b = (uint8_t)0x14;
        *(uint16_t*)0x2302c = (uint16_t)0x972f;
        *(uint8_t*)0x2302e = (uint8_t)0x1f;
        *(uint8_t*)0x2302f = (uint8_t)0x7;
        *(uint8_t*)0x23030 = (uint8_t)0x3f;
        *(uint8_t*)0x23031 = (uint8_t)0x9;
        *(uint8_t*)0x23032 = (uint8_t)0x5;
        *(uint8_t*)0x23033 = (uint8_t)0x8;
        *(uint8_t*)0x23034 = (uint8_t)0x0;
        *(uint16_t*)0x23035 = (uint16_t)0x7;
        *(uint8_t*)0x23037 = (uint8_t)0x81;
        *(uint8_t*)0x23038 = (uint8_t)0x7ff;
        *(uint8_t*)0x23039 = (uint8_t)0x200;
        *(uint8_t*)0x2303a = (uint8_t)0x12;
        *(uint8_t*)0x2303b = (uint8_t)0x1;
        *(uint16_t*)0x2303c = (uint16_t)0xffffffff;
        *(uint8_t*)0x2303e = (uint8_t)0x7fd;
        *(uint8_t*)0x2303f = (uint8_t)0x4;
        *(uint8_t*)0x23040 = (uint8_t)0x3;
        *(uint8_t*)0x23041 = (uint8_t)0x1000;
        *(uint16_t*)0x23042 = (uint16_t)0x403;
        *(uint16_t*)0x23044 = (uint16_t)0x1000f9e9;
        *(uint16_t*)0x23046 = (uint16_t)0x4;
        *(uint8_t*)0x23048 = (uint8_t)0x4;
        *(uint8_t*)0x23049 = (uint8_t)0x8;
        *(uint8_t*)0x2304a = (uint8_t)0x7ff;
        *(uint8_t*)0x2304b = (uint8_t)0x1;
        r[65] = syz_usb_config(0x4cul, 0x23000ul);
}

int main()
{
        gadgetfs_mkdir();
        gadgetfs_mount();
        loop();
        return 0;
}

  reply	other threads:[~2017-09-19 13:17 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CAAeHK+y-gycNCJv3XEZ4hwv_BndB590UWVqCYWd-Y8URDbH+vg@mail.gmail.com>
     [not found] ` <Pine.LNX.4.44L0.1709110920020.27275-100000@netrider.rowland.org>
2017-09-11 15:15   ` usb/gadget: stalls in dummy_timer Andrey Konovalov
2017-09-11 17:27     ` Andrey Konovalov
2017-09-11 18:54     ` Dmitry Torokhov
2017-09-12 15:48       ` Andrey Konovalov
     [not found]         ` <CAAeHK+yDjw3sh=7nCEZTRqHPWUwxKNfQ1-WVq5=K2PWK5E2FFw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-09-12 17:06           ` Dmitry Torokhov
2017-09-12 17:44             ` Andrey Konovalov
2017-09-14 16:02               ` Andrey Konovalov
2017-09-14 17:49                 ` Alan Stern
2017-09-14 17:58                   ` Andrey Konovalov
2017-09-15 18:57                     ` Alan Stern
2017-09-19 13:17                       ` Andrey Konovalov [this message]
2017-09-19 17:17                         ` Alan Stern
2017-09-19 17:29                           ` Andrey Konovalov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAAeHK+ww_=YHBpCTf1kisLADR2DPNoE7OGNs4N9L_aee9X-MpQ@mail.gmail.com' \
    --to=andreyknvl@google.com \
    --cc=balbi@kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=dvyukov@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=johan@kernel.org \
    --cc=kcc@google.com \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=peter.chen@nxp.com \
    --cc=rydberg@bitmath.org \
    --cc=stern@rowland.harvard.edu \
    --cc=syzkaller@googlegroups.com \
    --cc=yuyang.du@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).