linux/fs
Linus Torvalds 03d4462ba3 fget: check that the fd still exists after getting a ref to it
commit 054aa8d439b9185d4f5eb9a90282d1ce74772969 upstream.

Jann Horn points out that there is another possible race wrt Unix domain
socket garbage collection, somewhat reminiscent of the one fixed in
commit cbcf01128d0a ("af_unix: fix garbage collect vs MSG_PEEK").

See the extended comment about the garbage collection requirements added
to unix_peek_fds() by that commit for details.

The race comes from how we can locklessly look up a file descriptor just
as it is in the process of being closed, and with the right artificial
timing (Jann added a few strategic 'mdelay(500)' calls to do that), the
Unix domain socket garbage collector could see the reference count
decrement of the close() happen before fget() took its reference to the
file and the file was attached onto a new file descriptor.

This is all (intentionally) correct on the 'struct file *' side, with
RCU lookups and lockless reference counting very much part of the
design.  Getting that reference count out of order isn't a problem per
se.

But the garbage collector can get confused by seeing this situation of
having seen a file not having any remaining external references and then
seeing it being attached to an fd.

In commit cbcf01128d0a ("af_unix: fix garbage collect vs MSG_PEEK") the
fix was to serialize the file descriptor install with the garbage
collector by taking and releasing the unix_gc_lock.

That's not really an option here, but since this all happens when we are
in the process of looking up a file descriptor, we can instead simply
just re-check that the file hasn't been closed in the meantime, and just
re-do the lookup if we raced with a concurrent close() of the same file
descriptor.

