linux/fs
Andreas Gruenbacher 9287c6452d gfs2: Fix occasional glock use-after-free
This patch has to do with the life cycle of glocks and buffers.  When
gfs2 metadata or journaled data is queued to be written, a gfs2_bufdata
object is assigned to track the buffer, and that is queued to various
lists, including the glock's gl_ail_list to indicate it's on the active
items list.  Once the page associated with the buffer has been written,
it is removed from the ail list, but its life isn't over until a revoke
has been successfully written.

So after the block is written, its bufdata object is moved from the
glock's gl_ail_list to a file-system-wide list of pending revokes,
sd_log_le_revoke.  At that point the glock still needs to track how many
revokes it contributed to that list (in gl_revokes) so that things like
glock go_sync can ensure all the metadata has been not only written, but
also revoked before the glock is granted to a different node.  This is
to guarantee journal replay doesn't replay the block once the glock has
been granted to another node.

Ross Lagerwall recently discovered a race in which an inode could be
evicted, and its glock freed after its ail list had been synced, but
while it still had unwritten revokes on the sd_log_le_revoke list.  The
evict decremented the glock reference count to zero, which allowed the
glock to be freed.  After the revoke was written, function
revoke_lo_after_commit tried to adjust the glock's gl_revokes counter
and clear its GLF_LFLUSH flag, at which time it referenced the freed
glock.

This patch fixes the problem by incrementing the glock reference count
in gfs2_add_revoke when the glock's first bufdata object is moved from
the glock to the global revokes list. Later, when the glock's last such
bufdata object is freed, the reference count is decremented. This
guarantees that whichever process finishes last (the revoke writing or
the evict) will properly free the glock, and neither will reference the
glock after it has been freed.

