fix SMP ordering hole in fcntl_setlk() (CVE-2008-1669)
commit89ebd169dd1e8be2c11c100c4decbffdcbd6466b
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 14 Jul 2008 18:09:23 +0000 (14 21:09 +0300)
committerAdrian Bunk <bunk@kernel.org>
Mon, 14 Jul 2008 18:09:23 +0000 (14 21:09 +0300)
treedbf08e3254ccf386dcfd6c47474096cf1aed5058
parent873496a3485950402ee0436c9d17eeb789157b10
fix SMP ordering hole in fcntl_setlk() (CVE-2008-1669)

fcntl_setlk()/close() race prevention has a subtle hole - we need to
make sure that if we *do* have an fcntl/close race on SMP box, the
access to descriptor table and inode->i_flock won't get reordered.

As it is, we get STORE inode->i_flock, LOAD descriptor table entry vs.
STORE descriptor table entry, LOAD inode->i_flock with not a single
lock in common on both sides.  We do have BKL around the first STORE,
but check in locks_remove_posix() is outside of BKL and for a good
reason - we don't want BKL on common path of close(2).

Solution is to hold ->file_lock around fcheck() in there; that orders
us wrt removal from descriptor table that preceded locks_remove_posix()
on close path and we either come first (in which case eviction will be
handled by the close side) or we'll see the effect of close and do
eviction ourselves.  Note that even though it's read-only access,
we do need ->file_lock here - rcu_read_lock() won't be enough to
order the things.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Adrian Bunk <bunk@kernel.org>
fs/locks.c