Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753696AbdHKShK (ORCPT ); Fri, 11 Aug 2017 14:37:10 -0400 Received: from prod-mx.aristanetworks.com ([162.210.130.12]:35493 "EHLO prod-mx.aristanetworks.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753584AbdHKShG (ORCPT ); Fri, 11 Aug 2017 14:37:06 -0400 X-Greylist: delayed 477 seconds by postgrey-1.27 at vger.kernel.org; Fri, 11 Aug 2017 14:37:06 EDT Date: Fri, 11 Aug 2017 11:29:07 -0700 To: linux-hotplug@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [uio] panic in name_show() Cc: fruggeri@arista.com User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-Id: <20170811182907.BBAB488201C7@us152.sjc.aristanetworks.com> From: fruggeri@arista.com (Francesco Ruggeri) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5584 Lines: 137 I have run into this panic while some devices were being hotunplugged, and I am able to easily reproduce it with the attached module, which creates a dummy uio device (in my case /sys/class/uio/uio74). The panic is the result of a race between uio_unregister_device(), which sets idev->info to NULL, and name_show() which dereferences it. Seen in 4.9, 3.18 and 3.4. Thanks, Francesco Ruggeri -bash-4.3# insmod dummydev.ko -bash-4.3# cat /sys/class/uio/uio74/name uio_dummydev -bash-4.3# rmmod dummydev -bash-4.3# Then on different bash shells on different cpus I run while true ;do insmod dummydev.ko; rmmod dummydev ;done while true ;do cat /sys/class/uio/uio74/name ;done -bash-4.3# taskset 1 bash bash-4.3# while true ;do insmod dummydev.ko; rmmod dummydev ;done [ 448.104247] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 [ 448.197773] IP: [] name_show+0x24/0x31 [uio] [ 448.267454] PGD 245c8d067 [ 448.297612] PUD 14b221067 PMD 0 [ 448.336088] [ 448.353773] Oops: 0000 [#1] PREEMPT SMP [ 448.399531] Modules linked in: dummydev(O-) l2mod_dma(PO) xt_u32 nfnetlink_log nfnetlink nf_log_ipv6 nf_conntrack_ipv6 nf_defrag_ipv6 ip6t_REJECT nf_reject_ipv6 ip6table_mangle nf_log_ipv4 nf_log_common nf_conntrack_ipv4 nf_defrag_ipv4 xt_LOG xt_limit xt_hl xt_multiport ipt_REJECT nf_reject_ipv4 xt_tcpudp iptable_mangle sch_prio msr strata_dma_drv(PO) arista_bde(PO) rbfd(PO) 8021q garp stp llc tun xt_conntrack xfrm_user nf_conntrack_tftp xfrm4_tunnel tunnel4 xt_CT nf_conntrack xt_mark ipcomp ip6table_raw iptable_raw xfrm_ipcomp iptable_filter ip6table_filter ip_tables ip6_tables esp4 x_tables ah4 af_key xfrm_algo x86_pkg_temp_thermal coretemp scd(O) kshim(PO) uio fan thermal tpm_tis tpm_tis_core tpm kvm_intel kvm irqbypass [last unloaded: dummydev] [ 449.193038] CPU: 1 PID: 5278 Comm: cat Tainted: P O 4.9.20.Ar-5809926.eostrunkkernel49 #1 [ 449.304316] task: ffff880148e4ce00 task.stack: ffffc90004544000 [ 449.375031] RIP: 0010:[] [] name_show+0x24/0x31 [uio] [ 449.473832] RSP: 0018:ffffc90004547da8 EFLAGS: 00010286 [ 449.537271] RAX: ffff88016a306000 RBX: ffffffffa01707c0 RCX: ffffffffa016f196 [ 449.622548] RDX: 0000000000000000 RSI: ffffffffa01701e4 RDI: ffff88016a306000 [ 449.707826] RBP: ffffc90004547da8 R08: ffff88014b16d810 R09: ffff88017d1df600 [ 449.793105] R10: ffffc90004547dc0 R11: 0000000000000246 R12: ffffffff81653b30 [ 449.878380] R13: ffffc90004547f08 R14: ffff88014b1b76c0 R15: ffff88014b212500 [ 449.963661] FS: 0000000000000000(0000) GS:ffff88024f880000(0063) knlGS:00000000f73b0940 [ 450.060376] CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033 [ 450.129016] CR2: 0000000000000008 CR3: 0000000154571000 CR4: 00000000000406e0 [ 450.214293] Stack: [ 450.238214] ffffc90004547dc8 ffffffff81382de9 ffff88014b16d810 ffff88014b1b76c0 [ 450.326613] ffffc90004547de8 ffffffff811d37f4 0000000000000000 0000000000010000 [ 450.415009] ffffc90004547df8 ffffffff811d242c ffffc90004547e60 ffffffff81187b60 [ 450.503409] Call Trace: [ 450.532542] [] dev_attr_show+0x25/0x49 [ 450.597019] [] sysfs_kf_seq_show+0x83/0xcf [ 450.665655] [] kernfs_seq_show+0x26/0x28 [ 450.732212] [] seq_read+0x181/0x358 [ 450.793574] [] ? handle_mm_fault+0xc50/0xd5a [ 450.864287] [] kernfs_fop_read+0x3a/0x166 [ 450.931887] [] __vfs_read+0x18/0x2f [ 450.993242] [] vfs_read+0xa6/0x10d [ 451.053562] [] SyS_read+0x51/0x8e [ 451.112844] [] do_fast_syscall_32+0xc9/0x150 [ 451.183559] [] entry_SYSENTER_compat+0x4c/0x5b [ 451.256356] Code: 08 16 e1 5d 48 98 c3 66 66 66 66 90 55 48 89 d0 48 8b 97 c0 00 00 00 48 c7 c6 e4 01 17 a0 48 89 c7 48 89 e5 48 8b 92 48 03 00 00 <48> 8b 52 08 e8 14 08 16 e1 5d 48 98 c3 66 66 66 66 90 55 48 89 [ 451.482028] RIP [] name_show+0x24/0x31 [uio] [ 451.552747] RSP [ 451.594346] CR2: 0000000000000008 #include #include #include #include #include #include #include #include #include static struct device *dummydev = NULL; static const char *devname = "dummydev"; static struct uio_info uio_info = { .name = "uio_dummydev", .version = "1.2.3", .irq = UIO_IRQ_CUSTOM, }; static void dummydev_release(struct device *dev) {} int init_module(void) { int ret; dummydev = kzalloc(sizeof(struct device), GFP_ATOMIC); if (!dummydev) { dev_info(dummydev, "INFO %s - kzalloc() failed\n", __func__); goto out; } dev_set_name(dummydev, devname); dummydev->release = dummydev_release; ret = device_register(dummydev); if (ret) { dev_info(dummydev, "INFO %s - device_register() failed\n", __func__); goto out_free; } ret = uio_register_device(dummydev, &uio_info); if (ret) { dev_info(dummydev, "INFO %s - uio_register_device() failed\n", __func__); goto out_dev_unregister; } dev_info(dummydev, "INFO %s - created\n", __func__); return 0; out_dev_unregister: device_unregister(dummydev); out_free: kfree(dummydev); out: return 1; } void cleanup_module(void) { if (!dummydev) return; dev_info(dummydev, "INFO %s - removing\n", __func__); uio_unregister_device(&uio_info); device_unregister(dummydev); kfree(dummydev); } MODULE_LICENSE("GPL");