Data races in generic_fillattr

From: Dmitry Vyukov
Date: Fri Aug 28 2015 - 13:10:17 EST


We are working on a dynamic data race detector for the Linux kernel,
KernelThreadSanitizer (ktsan):
https://github.com/google/ktsan/wiki

While booting kernel (upstream revision 21bdb584af8c) we get a bunch
of reports of the form:

ThreadSanitizer: data-race in generic_fillattr

Read of size 8 by thread T173 (K1854):
[<ffffffff81266028>] generic_fillattr+0x138/0x1d0 fs/stat.c:32
[<ffffffff8126615a>] vfs_getattr_nosec+0x9a/0xa0 fs/stat.c:59
[<ffffffff812662c5>] vfs_getattr+0x35/0x50 fs/stat.c:72
[<ffffffff8126631b>] vfs_fstat+0x3b/0x70 fs/stat.c:83
[<ffffffff81266d54>] SYSC_newfstat+0x24/0x50 fs/stat.c:307
[<ffffffff812671e0>] SyS_newfstat+0x20/0x30 fs/stat.c:304
[<ffffffff81ee242e>] entry_SYSCALL_64_fastpath+0x12/0x71
arch/x86/entry/entry_64.S:186

Previous write of size 8 by thread T170 (K1853):
[<ffffffff8128b3d0>] generic_update_time+0x90/0x170 fs/inode.c:1562
[< inlined >] file_update_time+0x112/0x1b0 update_time fs/inode.c:1582
[<ffffffff81289d42>] file_update_time+0x112/0x1b0 fs/inode.c:1785
[<ffffffff8126c6cd>] pipe_write+0x47d/0x670 fs/pipe.c:466
[< inlined >] __vfs_write+0x1a3/0x1f0 new_sync_write fs/read_write.c:478
[<ffffffff8125e1b3>] __vfs_write+0x1a3/0x1f0 fs/read_write.c:491
[<ffffffff8125efef>] vfs_write+0xef/0x280 fs/read_write.c:538
[< inlined >] SyS_write+0x70/0xe0 SYSC_write fs/read_write.c:585
[<ffffffff812603f0>] SyS_write+0x70/0xe0 fs/read_write.c:577
[<ffffffff81ee242e>] entry_SYSCALL_64_fastpath+0x12/0x71
arch/x86/entry/entry_64.S:186


ThreadSanitizer: data-race in shmem_mknod

Write of size 8 by thread T609 (K1067):
[<ffffffff811f5048>] shmem_mknod+0xe8/0x140 mm/shmem.c:2222
[<ffffffff811f5573>] shmem_create+0x33/0x50 mm/shmem.c:2269
[<ffffffff8127222c>] vfs_create+0x13c/0x1d0 fs/namei.c:2642
[< inlined >] path_openat+0x1501/0x2060 lookup_open fs/namei.c:2981
[< inlined >] path_openat+0x1501/0x2060 do_last fs/namei.c:3066
[<ffffffff81276f31>] path_openat+0x1501/0x2060 fs/namei.c:3306
[<ffffffff8127949f>] do_filp_open+0xff/0x170 fs/namei.c:3341
[<ffffffff8125d5e1>] do_sys_open+0x191/0x2b0 fs/open.c:1025
[< inlined >] SyS_open+0x35/0x50 SYSC_open fs/open.c:1043
[<ffffffff8125d735>] SyS_open+0x35/0x50 fs/open.c:1038
[<ffffffff81ee242e>] entry_SYSCALL_64_fastpath+0x12/0x71
arch/x86/entry/entry_64.S:186
D
Previous read of size 8 by thread T501 (K1069):
[<ffffffff8126604d>] generic_fillattr+0x15d/0x1d0 fs/stat.c:33
[<ffffffff8126615a>] vfs_getattr_nosec+0x9a/0xa0 fs/stat.c:59
[<ffffffff812662c5>] vfs_getattr+0x35/0x50 fs/stat.c:72
[<ffffffff812663bb>] vfs_fstatat+0x6b/0xb0 fs/stat.c:110
[< inlined >] SYSC_newstat+0x2d/0x60 vfs_stat fs/stat.c:123
[<ffffffff81266c2d>] SYSC_newstat+0x2d/0x60 fs/stat.c:270
[<ffffffff81267111>] SyS_newstat+0x21/0x40 fs/stat.c:266
[<ffffffff81ee242e>] entry_SYSCALL_64_fastpath+0x12/0x71
arch/x86/entry/entry_64.S:186

The first one is between:
stat->mtime = inode->i_mtime;
and:
inode->i_mtime = *time;

The second:
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
and:
stat->ctime = inode->i_ctime;

timespec is 16 bytes, so stat can return complete mess in times.

Please confirm this is a real bug.

Thank you
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/