Received: by 2002:a05:6a10:17d3:0:0:0:0 with SMTP id hz19csp2948473pxb; Tue, 13 Apr 2021 14:29:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy959QOXPNG4YfmtyJhtXoqH9XP7Q2qDcoEGCohM7PbmF1tg6Bsa7+1mQqLKFDJJr0lV1w/ X-Received: by 2002:a17:906:2da9:: with SMTP id g9mr33079681eji.100.1618349341794; Tue, 13 Apr 2021 14:29:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1618349341; cv=none; d=google.com; s=arc-20160816; b=0zYi00eAoKmjo4Mq9RNNfDFqL40cm7vF0v+Ho6vgDkdtBVX6A7vpqTyEbw2UEgr5zl H7RypeWCJN1Fu0K98ujbOXce3eZt1eEMflSjOWRk6eafsGck2qMgqBchq+nDiyjXE2cV vVK85I7nmGQ2bSxx3eUrIJKsAXB7PMfG31OaeNhuu8yNJJ9Tr6JxqdRjWEfBocQ+ag0l kmo/RxoG0wLOQr7cs/HHfQUIDVsjDszSVwgcmFE+ASPKA5b92ujqQ39XWx6F3THmaClC Mcr5GHhTPNkRqvPnYFyHtGVktfVme6zNa+jsSc1svsQwWBjX8sk2m/4mmzCFRl4wYQNR 7yww== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:user-agent:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date; bh=xFYHHpaaqP6XG6DkTXq0gjKnf9gin9kotGIvt3iDgn4=; b=IfGqA52tYDMYTSY+RiMUrZrl0Ox024YrLN4/Q/Dnuo31T4VAomV3W3gGNBkYqIp5Md /GqP2AohrWzoo7lkqclyHWT0MQ4jB8x9AyfntRkDW/Lc1+JiVbKu68mjpcfBjhHAp8wA RYdIwinRUIUBYjO480mNT1sBXwRth3Znpj1DOz4R+Osikn3iliHFUAmi5P+OOXpNZRuZ 0GMClAxn0uymsWlETG2KPBcRKWsa11wV8wSwChADTzVdLPngbq19jSJmkbsNDLxewQKc erR383s88HZv+spBOOHxNUMA3TAMImxW0FbMDE0OqlRHu8hCzjeXylZ2cDhYO34kQ1/f IIeg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id re11si7046884ejb.590.2021.04.13.14.28.39; Tue, 13 Apr 2021 14:29:01 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231313AbhDMQNd (ORCPT + 99 others); Tue, 13 Apr 2021 12:13:33 -0400 Received: from netrider.rowland.org ([192.131.102.5]:52115 "HELO netrider.rowland.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S229688AbhDMQNc (ORCPT ); Tue, 13 Apr 2021 12:13:32 -0400 Received: (qmail 1460435 invoked by uid 1000); 13 Apr 2021 12:13:11 -0400 Date: Tue, 13 Apr 2021 12:13:11 -0400 From: Alan Stern To: Dmitry Vyukov Cc: syzbot , Andrey Konovalov , Felipe Balbi , Dan Carpenter , Greg Kroah-Hartman , LKML , USB list , syzkaller-bugs Subject: Re: [syzbot] general protection fault in gadget_setup Message-ID: <20210413161311.GC1454681@rowland.harvard.edu> References: <00000000000075c58405bfd6228c@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Apr 13, 2021 at 10:12:05AM +0200, Dmitry Vyukov wrote: > On Tue, Apr 13, 2021 at 10:08 AM syzbot > wrote: > > > > Hello, > > > > syzbot found the following issue on: > > > > HEAD commit: 0f4498ce Merge tag 'for-5.12/dm-fixes-2' of git://git.kern.. > > git tree: upstream > > console output: https://syzkaller.appspot.com/x/log.txt?x=124adbf6d00000 > > kernel config: https://syzkaller.appspot.com/x/.config?x=daeff30c2474a60f > > dashboard link: https://syzkaller.appspot.com/bug?extid=eb4674092e6cc8d9e0bd > > userspace arch: i386 > > > > Unfortunately, I don't have any reproducer for this issue yet. > > > > IMPORTANT: if you fix the issue, please add the following tag to the commit: > > Reported-by: syzbot+eb4674092e6cc8d9e0bd@syzkaller.appspotmail.com > > I suspect that the raw gadget_unbind() can be called while the timer > is still active. gadget_unbind() sets gadget data to NULL. > But I am not sure which unbind call this is: > usb_gadget_remove_driver() or right in udc_bind_to_driver() due to a > start error. This certainly looks like a race between gadget_unbind and gadget_setup in raw_gadget. In theory, this race shouldn't matter. The gadget core is supposed to guarantee that there won't be any more callbacks to the gadget driver once the driver's unbind routine is called. That guarantee is enforced in usb_gadget_remove_driver as follows: usb_gadget_disconnect(udc->gadget); if (udc->gadget->irq) synchronize_irq(udc->gadget->irq); udc->driver->unbind(udc->gadget); usb_gadget_udc_stop(udc); usb_gadget_disconnect turns off the pullup resistor, telling the host that the gadget is no longer connected and preventing the transmission of any more USB packets. Any packets that have already been received are sure to processed by the UDC driver's interrupt handler by the time synchronize_irq returns. But this doesn't work with dummy_hcd, because dummy_hcd doesn't use interrupts; it uses a timer instead. It does have code to emulate the effect of synchronize_irq, but that code doesn't get invoked at the right time -- it currently runs in usb_gadget_udc_stop, after the unbind callback instead of before. Indeed, there's no way for usb_gadget_remove_driver to invoke this code before the unbind callback,. I thought the synchronize_irq emulation problem had been completely solved, but evidently it hasn't. It looks like the best solution is to add a call of the synchronize_irq emulation code in dummy_pullup. Maybe we can test this reasoning by putting a delay just before the call to dum->driver->setup. That runs in the timer handler, so it's not a good place to delay, but it may be okay just for testing purposes. Hopefully this patch will make the race a lot more likely to occur. Is there any way to tell syzkaller to test it, despite the fact that syzkaller doesn't think it has a reproducer for this issue? Alan Stern Index: usb-devel/drivers/usb/gadget/udc/dummy_hcd.c =================================================================== --- usb-devel.orig/drivers/usb/gadget/udc/dummy_hcd.c +++ usb-devel/drivers/usb/gadget/udc/dummy_hcd.c @@ -1900,6 +1900,7 @@ restart: if (value > 0) { ++dum->callback_usage; spin_unlock(&dum->lock); + mdelay(5); value = dum->driver->setup(&dum->gadget, &setup); spin_lock(&dum->lock);