linux/fs
Cong Wang 49ffe04fcd nsfs: mark dentry with DCACHE_RCUACCESS
commit 073c516ff7 upstream.

Andrey reported a use-after-free in __ns_get_path():

  spin_lock include/linux/spinlock.h:299 [inline]
  lockref_get_not_dead+0x19/0x80 lib/lockref.c:179
  __ns_get_path+0x197/0x860 fs/nsfs.c:66
  open_related_ns+0xda/0x200 fs/nsfs.c:143
  sock_ioctl+0x39d/0x440 net/socket.c:1001
  vfs_ioctl fs/ioctl.c:45 [inline]
  do_vfs_ioctl+0x1bf/0x1780 fs/ioctl.c:685
  SYSC_ioctl fs/ioctl.c:700 [inline]
  SyS_ioctl+0x8f/0xc0 fs/ioctl.c:691

We are under rcu read lock protection at that point:

        rcu_read_lock();
        d = atomic_long_read(&ns->stashed);
        if (!d)
                goto slow;
        dentry = (struct dentry *)d;
        if (!lockref_get_not_dead(&dentry->d_lockref))
                goto slow;
        rcu_read_unlock();

but don't use a proper RCU API on the free path, therefore a parallel
__d_free() could free it at the same time.  We need to mark the stashed
dentry with DCACHE_RCUACCESS so that __d_free() will be called after all
readers leave RCU.

