Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp2214192ybz; Sat, 18 Apr 2020 18:40:56 -0700 (PDT) X-Google-Smtp-Source: APiQypK9p2IHr6pF9Go2xQkJQfJS3q1F7pMiYfU1DtxDFoNwviDzZb6Q3/ZNHPIdFDomB0bez5ey X-Received: by 2002:a17:906:b7da:: with SMTP id fy26mr10143343ejb.327.1587260456154; Sat, 18 Apr 2020 18:40:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1587260456; cv=none; d=google.com; s=arc-20160816; b=iqRA+zZdk2rAi11j3VKh0uwxp90pLSUU+l36LRVUOb/cLhyZ7tB1xwMZO9FDeir7jy LtPq6Ygw2JJGAd0U+PEpxnpPusNynNdrd6j81pF4KNTeqFJBCKdgjrbG7+UvsNhENKH5 atNbRorn+RrWjqiXQfhmzrwicO7jj9V2u0mJ4wfT6FM5mjyVaLoTYVR1gjS7/NikRAjP zVkF+XGOsupzXpWGQSF/H6USjo3NHpCje9ICiI341Gc45XXmbswn8Hv5mLGoZ3p1MTCX Yaq1+BwFdSH8mKLAJN/XZrmcV/c8gx4RLMrr1Sm+OWQ3y9jg3Fb5rhvAlpGKEXt4kPd6 r2GA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:in-reply-to :subject:cc:to:from:date; bh=XfPq8c5CW2VF7MKit+GaDwxZr7z5N3DCIexjJ+8qdfE=; b=UizwRtAEnTytVUT5weDKTey1f6+d6gOyWxqfQE/52IHKXUaWijdIFgQeCNlf1ZjSbk TrD7lKBMD2fwUATUWWUukH4fkUO9vzmGRaUQlgAvm4/JBdFXrnx/ZwYyRr1yOL3HPik7 /2PdIoAIHUEKGpYMf45Qkr238AePVPzKIiQOWy1W2FCXVraJ2xTJv1pivQKjIooDjG2x b7WNZPio4fOVdQkZDr+bOnUsARqCoU4hgC5qam8RuQe333yFAz2WHm0Skj0nIO7vOayj 0Shcktg00v0tTdLKrpvh+m6+jmDsdlgudVkbvXXRs0jADYqwgGXCyClJsDA/nxO4+jDL KxCQ== 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 a22si19093232edn.385.2020.04.18.18.40.33; Sat, 18 Apr 2020 18:40:56 -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 S1725970AbgDSBem (ORCPT + 99 others); Sat, 18 Apr 2020 21:34:42 -0400 Received: from netrider.rowland.org ([192.131.102.5]:32869 "HELO netrider.rowland.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1725877AbgDSBel (ORCPT ); Sat, 18 Apr 2020 21:34:41 -0400 Received: (qmail 26346 invoked by uid 500); 18 Apr 2020 21:34:40 -0400 Received: from localhost (sendmail-bs@127.0.0.1) by localhost with SMTP; 18 Apr 2020 21:34:40 -0400 Date: Sat, 18 Apr 2020 21:34:40 -0400 (EDT) From: Alan Stern X-X-Sender: stern@netrider.rowland.org To: syzbot cc: andreyknvl@google.com, , , , , Subject: Re: KASAN: use-after-free Read in usbhid_close (3) In-Reply-To: <000000000000f4957305a3968e84@google.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, 18 Apr 2020, syzbot wrote: > Hello, > > syzbot has tested the proposed patch but the reproducer still triggered crash: > WARNING in usbhid_stop > > usbhid 6-1:0.0: Stop: 1 1 0 0 > ------------[ cut here ]------------ > usbhid 6-1:0.0: Stop while open = 1 This indicates there is some confusion about whether the wacom device is an input device. Apparently hidinput_connect() either doesn't get called or fails, but nevertheless an evdev input handler gets associated with the device. Maybe the confusion is only in my head. This test may help clear it up a little. Alan Stern #syz test: https://github.com/google/kasan.git 0fa84af8 Index: usb-devel/drivers/hid/usbhid/hid-core.c =================================================================== --- usb-devel.orig/drivers/hid/usbhid/hid-core.c +++ usb-devel/drivers/hid/usbhid/hid-core.c @@ -747,6 +747,7 @@ static void usbhid_close(struct hid_devi return; hid_cancel_delayed_stuff(usbhid); + --hid->alan_open; usb_kill_urb(usbhid->urbin); usbhid->intf->needs_remote_wakeup = 0; } @@ -1177,6 +1178,7 @@ static int usbhid_start(struct hid_devic usbhid_set_leds(hid); device_set_wakeup_enable(&dev->dev, 1); } + ++hid->alan_open; return 0; fail: @@ -1197,6 +1199,11 @@ static void usbhid_stop(struct hid_devic if (WARN_ON(!usbhid)) return; + dev_info(&usbhid->intf->dev, "Stop: %d %d %d %d\n", + hid->alan1, hid->alan2, hid->alan3, hid->alan4); + if (hid->alan_open > 0) + dev_WARN(&usbhid->intf->dev, "Stop while open = %d\n", + hid->alan_open); if (hid->quirks & HID_QUIRK_ALWAYS_POLL) { clear_bit(HID_IN_POLLING, &usbhid->iofl); usbhid->intf->needs_remote_wakeup = 0; Index: usb-devel/drivers/hid/hid-input.c =================================================================== --- usb-devel.orig/drivers/hid/hid-input.c +++ usb-devel/drivers/hid/hid-input.c @@ -1861,6 +1861,7 @@ int hidinput_connect(struct hid_device * unsigned int application; int i, k; + dev_info(&hid->dev, "In hidinput_connect\n"); INIT_LIST_HEAD(&hid->inputs); INIT_WORK(&hid->led_work, hidinput_led_worker); @@ -1960,6 +1961,7 @@ void hidinput_disconnect(struct hid_devi { struct hid_input *hidinput, *next; + ++hid->alan3; hidinput_cleanup_battery(hid); list_for_each_entry_safe(hidinput, next, &hid->inputs, list) { Index: usb-devel/drivers/input/evdev.c =================================================================== --- usb-devel.orig/drivers/input/evdev.c +++ usb-devel/drivers/input/evdev.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "input-compat.h" struct evdev { @@ -1329,6 +1330,11 @@ static void evdev_mark_dead(struct evdev static void evdev_cleanup(struct evdev *evdev) { struct input_handle *handle = &evdev->handle; +// struct hid_device *hid; + +// hid = evdev->handle.dev->hid; +// if (hid) +// ++hid->alan3; evdev_mark_dead(evdev); evdev_hangup(evdev); Index: usb-devel/drivers/input/input.c =================================================================== --- usb-devel.orig/drivers/input/input.c +++ usb-devel/drivers/input/input.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "input-compat.h" #include "input-poller.h" @@ -1031,6 +1032,10 @@ static int input_attach_handler(struct i if (error && error != -ENODEV) pr_err("failed to attach handler %s to device %s, error: %d\n", handler->name, kobject_name(&dev->dev.kobj), error); + if (!error && dev->hid) { + dev_info(&dev->dev, "Attached to handler %s\n", handler->name); + dump_stack(); + } return error; } @@ -2157,6 +2162,7 @@ int input_register_device(struct input_d const char *path; int error; + dev_info(&dev->dev, "In input_register_device\n"); if (test_bit(EV_ABS, dev->evbit) && !dev->absinfo) { dev_err(&dev->dev, "Absolute device without dev->absinfo, refusing to register\n"); @@ -2258,6 +2264,11 @@ EXPORT_SYMBOL(input_register_device); */ void input_unregister_device(struct input_dev *dev) { + struct hid_device *hid; + + hid = dev->hid; + if (hid) + ++hid->alan4; if (dev->devres_managed) { WARN_ON(devres_destroy(dev->dev.parent, devm_input_device_unregister, Index: usb-devel/include/linux/hid.h =================================================================== --- usb-devel.orig/include/linux/hid.h +++ usb-devel/include/linux/hid.h @@ -618,6 +618,9 @@ struct hid_device { /* device repo struct list_head debug_list; spinlock_t debug_list_lock; wait_queue_head_t debug_wait; + + int alan_open; + int alan1, alan2, alan3, alan4; }; #define to_hid_device(pdev) \ Index: usb-devel/include/linux/input.h =================================================================== --- usb-devel.orig/include/linux/input.h +++ usb-devel/include/linux/input.h @@ -22,6 +22,7 @@ #include struct input_dev_poller; +struct hid_device; /** * struct input_value - input value representation @@ -129,6 +130,7 @@ enum input_clock_type { * by a driver */ struct input_dev { + struct hid_device *hid; const char *name; const char *phys; const char *uniq; Index: usb-devel/drivers/hid/wacom_sys.c =================================================================== --- usb-devel.orig/drivers/hid/wacom_sys.c +++ usb-devel/drivers/hid/wacom_sys.c @@ -2017,6 +2017,7 @@ static struct input_dev *wacom_allocate_ if (!input_dev) return NULL; + input_dev->hid = hdev; input_dev->name = wacom_wac->features.name; input_dev->phys = hdev->phys; input_dev->dev.parent = &hdev->dev; Index: usb-devel/drivers/hid/hid-core.c =================================================================== --- usb-devel.orig/drivers/hid/hid-core.c +++ usb-devel/drivers/hid/hid-core.c @@ -2001,6 +2001,7 @@ EXPORT_SYMBOL_GPL(hid_connect); void hid_disconnect(struct hid_device *hdev) { + ++hdev->alan2; device_remove_file(&hdev->dev, &dev_attr_country); if (hdev->claimed & HID_CLAIMED_INPUT) hidinput_disconnect(hdev); @@ -2050,6 +2051,7 @@ EXPORT_SYMBOL_GPL(hid_hw_start); */ void hid_hw_stop(struct hid_device *hdev) { + ++hdev->alan1; hid_disconnect(hdev); hdev->ll_driver->stop(hdev); }