fs: fix data races on inode->i_flctx
authorDmitry Vyukov <dvyukov@google.com>
Mon, 21 Sep 2015 07:43:06 +0000 (09:43 +0200)
committerJeff Layton <jeff.layton@primarydata.com>
Mon, 21 Sep 2015 11:27:35 +0000 (07:27 -0400)
commit128a37852234c1bd68eee4e7447f5362778009b8
tree8f03feb85b58f1de45dff01387ac2736fc971585
parentd11797a0a7acc1fe6a51b1605e166adad04da29b
fs: fix data races on inode->i_flctx

locks_get_lock_context() uses cmpxchg() to install i_flctx.
cmpxchg() is a release operation which is correct. But it uses
a plain load to load i_flctx. This is incorrect. Subsequent loads
from i_flctx can hoist above the load of i_flctx pointer itself
and observe uninitialized garbage there. This in turn can lead
to corruption of ctx->flc_lock and other members.

Documentation/memory-barriers.txt explicitly requires to use
a barrier in such context:
"A load-load control dependency requires a full read memory barrier".

Use smp_load_acquire() in locks_get_lock_context() and in bunch
of other functions that can proceed concurrently with
locks_get_lock_context().

The data race was found with KernelThreadSanitizer (KTSAN).

Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
fs/locks.c