Fixes: e149ed2b80 ("take the targets of /proc/*/ns/* symlinks to separate fs")
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Eric Biggers <ebiggers3@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-02-16 20:09:43 +01:00
..
9p fs/9p: Compare qid.path in v9fs_test_inode 2017-11-30 08:37:22 +00:00
adfs
affs
afs afs: Fix afs_kill_pages() 2017-12-20 10:04:56 +01:00
autofs4 autofs: fix careless error in recent commit 2017-12-20 10:04:51 +01:00
befs
bfs
btrfs btrfs: fix deadlock when writing out space cache 2018-02-03 17:04:27 +01:00
cachefiles
ceph ceph: drop negative child dentries before try pruning inode's alias 2017-12-20 10:04:52 +01:00
cifs CIFS: zero sensitive data when freeing 2018-02-16 20:09:39 +01:00
coda coda: fix 'kernel memory exposure attempt' in fsync 2017-11-24 08:32:25 +01:00
configfs configfs: Fix race between create_link and configfs_rmdir 2017-06-26 07:13:08 +02:00
cramfs
debugfs dentry name snapshots 2017-08-06 19:19:42 -07:00
devpts
dlm dlm: avoid double-free on error path in dlm_device_{register,unregister} 2017-09-13 14:09:45 -07:00
ecryptfs eCryptfs: use after free in ecryptfs_release_messaging() 2017-11-30 08:37:20 +00:00
efivarfs
efs
exofs
exportfs
ext2 ext2: Don't clear SGID when inheriting ACLs 2018-01-31 12:06:11 +01:00
ext4 don't put symlink bodies in pagecache into highmem 2018-02-16 20:09:38 +01:00
f2fs don't put symlink bodies in pagecache into highmem 2018-02-16 20:09:38 +01:00
fat fat: fix using uninitialized fields of fat_inode/fsinfo_inode 2017-03-15 09:57:15 +08:00
freevxfs
fscache FS-Cache: fix dereference of NULL user_key_payload 2017-10-27 10:23:18 +02:00
fuse fuse: fix READDIRPLUS skipping an entry 2017-11-02 09:40:49 +01:00
gfs2 GFS2: Take inode off order_write list when setting jdata flag 2017-12-20 10:04:59 +01:00
hfs
hfsplus
hostfs
hpfs
hugetlbfs mm: larger stack guard gap, between vmas 2017-06-26 07:13:11 +02:00
isofs isofs: fix timestamps beyond 2027 2017-11-30 08:37:20 +00:00
jbd2 jbd2: don't leak modified metadata buffers on an aborted journal 2017-03-12 06:37:26 +01:00
jffs2
jfs fs: add i_blocksize() 2017-06-14 13:16:24 +02:00
kernfs kernfs: fix regression in kernfs_fop_write caused by wrong type 2018-02-16 20:09:42 +01:00
lockd
logfs
minix
ncpfs
nfs NFS: reject request for id_legacy key without auxdata 2018-02-16 20:09:42 +01:00
nfs_common lockd: fix "list_add double add" caused by legacy signal interface 2018-02-03 17:04:28 +01:00
nfsd lockd: fix "list_add double add" caused by legacy signal interface 2018-02-03 17:04:28 +01:00
nilfs2 nilfs2: fix race condition that causes file system corruption 2017-11-30 08:37:20 +00:00
nls
notify dentry name snapshots 2017-08-06 19:19:42 -07:00
ntfs
ocfs2 Revert "ocfs2: should wait dio before inode lock in ocfs2_setattr()" 2017-12-09 18:42:43 +01:00
omfs
openpromfs
overlayfs
proc tty fix oops when rmmod 8250 2017-12-20 10:05:00 +01:00
pstore pstore: Use dynamic spinlock initializer 2017-08-06 19:19:43 -07:00
qnx4
qnx6
quota quota: Check for register_shrinker() failure. 2018-02-03 17:04:28 +01:00
ramfs
reiserfs reiserfs: Don't clear SGID when inheriting ACLs 2018-01-31 12:06:11 +01:00
romfs romfs: use different way to generate fsid for BLOCK or MTD 2017-06-17 06:39:38 +02:00
squashfs
sysfs sysfs: be careful of error returns from ops->show() 2017-04-12 12:38:33 +02:00
sysv
tracefs
ubifs ubifs: Fix journal replay wrt. xattr nodes 2017-01-26 08:23:48 +01:00
udf udf: Avoid overflow when session starts at large offset 2017-12-20 10:05:01 +01:00
ufs ufs_getfrag_block(): we only grab ->truncate_mutex on block creation path 2017-06-14 13:16:24 +02:00
xfs xfs: ubsan fixes 2018-02-03 17:04:29 +01:00
aio.c
anon_inodes.c
attr.c
bad_inode.c
binfmt_aout.c
binfmt_elf_fdpic.c
binfmt_elf.c binfmt_elf: use ELF_ET_DYN_BASE only for PIE 2017-07-21 07:44:57 +02:00
binfmt_em86.c
binfmt_flat.c
binfmt_misc.c
binfmt_script.c
block_dev.c fs/block_dev: always invalidate cleancache in invalidate_bdev() 2017-05-20 14:27:01 +02:00
buffer.c fs: add i_blocksize() 2017-06-14 13:16:24 +02:00
char_dev.c
compat_binfmt_elf.c
compat_ioctl.c
compat.c
coredump.c coredump: Ensure proper size of sparse core files 2017-07-05 14:37:20 +02:00
dax.c
dcache.c dentry name snapshots 2017-08-06 19:19:42 -07:00
dcookies.c
direct-io.c direct-io: Prevent NULL pointer access in submit_page_section 2017-10-18 09:20:42 +02:00
drop_caches.c
eventfd.c
eventpoll.c epoll: fix race between ep_poll_callback(POLLFREE) and ep_free()/ep_remove() 2017-09-07 08:34:10 +02:00
exec.c exec: Limit arg stack to at most 75% of _STK_LIM 2017-07-21 07:44:57 +02:00
fcntl.c fs/fcntl: f_setown, avoid undefined behaviour 2018-01-31 12:06:11 +01:00
fhandle.c
file_table.c
file.c
filesystems.c
fs_pin.c
fs_struct.c
fs-writeback.c writeback: fix memory leak in wb_queue_work() 2017-12-20 10:04:54 +01:00
inode.c don't put symlink bodies in pagecache into highmem 2018-02-16 20:09:38 +01:00
internal.h
ioctl.c
Kconfig
Kconfig.binfmt
libfs.c
locks.c locks: don't check for race with close when setting OFD lock 2018-01-17 09:35:27 +01:00
Makefile
mbcache.c
mount.h mnt: In propgate_umount handle visiting mounts in any order 2017-07-21 07:44:57 +02:00
mpage.c fs: add i_blocksize() 2017-06-14 13:16:24 +02:00
namei.c dentry name snapshots 2017-08-06 19:19:42 -07:00
namespace.c mnt: In propgate_umount handle visiting mounts in any order 2017-07-21 07:44:57 +02:00
no-block.c
nsfs.c nsfs: mark dentry with DCACHE_RCUACCESS 2018-02-16 20:09:43 +01:00
open.c fs: completely ignore unknown open flags 2017-07-15 11:57:44 +02:00
pipe.c pipe: avoid round_pipe_size() nr_pages overflow on 32-bit 2018-01-23 19:50:15 +01:00
pnode.c mnt: Make propagate_umount less slow for overlapping mount propagation trees 2017-07-21 07:44:58 +02:00
pnode.h mnt: Add a per mount namespace limit on the number of mounts 2017-04-30 05:49:28 +02:00
posix_acl.c tmpfs: clear S_ISGID when setting posix ACLs 2017-01-26 08:23:47 +01:00
proc_namespace.c
read_write.c vfs: Return -ENXIO for negative SEEK_HOLE / SEEK_DATA offsets 2017-10-05 09:41:45 +02:00
readdir.c
select.c fs/select: add vmalloc fallback for select(2) 2018-01-31 12:06:09 +01:00
seq_file.c Make file credentials available to the seqfile interfaces 2017-08-06 19:19:42 -07:00
signalfd.c
splice.c vfs: fix uninitialized flags in splice_to_pipe() 2017-02-23 17:43:09 +01:00
stack.c
stat.c ufs: restore maintaining ->i_blocks 2017-06-14 13:16:24 +02:00
statfs.c
super.c
sync.c
timerfd.c timerfd: Protect the might cancel mechanism proper 2017-05-08 07:46:01 +02:00
userfaultfd.c userfaultfd: shmem: __do_fault requires VM_FAULT_NOPAGE 2017-12-20 10:04:53 +01:00
utimes.c
xattr.c lsm: fix smack_inode_removexattr and xattr_getsecurity memleak 2017-10-12 11:27:32 +02:00