Bug 197679

Summary: removing uinput devices crashes in led_classdev_unregister
Product: Drivers Reporter: Peter Hutterer (peter.hutterer)
Component: Input DevicesAssignee: drivers_input-devices
Status: NEW ---    
Severity: normal    
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 4.13 Subsystem:
Regression: No Bisected commit-id:

Description Peter Hutterer 2017-11-02 03:08:18 UTC
Rapidly creating and destroying uinput devices will eventually crash the kernel.

This appears to be a race condition because I cannot trigger it manually with evemu-device and how frequently it occurs depends on the set of wait times I have. 

Reproducer is simple tool that uinput devices with random bits set, then sends a random number of events through the device. See https://github.com/whot/fuzzydevice for the code.  Reproduce with
  meson build && ninja -C build && sudo ./build/fuzzydevice

At some point, it'll crash with this backtrace:

Nov 02 12:46:35 localhost.localdomain kernel: BUG: unable to handle kernel NULL pointer dereference at 000000000000009e
Nov 02 12:46:35 localhost.localdomain kernel: IP: device_del+0x35/0x350
Nov 02 12:46:35 localhost.localdomain kernel: PGD 130dc2067 
Nov 02 12:46:35 localhost.localdomain kernel: P4D 130dc2067 
Nov 02 12:46:35 localhost.localdomain kernel: PUD 130dc3067 
Nov 02 12:46:35 localhost.localdomain kernel: PMD 0 
Nov 02 12:46:35 localhost.localdomain kernel: 
Nov 02 12:46:35 localhost.localdomain kernel: Oops: 0000 [#3] SMP
Nov 02 12:46:35 localhost.localdomain kernel: Modules linked in: uinput xt_CHECKSUM ipt_MASQUERADE nf_nat_masquerade_ipv4 tun nf_conntrack_netbios_ns nf_conntrack_broadcast xt_CT ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 xt_conntrack ip_set nfnetlink ebtable_nat ebtable_broute bridge stp llc ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_raw ip6table_security iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack libcrc32c iptable_mangle iptable_raw iptable_security ebtable_filter ebtables ip6table_filter ip6_tables sunrpc crct10dif_pclmul crc32_pclmul ghash_clmulni_intel joydev virtio_balloon pcspkr i2c_piix4 pvpanic qxl drm_kms_helper ttm drm virtio_console 8139too crc32c_intel virtio_pci 8139cp ata_generic serio_raw virtio_ring virtio mii pata_acpi
Nov 02 12:46:35 localhost.localdomain kernel: CPU: 0 PID: 1563 Comm: fuzzydevice Tainted: G      D         4.13.0 #1
Nov 02 12:46:35 localhost.localdomain kernel: Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
Nov 02 12:46:35 localhost.localdomain kernel: task: ffff9ca66ea42640 task.stack: ffffb86280f00000
Nov 02 12:46:35 localhost.localdomain kernel: RIP: 0010:device_del+0x35/0x350
Nov 02 12:46:35 localhost.localdomain kernel: RSP: 0018:ffffb86280f03c80 EFLAGS: 00010202
Nov 02 12:46:35 localhost.localdomain kernel: RAX: 000000000000000e RBX: ffff9ca670f68c00 RCX: 0000000000000000
Nov 02 12:46:35 localhost.localdomain kernel: RDX: 0000000080000000 RSI: 0000000000000000 RDI: ffff9ca670f68c00
Nov 02 12:46:35 localhost.localdomain kernel: RBP: ffffb86280f03cb8 R08: 000000000001d840 R09: ffffffff8f6910f3
Nov 02 12:46:35 localhost.localdomain kernel: R10: ffffe48b44c90c80 R11: 0000000000000000 R12: ffff9ca670f68a98
Nov 02 12:46:35 localhost.localdomain kernel: R13: ffff9ca6717f0220 R14: ffff9ca670f68800 R15: ffff9ca672432280
Nov 02 12:46:35 localhost.localdomain kernel: FS:  00007fad13388880(0000) GS:ffff9ca67fc00000(0000) knlGS:0000000000000000
Nov 02 12:46:35 localhost.localdomain kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Nov 02 12:46:35 localhost.localdomain kernel: CR2: 000000000000009e CR3: 0000000130de1000 CR4: 00000000001406f0
Nov 02 12:46:35 localhost.localdomain kernel: Call Trace:
Nov 02 12:46:35 localhost.localdomain kernel:  device_unregister+0x1a/0x60
Nov 02 12:46:35 localhost.localdomain kernel:  led_classdev_unregister+0x6b/0xe0
Nov 02 12:46:35 localhost.localdomain kernel:  input_leds_disconnect+0x39/0x70
Nov 02 12:46:35 localhost.localdomain kernel:  __input_unregister_device+0xb3/0x180
Nov 02 12:46:35 localhost.localdomain kernel:  input_unregister_device+0x47/0x60
Nov 02 12:46:35 localhost.localdomain kernel:  uinput_destroy_device+0xb4/0xc0 [uinput]
Nov 02 12:46:35 localhost.localdomain kernel:  uinput_ioctl_handler.isra.9+0x670/0x9b0 [uinput]
Nov 02 12:46:35 localhost.localdomain kernel:  ? ep_scan_ready_list.constprop.15+0x23b/0x240
Nov 02 12:46:35 localhost.localdomain kernel:  uinput_ioctl+0x18/0x20 [uinput]
Nov 02 12:46:35 localhost.localdomain kernel:  do_vfs_ioctl+0xa5/0x600
Nov 02 12:46:35 localhost.localdomain kernel:  ? security_file_permission+0x9b/0xc0
Nov 02 12:46:35 localhost.localdomain kernel:  SyS_ioctl+0x79/0x90
Nov 02 12:46:35 localhost.localdomain kernel:  entry_SYSCALL_64_fastpath+0x1a/0xa5
Nov 02 12:46:35 localhost.localdomain kernel: RIP: 0033:0x7fad12885847
Nov 02 12:46:35 localhost.localdomain kernel: RSP: 002b:00007ffd63b70348 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
Nov 02 12:46:35 localhost.localdomain kernel: RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fad12885847
Nov 02 12:46:35 localhost.localdomain kernel: RDX: 0000000000000000 RSI: 0000000000005502 RDI: 0000000000000005
Nov 02 12:46:35 localhost.localdomain kernel: RBP: 0000000000000000 R08: fffffffffffffff0 R09: 0000000000000000
Nov 02 12:46:35 localhost.localdomain kernel: R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000005
Nov 02 12:46:35 localhost.localdomain kernel: R13: 00007ffd63b70500 R14: 0000000000000000 R15: 0000000000000000
Nov 02 12:46:35 localhost.localdomain kernel: Code: 56 41 55 41 54 53 48 89 fb 48 83 ec 18 4c 8b 2f 65 48 8b 04 25 28 00 00 00 48 89 45 d8 31 c0 48 8b 87 80 00 00 00 48 85 c0 74 1b <48> 8b b8 90 00 00 00 48 89 da be 02 00 00 00 48 81 c7 f0 00 00 
Nov 02 12:46:35 localhost.localdomain kernel: RIP: device_del+0x35/0x350 RSP: ffffb86280f03c80
Nov 02 12:46:35 localhost.localdomain kernel: CR2: 000000000000009e
Nov 02 12:46:35 localhost.localdomain kernel: ---[ end trace 9d4f0431027649e0 ]---


Extending the timeouts between uinput device creation, sending the events and destroying the device delays it, but even with several 500ms timeouts sprinkled in, it'll still crash eventually.