Reported-and-tested-by: Jann Horn <jannh@google.com>
Acked-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-12-08 09:01:11 +01:00
..
9p 9P: Cast to loff_t before multiplying 2020-11-05 11:43:34 +01:00
adfs
affs fs/affs: release old buffer head on error path 2021-03-04 10:26:48 +01:00
afs afs: Fix incorrect triggering of sillyrename on 3rd-party invalidation 2021-09-30 10:09:22 +02:00
autofs
befs
bfs bfs: don't use WARNING: string when it's just info. 2021-01-06 14:48:39 +01:00
btrfs btrfs: check-integrity: fix a warning on write caching disabled disk 2021-12-08 09:01:09 +01:00
cachefiles cachefiles: Handle readpage error correctly 2020-11-05 11:43:36 +01:00
ceph ceph: fix handling of "meta" errors 2021-10-27 09:54:27 +02:00
cifs smb3: do not error on fsync when readonly 2021-12-01 09:23:34 +01:00
coda
configfs configfs: fix memleak in configfs_release_bin_file 2021-07-14 16:53:46 +02:00
cramfs
crypto fscrypt: add fscrypt_symlink_getattr() for computing st_size 2021-09-12 08:56:38 +02:00
debugfs debugfs: debugfs_create_file_size(): use IS_ERR to check for error 2021-10-06 15:42:35 +02:00
devpts
dlm fs: dlm: fix memory leak when fenced 2021-07-14 16:53:17 +02:00
ecryptfs Revert "ecryptfs: replace BUG_ON with error handling code" 2021-05-26 12:05:19 +02:00
efivarfs efivarfs: revert "fix memory leak in efivarfs_create()" 2020-12-02 08:49:53 +01:00
efs
erofs erofs: fix unsafe pagevec reuse of hooked pclusters 2021-11-21 13:38:51 +01:00
exportfs
ext2 ext2: fix sleeping in atomic bugs on error 2021-10-09 14:39:49 +02:00
ext4 ext4: fix lazy initialization next schedule time computation in more granular unit 2021-11-21 13:38:50 +01:00
f2fs f2fs: set SBI_NEED_FSCK flag when inconsistent node block found 2021-12-01 09:23:34 +01:00
fat fat: don't allow to mount if the FAT length == 0 2020-06-17 16:40:36 +02:00
freevxfs
fscache fscache: Fix cookie key hashing 2021-09-22 12:26:25 +02:00
fuse fuse: release pipe buf after last use 2021-12-01 09:23:35 +01:00
gfs2 gfs2: Fix length of holes reported at end-of-file 2021-12-08 09:01:08 +01:00
hfs hfs: add lock nesting notation to hfs_find_init 2021-07-31 08:19:38 +02:00
hfsplus hfsplus: prevent corruption in shrinking truncate 2021-05-19 10:08:29 +02:00
hostfs hostfs: fix memory handling in follow_link() 2021-04-14 08:24:14 +02:00
hpfs
hugetlbfs hugetlbfs: fix mount mode command line processing 2021-07-28 13:31:01 +02:00
iomap mm/swap: consider max pages in iomap_swapfile_add_extent 2021-09-15 09:47:35 +02:00
isofs isofs: Fix out of bound access for corrupted isofs image 2021-11-12 14:43:03 +01:00
jbd2 jbd2: fix up sparse warnings in checkpoint code 2020-11-18 19:20:30 +01:00
jffs2 jffs2: check the validity of dstlen in jffs2_zlib_compress() 2021-05-11 14:04:16 +02:00
jfs JFS: fix memleak in jfs_mount 2021-11-17 09:48:42 +01:00
kernfs kernfs: do not call fsnotify() with name without a parent 2020-08-19 08:16:12 +02:00
lockd lockd: lockd server-side shouldn't set fl_ops 2021-09-22 12:26:34 +02:00
minix fs/minix: remove expected error message in block_to_path() 2020-08-21 13:05:37 +02:00
nfs NFSv42: Fix pagecache invalidation after COPY/CLONE 2021-12-08 09:01:08 +01:00
nfs_common nfs_common: need lock during iterate through the list 2020-12-30 11:51:22 +01:00
nfsd NFSD: Keep existing listeners on portlist error 2021-10-27 09:54:25 +02:00
nilfs2 nilfs2: fix memory leak in nilfs_sysfs_delete_snapshot_group 2021-09-26 14:07:13 +02:00
nls
notify fanotify: fix ignore mask logic for events on child and on dir 2020-06-17 16:40:24 +02:00
ntfs ntfs: fix validity check for file name attribute 2021-07-14 16:53:01 +02:00
ocfs2 ocfs2: fix data corruption on truncate 2021-11-17 09:48:17 +01:00
omfs
openpromfs
orangefs fs: orangefs: fix error return code of orangefs_revalidate_lookup() 2021-11-17 09:48:45 +01:00
overlayfs ovl: fix deadlock in splice write 2021-11-17 09:48:49 +01:00
proc proc/vmcore: fix clearing user buffer by properly using clear_user() 2021-12-01 09:23:31 +01:00
pstore pstore: Fix typo in compression option name 2021-03-04 10:26:45 +01:00
qnx4 qnx4: work around gcc false positive warning bug 2021-09-30 10:09:26 +02:00
qnx6
quota quota: correct error number in free_dqentry() 2021-11-17 09:48:26 +01:00
ramfs ramfs: fix nommu mmap with gaps in the page cache 2020-10-29 09:57:53 +01:00
reiserfs reiserfs: check directory items on read from disk 2021-08-12 13:21:05 +02:00
romfs romfs: fix uninitialized memory leak in romfs_dev_read() 2020-08-26 10:40:51 +02:00
squashfs squashfs: fix divide error in calculate_skip() 2021-05-19 10:08:29 +02:00
sysfs sysfs: Add sysfs_emit and sysfs_emit_at to format sysfs output 2021-03-07 12:20:48 +01:00
sysv
tracefs tracefs: Have tracefs directories not set OTH permission bits by default 2021-11-17 09:48:30 +01:00
ubifs ubifs: report correct st_size for encrypted symlinks 2021-09-12 08:56:39 +02:00
udf udf: Fix crash after seekdir 2021-11-26 10:47:21 +01:00
ufs fs/ufs: avoid potential u32 multiplication overflow 2020-08-21 13:05:37 +02:00
unicode
verity fs-verity: fix signed integer overflow with i_size near S64_MAX 2021-10-06 15:42:30 +02:00
xfs xfs: Fix assert failure in xfs_setattr_size() 2021-03-07 12:20:42 +01:00
Kconfig
Kconfig.binfmt
Makefile
aio.c aio: fix async fsync creds 2020-06-17 16:40:24 +02:00
anon_inodes.c
attr.c
bad_inode.c
binfmt_aout.c
binfmt_elf.c elf: don't use MAP_FIXED_NOREPLACE for elf interpreter mappings 2021-10-06 15:42:35 +02:00
binfmt_elf_fdpic.c
binfmt_em86.c
binfmt_flat.c binfmt_flat: revert "binfmt_flat: don't offset the data start" 2020-09-03 11:26:39 +02:00
binfmt_misc.c binfmt_misc: fix possible deadlock in bm_register_write 2021-03-17 17:03:57 +01:00
binfmt_script.c
block_dev.c block: reexpand iov_iter after read/write 2021-05-22 11:38:29 +02:00
buffer.c fs: Don't invalidate page buffers in block_write_full_page() 2020-11-05 11:43:24 +01:00
char_dev.c
compat.c
compat_binfmt_elf.c
compat_ioctl.c
coredump.c coredump: fix core_pattern parse error 2020-12-11 13:23:30 +01:00
d_path.c fs: fix NULL dereference due to data race in prepend_path() 2020-10-29 09:57:45 +01:00
dax.c dax: fix ENOMEM handling in grab_mapping_entry() 2021-07-14 16:53:25 +02:00
dcache.c fix dget_parent() fastpath race 2020-10-01 13:17:19 +02:00
dcookies.c
direct-io.c fs: direct-io: fix missing sdio->boundary 2021-04-14 08:24:11 +02:00
drop_caches.c
eventfd.c
eventpoll.c ep_create_wakeup_source(): dentry name can change under you... 2020-10-07 08:01:31 +02:00
exec.c vfs: check fd has read access in kernel_read_file_from_fd() 2021-10-27 09:54:27 +02:00
fcntl.c fcntl: fix potential deadlock for &fasync_struct.fa_lock 2021-09-15 09:47:28 +02:00
fhandle.c
file.c fget: check that the fd still exists after getting a ref to it 2021-12-08 09:01:11 +01:00
file_table.c
filesystems.c fs/filesystems.c: downgrade user-reachable WARN_ONCE() to pr_warn_once() 2020-04-17 10:50:21 +02:00
fs-writeback.c writeback: fix obtain a reference to a freeing memcg css 2021-07-14 16:53:35 +02:00
fs_context.c
fs_parser.c
fs_pin.c
fs_struct.c
fs_types.c
fsopen.c
inode.c futex: Fix inode life-time issue 2020-03-25 08:25:58 +01:00
internal.h cgroup1: fix leaked context root causing sporadic NULL deref in LTP 2021-07-31 08:19:37 +02:00
io_uring.c io_uring: Fix current->fs handling in io_sq_wq_submit_work() 2021-01-30 13:54:10 +01:00
ioctl.c
libfs.c libfs: fix error cast of negative value in simple_attr_write() 2020-11-24 13:29:19 +01:00
locks.c locks: reinstate locks_delete_block optimization 2020-03-25 08:25:41 +01:00
mbcache.c
mount.h
mpage.c
namei.c namei: only return -ECHILD from follow_dotdot_rcu() 2020-03-05 16:43:48 +01:00
namespace.c fs: warn about impending deprecation of mandatory locks 2021-08-26 08:36:22 -04:00
no-block.c
nsfs.c
open.c cifs_atomic_open(): fix double-put on late allocation failure 2020-03-18 07:17:51 +01:00
pipe.c pipe: increase minimum default pipe size to 2 pages 2021-08-12 13:21:02 +02:00
pnode.c propagate_one(): mnt_set_mountpoint() needs mount_lock 2020-05-02 08:48:44 +02:00
pnode.h mount: fix mounting of detached mounts onto targets that reside on shared mounts 2021-03-17 17:03:33 +01:00
posix_acl.c
proc_namespace.c
read_write.c
readdir.c readdir: make sure to verify directory entry for legacy interfaces too 2021-04-21 12:56:16 +02:00
select.c kernel, fs: Introduce and use set_restart_fn() and arch_set_restart_data() 2021-03-24 11:26:44 +01:00
seq_file.c seq_file: disallow extremely large seq buffer allocations 2021-07-20 16:10:54 +02:00
signalfd.c fs/signalfd.c: fix inconsistent return codes for signalfd4 2020-08-26 10:40:58 +02:00
splice.c
stack.c
stat.c
statfs.c
super.c vfs: remove lockdep bogosity in __sb_start_write 2020-11-24 13:29:01 +01:00
sync.c
timerfd.c
userfaultfd.c userfaultfd: prevent concurrent API initialization 2021-09-22 12:26:26 +02:00
utimes.c
xattr.c xattr: break delegations in {set,remove}xattr 2020-08-11 15:33:39 +02:00