Thread (1 message) 1 message, 1 author, 2020-03-08

Re: INFO: trying to register non-static key in uhid_char_release

From: Eric Biggers <ebiggers@kernel.org>
Date: 2020-03-08 06:08:18
Also in: lkml

Possibly related (same subject, not in this thread)

On Sun, Mar 08, 2020 at 12:05:35PM +0800, Hillf Danton wrote:
quoted hunk
Fri, 06 Mar 2020 19:05:11 -0800
quoted
syzbot found the following crash on:

HEAD commit:    fb279f4e Merge branch 'i2c/for-current-fixed' of git://git..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=16bc5181e00000
kernel config:  https://syzkaller.appspot.com/x/.config?x=8b13b05f0e61d957
dashboard link: https://syzkaller.appspot.com/bug?extid=8357fbef0d7bb602de45
compiler:       clang version 10.0.0 (https://github.com/llvm/llvm-project/ c2443155a0fb245c8f17f2c1c72b6ea391e86e81)

Unfortunately, I don't have any reproducer for this crash yet.

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+8357fbef0d7bb602de45@syzkaller.appspotmail.com

INFO: trying to register non-static key.
the code is fine but needs lockdep annotation.
turning off the locking correctness validator.
CPU: 0 PID: 9870 Comm: syz-executor.1 Not tainted 5.6.0-rc3-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x1e9/0x30e lib/dump_stack.c:118
 register_lock_class+0x6f4/0xec0 kernel/locking/lockdep.c:443
 __lock_acquire+0x116/0x1bc0 kernel/locking/lockdep.c:3836
 lock_acquire+0x154/0x250 kernel/locking/lockdep.c:4484
 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline]
 _raw_spin_lock_irqsave+0x9e/0xc0 kernel/locking/spinlock.c:159
 __wake_up_common_lock kernel/sched/wait.c:122 [inline]
 __wake_up+0xb8/0x150 kernel/sched/wait.c:142
 uhid_dev_destroy drivers/hid/uhid.c:563 [inline]
 uhid_char_release+0x99/0x600 drivers/hid/uhid.c:642
 __fput+0x2d8/0x730 fs/file_table.c:280
 task_work_run+0x176/0x1b0 kernel/task_work.c:113
 tracehook_notify_resume include/linux/tracehook.h:188 [inline]
 exit_to_usermode_loop arch/x86/entry/common.c:164 [inline]
 prepare_exit_to_usermode+0x48a/0x5c0 arch/x86/entry/common.c:195
 entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x416041
Code: 75 14 b8 03 00 00 00 0f 05 48 3d 01 f0 ff ff 0f 83 04 1b 00 00 c3 48 83 ec 08 e8 0a fc ff ff 48 89 04 24 b8 03 00 00 00 0f 05 <48> 8b 3c 24 48 89 c2 e8 53 fc ff ff 48 89 d0 48 83 c4 08 48 3d 01
RSP: 002b:00007ffd2649c0a0 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
RAX: 0000000000000000 RBX: 0000000000000004 RCX: 0000000000416041
RDX: 0000001b2f820000 RSI: 0000000000000000 RDI: 0000000000000003
RBP: 0000000000000001 R08: 00000000a5a41883 R09: 00000000a5a41887
R10: 00007ffd2649c180 R11: 0000000000000293 R12: 000000000076bf20
R13: 00000000007715a0 R14: 000000000003bd20 R15: 000000000076bf2c

general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
CPU: 0 PID: 9870 Comm: syz-executor.1 Not tainted 5.6.0-rc3-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
RIP: 0010:__wake_up_common+0x297/0x4d0 kernel/sched/wait.c:86
Code: fb 01 00 00 45 31 f6 eb 13 66 2e 0f 1f 84 00 00 00 00 00 4d 39 fc 0f 84 e3 01 00 00 4c 89 fb 49 8d 6f e8 4c 89 f8 48 c1 e8 03 <80> 3c 10 00 74 12 48 89 df e8 eb 48 59 00 48 ba 00 00 00 00 00 fc
RSP: 0018:ffffc900049a7d20 EFLAGS: 00010046
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: dffffc0000000000 RSI: 0000000000000001 RDI: ffff888048e513c8
RBP: ffffffffffffffe8 R08: 0000000000000000 R09: ffffc900049a7d88
R10: fffff52000934fa4 R11: 0000000000000000 R12: ffff888048e51400
R13: 1ffff92000934fb1 R14: 0000000000000000 R15: 0000000000000000
FS:  0000000000ed3940(0000) GS:ffff8880ae800000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b2f822000 CR3: 0000000098f9a000 CR4: 00000000001406f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 __wake_up_common_lock kernel/sched/wait.c:123 [inline]
 __wake_up+0xd4/0x150 kernel/sched/wait.c:142
 uhid_dev_destroy drivers/hid/uhid.c:563 [inline]
 uhid_char_release+0x99/0x600 drivers/hid/uhid.c:642
 __fput+0x2d8/0x730 fs/file_table.c:280
 task_work_run+0x176/0x1b0 kernel/task_work.c:113
 tracehook_notify_resume include/linux/tracehook.h:188 [inline]
 exit_to_usermode_loop arch/x86/entry/common.c:164 [inline]
 prepare_exit_to_usermode+0x48a/0x5c0 arch/x86/entry/common.c:195
 entry_SYSCALL_64_after_hwframe+0x49/0xbe
Only for gpf.
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -636,9 +636,13 @@ static int uhid_char_open(struct inode *
 
 static int uhid_char_release(struct inode *inode, struct file *file)
 {
-	struct uhid_device *uhid = file->private_data;
+	struct uhid_device *uhid;
 	unsigned int i;
 
+	uhid = xchg(&file->private_data, NULL);
+	if (!uhid)
+		return 0; /* race is benign */
+
 	uhid_dev_destroy(uhid);
 
 	for (i = 0; i < UHID_BUFSIZE; ++i)
That looks wrong.  The normal semantics for files (and uhid looks no different)
is that file->private_data is valid as long as they're open, and then
->release() frees it.  ->release() should never see NULL private_data.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help