OSDN Git Service

Fix SMP ordering hole in fcntl_setlk() (CVE-2008-1669)
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 6 May 2008 22:16:24 +0000 (00:16 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 6 May 2008 22:35:25 +0000 (00:35 +0200)
commit7e98aaf5fc21d623d1ca9b51717b18e9fd9f3ef2
treed551387967d68e3c3c6db90305b8a8aa3a1c3073
parent141787e66243b24109d3da653168f3a813f6db2b
Fix SMP ordering hole in fcntl_setlk() (CVE-2008-1669)

[ sync up with 2.6 commit 0b2bac2f1ea0d33a3621b27ca68b9ae760fca2e9 ]

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.

[ w@1wt.eu: this patch also includes a missing fix for and older
  bug affecting the same code, which was already fixed in 2.6. As
  of now, 2.4 is in sync with 2.6 concerning this bug. ]
fs/fcntl.c
fs/locks.c
include/linux/fs.h