general protection fault in strncasecmp
Hillf Danton
hdanton at sina.com
Thu Sep 24 09:40:52 EDT 2020
On Thu, 24 Sep 2020 02:26:27 -0700
> syzbot found the following issue on:
>
> HEAD commit: 98477740 Merge branch 'rcu/urgent' of git://git.kernel.org..
> git tree: upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=15b4d887900000
> kernel config: https://syzkaller.appspot.com/x/.config?x=5f4c828c9e3cef97
> dashboard link: https://syzkaller.appspot.com/bug?extid=459a5dce0b4cb70fd076
> compiler: gcc (GCC) 10.1.0-syz 20200507
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=125d46c5900000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=16c58f8b900000
>
> IMPORTANT: if you fix the issue, please add the following tag to the commit:
> Reported-by: syzbot+459a5dce0b4cb70fd076 at syzkaller.appspotmail.com
>
> general protection fault, probably for non-canonical address 0xf27d208691691fdb: 0000 [#1] PREEMPT SMP KASAN
> KASAN: maybe wild-memory-access in range [0x93e924348b48fed8-0x93e924348b48fedf]
> CPU: 1 PID: 10071 Comm: syz-executor152 Not tainted 5.9.0-rc6-syzkaller #0
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
> RIP: 0010:strncasecmp lib/string.c:52 [inline]
> RIP: 0010:strncasecmp+0x5f/0x240 lib/string.c:43
> Code: 00 40 38 ce 0f 85 ec 01 00 00 4c 39 e2 0f 84 11 01 00 00 4c 89 fe 4c 89 e7 49 83 c4 01 48 89 f8 48 89 f9 48 c1 e8 03 83 e1 07 <42> 0f b6 04 28 38 c8 7f 08 84 c0 0f 85 0f 01 00 00 41 0f b6 6c 24
> RSP: 0018:ffffc9000ba7f958 EFLAGS: 00010202
> RAX: 127d248691691fdb RBX: dffffc0000000000 RCX: 0000000000000001
> RDX: 93e924348b48fee3 RSI: ffff8880a1a65401 RDI: 93e924348b48fed9
> RBP: 0000000000000009 R08: 000000000000002e R09: 0000000000000025
> R10: 0000000000000000 R11: 0000000000000005 R12: 93e924348b48feda
> R13: dffffc0000000000 R14: 00000000000000e7 R15: ffffffff82ddbcd0
> FS: 00007fd01e732700(0000) GS:ffff8880ae500000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00000000004cdb30 CR3: 00000000929cd000 CR4: 00000000001506e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> Call Trace:
> afs_lookup_cell_rcu+0x313/0x720 fs/afs/cell.c:88
> afs_lookup_cell+0x2ee/0x1440 fs/afs/cell.c:249
> afs_parse_source fs/afs/super.c:290 [inline]
> afs_parse_param+0x404/0x8c0 fs/afs/super.c:326
> vfs_parse_fs_param fs/fs_context.c:117 [inline]
> vfs_parse_fs_param+0x203/0x550 fs/fs_context.c:98
> vfs_parse_fs_string+0xe6/0x150 fs/fs_context.c:161
> generic_parse_monolithic+0x16f/0x1f0 fs/fs_context.c:201
> do_new_mount fs/namespace.c:2871 [inline]
> path_mount+0x133f/0x20a0 fs/namespace.c:3192
> do_mount fs/namespace.c:3205 [inline]
> __do_sys_mount fs/namespace.c:3413 [inline]
> __se_sys_mount fs/namespace.c:3390 [inline]
> __x64_sys_mount+0x27f/0x300 fs/namespace.c:3390
> do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
> entry_SYSCALL_64_after_hwframe+0x44/0xa9
Bump up cell's usage count before anything important and skip it in
case of failure to do so.
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -85,6 +85,20 @@ struct afs_cell *afs_lookup_cell_rcu(str
while (p) {
cell = rb_entry(p, struct afs_cell, net_node);
+ /*
+ * care to detect writers because
+ *
+ * read_seqbegin_or_lock(&net->cells_lock, &seq);
+ *
+ * is unable to block
+ *
+ * write_seqlock(&net->cells_lock);
+ *
+ */
+ if (!atomic_inc_not_zero(&cell->usage)) {
+ cell = NULL;
+ break;
+ }
n = strncasecmp(cell->name, name,
min_t(size_t, cell->name_len, namesz));
if (n == 0)
@@ -94,17 +108,11 @@ struct afs_cell *afs_lookup_cell_rcu(str
} else if (n > 0) {
p = rcu_dereference_raw(p->rb_right);
} else {
- if (atomic_inc_not_zero(&cell->usage)) {
- ret = 0;
- break;
- }
- /* We want to repeat the search, this time with
- * the lock properly locked.
- */
+ ret = 0;
+ break;
}
cell = NULL;
}
-
} while (need_seqretry(&net->cells_lock, seq));
done_seqretry(&net->cells_lock, seq);
More information about the linux-afs
mailing list