Reported-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
2019-05-07 23:39:14 +02:00
..
9p 9p: switch to ->free_inode() 2019-05-01 22:43:23 -04:00
adfs Wimplicit-fallthrough patches for 5.2-rc1 2019-05-07 12:48:10 -07:00
affs Wimplicit-fallthrough patches for 5.2-rc1 2019-05-07 12:48:10 -07:00
afs Wimplicit-fallthrough patches for 5.2-rc1 2019-05-07 12:48:10 -07:00
autofs autofs: fix use-after-free in lockless ->d_manage() 2019-04-09 19:18:19 -04:00
befs befs: switch to ->free_inode() 2019-05-01 22:43:23 -04:00
bfs bfs: switch to ->free_inode() 2019-05-01 22:43:24 -04:00
btrfs Wimplicit-fallthrough patches for 5.2-rc1 2019-05-07 12:48:10 -07:00
cachefiles
ceph Wimplicit-fallthrough patches for 5.2-rc1 2019-05-07 12:48:10 -07:00
cifs Merge branch 'work.icache' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-05-07 10:57:05 -07:00
coda coda: switch to ->free_inode() 2019-05-01 22:43:26 -04:00
configfs
cramfs
crypto crypto: shash - remove shash_desc::flags 2019-04-25 15:38:12 +08:00
debugfs debugfs: switch to ->free_inode() 2019-05-01 22:43:24 -04:00
devpts
dlm
ecryptfs Merge branch 'work.icache' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-05-07 10:57:05 -07:00
efivarfs
efs efs: switch to ->free_inode() 2019-05-01 22:43:24 -04:00
exportfs
ext2 ext2: switch to ->free_inode() 2019-05-01 22:43:24 -04:00
ext4 Merge branch 'work.icache' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-05-07 10:57:05 -07:00
f2fs Wimplicit-fallthrough patches for 5.2-rc1 2019-05-07 12:48:10 -07:00
fat fat: switch to ->free_inode() 2019-05-01 22:43:24 -04:00
freevxfs freevxfs: switch to ->free_inode() 2019-05-01 22:43:24 -04:00
fscache
fuse Merge branch 'work.icache' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-05-07 10:57:05 -07:00
gfs2 gfs2: Fix occasional glock use-after-free 2019-05-07 23:39:14 +02:00
hfs hfs: switch to ->free_inode() 2019-05-01 22:43:24 -04:00
hfsplus hfsplus: switch to ->free_inode() 2019-05-01 22:43:24 -04:00
hostfs hostfs: switch to ->free_inode() 2019-05-01 22:43:24 -04:00
hpfs hpfs: switch to ->free_inode() 2019-05-01 22:43:24 -04:00
hugetlbfs hugetlb: make use of ->free_inode() 2019-05-01 22:43:27 -04:00
isofs isofs: switch to ->free_inode() 2019-05-01 22:43:24 -04:00
jbd2
jffs2 Wimplicit-fallthrough patches for 5.2-rc1 2019-05-07 12:48:10 -07:00
jfs Several minor jfs fixes 2019-05-07 11:37:27 -07:00
kernfs
lockd
minix minix: switch to ->free_inode() 2019-05-01 22:43:25 -04:00
nfs Merge branch 'work.icache' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-05-07 10:57:05 -07:00
nfs_common
nfsd Wimplicit-fallthrough patches for 5.2-rc1 2019-05-07 12:48:10 -07:00
nilfs2 nilfs2: switch to ->free_inode() 2019-05-01 22:43:25 -04:00
nls
notify pidfd patches for v5.2-rc1 2019-05-07 12:30:24 -07:00
ntfs ntfs: switch to ->free_inode() 2019-05-01 22:43:26 -04:00
ocfs2 Wimplicit-fallthrough patches for 5.2-rc1 2019-05-07 12:48:10 -07:00
omfs
openpromfs openpromfs: switch to ->free_inode() 2019-05-01 22:43:25 -04:00
orangefs orangefs: make use of ->free_inode() 2019-05-01 22:43:27 -04:00
overlayfs overlayfs: make use of ->free_inode() 2019-05-01 22:43:27 -04:00
proc Merge branch 'work.icache' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-05-07 10:57:05 -07:00
pstore
qnx4 qnx4: switch to ->free_inode() 2019-05-01 22:43:25 -04:00
qnx6 qnx6: switch to ->free_inode() 2019-05-01 22:43:25 -04:00
quota
ramfs
reiserfs reiserfs: convert to ->free_inode() 2019-05-01 22:43:25 -04:00
romfs romfs: convert to ->free_inode() 2019-05-01 22:43:25 -04:00
squashfs squashfs: switch to ->free_inode() 2019-05-01 22:43:25 -04:00
sysfs
sysv sysv: switch to ->free_inode() 2019-05-01 22:43:25 -04:00
tracefs
ubifs Merge branch 'work.icache' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-05-07 10:57:05 -07:00
udf udf: switch to ->free_inode() 2019-05-01 22:43:25 -04:00
ufs Wimplicit-fallthrough patches for 5.2-rc1 2019-05-07 12:48:10 -07:00
xfs xfs: change some error-less functions to void types 2019-05-01 20:26:30 -07:00
Kconfig
Kconfig.binfmt
Makefile Make anon_inodes unconditional 2019-04-19 14:03:11 +02:00
aio.c
anon_inodes.c
attr.c
bad_inode.c
binfmt_aout.c
binfmt_elf.c
binfmt_elf_fdpic.c
binfmt_em86.c
binfmt_flat.c
binfmt_misc.c
binfmt_script.c
block_dev.c Merge branch 'work.icache' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-05-07 10:57:05 -07:00
buffer.c iomap: Fix use-after-free error in page_done callback 2019-05-01 07:47:37 -07:00
char_dev.c
compat.c
compat_binfmt_elf.c
compat_ioctl.c
coredump.c
d_path.c
dax.c
dcache.c dcache: sort the freeing-without-RCU-delay mess for good. 2019-04-09 19:18:04 -04:00
dcookies.c
direct-io.c
drop_caches.c
eventfd.c
eventpoll.c
exec.c
fcntl.c
fhandle.c
file.c
file_table.c
filesystems.c
fs-writeback.c
fs_context.c
fs_parser.c
fs_pin.c
fs_struct.c
fs_types.c
inode.c Merge branch 'work.icache' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-05-07 10:57:05 -07:00
internal.h Changes for Linux 5.2: 2019-05-07 11:43:32 -07:00
io_uring.c io_uring: avoid page allocation warnings 2019-05-01 10:00:25 -06:00
ioctl.c
iomap.c iomap: move iomap_read_inline_data around 2019-05-01 20:16:40 -07:00
libfs.c
locks.c Wimplicit-fallthrough patches for 5.2-rc1 2019-05-07 12:48:10 -07:00
mbcache.c
mount.h
mpage.c
namei.c
namespace.c
no-block.c
nsfs.c dcache: sort the freeing-without-RCU-delay mess for good. 2019-04-09 19:18:04 -04:00
open.c vfs: pass ppos=NULL to .read()/.write() of FMODE_STREAM files 2019-05-06 17:46:52 +03:00
pipe.c Merge branch 'page-refs' (page ref overflow) 2019-04-14 15:09:40 -07:00
pnode.c
pnode.h
posix_acl.c
proc_namespace.c
read_write.c vfs: pass ppos=NULL to .read()/.write() of FMODE_STREAM files 2019-05-06 17:46:52 +03:00
readdir.c
select.c
seq_file.c
signalfd.c
splice.c There tracing fixes: 2019-04-26 11:09:55 -07:00
stack.c
stat.c
statfs.c
super.c [fix] get rid of checking for absent device name in vfs_get_tree() 2019-04-28 21:34:21 -04:00
sync.c
timerfd.c
userfaultfd.c coredump: fix race condition between mmget_not_zero()/get_task_mm() and core dumping 2019-04-19 09:46:05 -07:00
utimes.c
xattr.c