WSL2-Linux-Kernel/fs
Kees Cook 56af7c0ea7 binfmt_elf: move brk out of mmap when doing direct loader exec
commit bbdc6076d2 upstream.

Commmit eab09532d4 ("binfmt_elf: use ELF_ET_DYN_BASE only for PIE"),
made changes in the rare case when the ELF loader was directly invoked
(e.g to set a non-inheritable LD_LIBRARY_PATH, testing new versions of
the loader), by moving into the mmap region to avoid both ET_EXEC and
PIE binaries.  This had the effect of also moving the brk region into
mmap, which could lead to the stack and brk being arbitrarily close to
each other.  An unlucky process wouldn't get its requested stack size
and stack allocations could end up scribbling on the heap.

This is illustrated here.  In the case of using the loader directly, brk
(so helpfully identified as "[heap]") is allocated with the _loader_ not
the binary.  For example, with ASLR entirely disabled, you can see this
more clearly:

$ /bin/cat /proc/self/maps
555555554000-55555555c000 r-xp 00000000 ... /bin/cat
55555575b000-55555575c000 r--p 00007000 ... /bin/cat
55555575c000-55555575d000 rw-p 00008000 ... /bin/cat
55555575d000-55555577e000 rw-p 00000000 ... [heap]
...
7ffff7ff7000-7ffff7ffa000 r--p 00000000 ... [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 ... [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00027000 ... /lib/x86_64-linux-gnu/ld-2.27.so
7ffff7ffd000-7ffff7ffe000 rw-p 00028000 ... /lib/x86_64-linux-gnu/ld-2.27.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 ...
7ffffffde000-7ffffffff000 rw-p 00000000 ... [stack]

$ /lib/x86_64-linux-gnu/ld-2.27.so /bin/cat /proc/self/maps
...
7ffff7bcc000-7ffff7bd4000 r-xp 00000000 ... /bin/cat
7ffff7bd4000-7ffff7dd3000 ---p 00008000 ... /bin/cat
7ffff7dd3000-7ffff7dd4000 r--p 00007000 ... /bin/cat
7ffff7dd4000-7ffff7dd5000 rw-p 00008000 ... /bin/cat
7ffff7dd5000-7ffff7dfc000 r-xp 00000000 ... /lib/x86_64-linux-gnu/ld-2.27.so
7ffff7fb2000-7ffff7fd6000 rw-p 00000000 ...
7ffff7ff7000-7ffff7ffa000 r--p 00000000 ... [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 ... [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00027000 ... /lib/x86_64-linux-gnu/ld-2.27.so
7ffff7ffd000-7ffff7ffe000 rw-p 00028000 ... /lib/x86_64-linux-gnu/ld-2.27.so
7ffff7ffe000-7ffff8020000 rw-p 00000000 ... [heap]
7ffffffde000-7ffffffff000 rw-p 00000000 ... [stack]

The solution is to move brk out of mmap and into ELF_ET_DYN_BASE since
nothing is there in the direct loader case (and ET_EXEC is still far
away at 0x400000).  Anything that ran before should still work (i.e.
the ultimately-launched binary already had the brk very far from its
text, so this should be no different from a COMPAT_BRK standpoint).  The
only risk I see here is that if someone started to suddenly depend on
the entire memory space lower than the mmap region being available when
launching binaries via a direct loader execs which seems highly
unlikely, I'd hope: this would mean a binary would _not_ work when
exec()ed normally.

(Note that this is only done under CONFIG_ARCH_HAS_ELF_RANDOMIZATION
when randomization is turned on.)

Link: http://lkml.kernel.org/r/20190422225727.GA21011@beast
Link: https://lkml.kernel.org/r/CAGXu5jJ5sj3emOT2QPxQkNQk0qbU6zEfu9=Omfhx_p0nCKPSjA@mail.gmail.com
Fixes: eab09532d4 ("binfmt_elf: use ELF_ET_DYN_BASE only for PIE")
Signed-off-by: Kees Cook <keescook@chromium.org>
Reported-by: Ali Saidi <alisaidi@amazon.com>
Cc: Ali Saidi <alisaidi@amazon.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jann Horn <jannh@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Frank van der Linden <fllinden@amazon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-09-21 07:15:46 +02:00
..
9p 9p: pass the correct prototype to read_cache_page 2019-07-31 07:28:55 +02:00
adfs fs/adfs: super: fix use-after-free bug 2019-08-06 19:05:21 +02:00
affs affs_lookup(): close a race with affs_remove_link() 2018-05-30 07:51:47 +02:00
afs afs: Fix directory permissions check 2018-07-08 15:30:51 +02:00
autofs4 autofs: fix error return in autofs_fill_super() 2019-03-13 14:03:19 -07:00
befs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
bfs bfs: add sanity check at bfs_fill_super() 2018-12-01 09:42:51 +01:00
btrfs Btrfs: fix assertion failure during fsync and use of stale transaction 2019-09-19 09:08:04 +02:00
cachefiles fscache, cachefiles: remove redundant variable 'cache' 2018-12-17 09:28:53 +01:00
ceph ceph: fix buffer free while holding i_ceph_lock in fill_inode() 2019-09-10 10:32:18 +01:00
cifs cifs: Use kzfree() to zero out the password 2019-09-21 07:15:38 +02:00
coda coda: add error handling for fget 2019-08-06 19:05:23 +02:00
configfs configfs: Fix use-after-free when accessing sd->s_dentry 2019-06-22 08:16:17 +02:00
cramfs Cramfs: fix abad comparison when wrap-arounds occur 2018-11-13 11:15:12 -08:00
crypto fscrypt: clean up some BUG_ON()s in block encryption/decryption 2019-07-31 07:28:22 +02:00
debugfs debugfs: fix use-after-free on symlink traversal 2019-05-08 07:20:49 +02:00
devpts fs/devpts: always delete dcache dentry-s in dput() 2019-03-23 14:35:21 +01:00
dlm dlm: Don't swamp the CPU with callbacks queued during recovery 2019-02-12 19:45:57 +01:00
ecryptfs eCryptfs: fix a couple type promotion bugs 2019-07-31 07:28:42 +02:00
efivarfs VFS: Kill off s_options and helpers 2017-07-11 06:09:21 -04:00
efs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
exofs fs/exofs: fix potential memory leak in mount option parsing 2018-11-27 16:10:47 +01:00
exportfs exportfs: do not read dentry after free 2018-12-17 09:28:50 +01:00
ext2 ext2: Fix underflow in ext2_max_size() 2019-03-23 14:35:23 +01:00
ext4 ext4: allow directory holes 2019-07-31 07:28:47 +02:00
f2fs f2fs: avoid out-of-range memory access 2019-07-31 07:28:55 +02:00
fat fs/fat/file.c: issue flush after the writeback of FAT 2019-06-15 11:54:51 +02:00
freevxfs
fscache fscache: fix race between enablement and dropping of object 2018-12-17 09:28:53 +01:00
fuse fuse: retrieve: cap requested size to negotiated max_write 2019-06-15 11:54:54 +02:00
gfs2 gfs2: Fix occasional glock use-after-free 2019-05-31 06:47:14 -07:00
hfs hfs: do not free node before using 2018-12-17 09:28:54 +01:00
hfsplus hfsplus: do not free node before using 2018-12-17 09:28:54 +01:00
hostfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
hpfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
hugetlbfs hugetlb: use same fault hash key for shared and private mappings 2019-05-31 06:47:12 -07:00
isofs isofs: reject hardware sector size > 2048 bytes 2018-10-03 17:00:57 -07:00
jbd2 jbd2: introduce jbd2_inode dirty range scoping 2019-07-31 07:28:47 +02:00
jffs2 jffs2: fix use-after-free on symlink traversal 2019-05-08 07:20:49 +02:00
jfs jfs: Fix inconsistency between memory allocation and ea_buf->max_size 2018-08-09 12:16:39 +02:00
kernfs kernfs: fix barrier usage in __kernfs_new_node() 2019-05-16 19:42:19 +02:00
lockd Revert "lockd: Show pid of lockd for remote locks" 2019-06-09 09:18:18 +02:00
minix License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ncpfs staging: ncpfs: memory corruption in ncp_read_kernel() 2018-03-28 18:24:43 +02:00
nfs NFSv2: Fix write regression 2019-09-21 07:15:37 +02:00
nfs_common lockd: fix "list_add double add" caused by legacy signal interface 2018-02-03 17:39:08 +01:00
nfsd nfsd: Fix overflow causing non-working mounts on 1 TB machines 2019-07-31 07:28:48 +02:00
nilfs2 do d_instantiate/unlock_new_inode combinations safely 2018-05-30 07:51:47 +02:00
nls License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
notify fanotify: fix handling of events on child sub-directory 2019-02-06 17:31:37 +01:00
ntfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ocfs2 ocfs2: remove set but not used variable 'last_hash' 2019-08-25 10:50:17 +02:00
omfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
openpromfs Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
orangefs orangefs: report attributes_mask and attributes for statx 2018-06-26 08:06:33 +08:00
overlayfs ovl: check whiteout in ovl_create_over_whiteout() 2018-11-21 09:24:17 +01:00
proc fs/proc/proc_sysctl.c: fix the default values of i_uid/i_gid on /proc/sys inodes. 2019-07-31 07:28:38 +02:00
pstore pstore/ram: Run without kernel crash dump region 2019-06-11 12:21:48 +02:00
qnx4 License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
qnx6 License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
quota quota: fix a problem about transfer quota 2019-07-21 09:04:28 +02:00
ramfs mm: make pagevec_lookup() update index 2017-09-06 17:27:26 -07:00
reiserfs reiserfs: propagate errors from fill_with_dentries() properly 2018-11-27 16:10:46 +01:00
romfs License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
squashfs Squashfs: Compute expected length from inode size rather than block length 2018-09-05 09:26:32 +02:00
sysfs scsi: sysfs: Introduce sysfs_{un,}break_active_protection() 2018-09-05 09:26:41 +02:00
sysv sysv: return 'err' instead of 0 in __sysv_write_inode 2018-12-17 09:28:48 +01:00
tracefs VFS: Don't use save/replace_mount_options if not using generic_show_options 2017-07-06 03:31:46 -04:00
ubifs ubifs: Correctly use tnc_next() in search_dh_cookie() 2019-09-19 09:08:06 +02:00
udf udf: Fix incorrect final NOT_ALLOCATED (hole) extent length 2019-07-21 09:04:30 +02:00
ufs ufs: fix braino in ufs_get_inode_gid() for solaris UFS flavour 2019-05-25 18:25:36 +02:00
xfs xfs: fix missing ILOCK unlock when xfs_setattr_nonsize fails due to EDQUOT 2019-08-29 08:26:45 +02:00
Kconfig fs/Kconfig: kill CONFIG_PERCPU_RWSEM some more 2017-07-12 16:26:00 -07:00
Kconfig.binfmt
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
aio.c aio: fix spectre gadget in lookup_ioctx 2018-12-21 14:13:04 +01:00
anon_inodes.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
attr.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
bad_inode.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
binfmt_aout.c fs: fix kernel_read prototype 2017-09-04 19:05:15 -04:00
binfmt_elf.c binfmt_elf: move brk out of mmap when doing direct loader exec 2019-09-21 07:15:46 +02:00
binfmt_elf_fdpic.c Merge branch 'work.set_fs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-09-14 18:13:32 -07:00
binfmt_em86.c
binfmt_flat.c fs/binfmt_flat.c: make load_flat_shared_library() work 2019-07-03 13:15:59 +02:00
binfmt_misc.c fs/binfmt_misc.c: do not allow offset overflow 2018-06-26 08:06:33 +08:00
binfmt_script.c Revert "exec: load_script: don't blindly truncate shebang string" 2019-02-15 09:08:56 +01:00
block_dev.c block: fix the return errno for direct IO 2019-04-17 08:37:53 +02:00
buffer.c fs: fix guard_bio_eod to check for real EOD errors 2019-04-05 22:31:28 +02:00
char_dev.c chardev: add additional check for minor range overlap 2019-05-31 06:47:31 -07:00
compat.c fs/compat.c: trim unused includes 2017-04-17 12:52:27 -04:00
compat_binfmt_elf.c fs/binfmt: Convert obsolete cputime type to nsecs 2017-02-01 09:13:51 +01:00
compat_ioctl.c compat_ioctl: pppoe: fix PPPOEIOCSFWD handling 2019-08-09 17:53:35 +02:00
coredump.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
dax.c fs/dax.c: release PMD lock even when there is no PMD support in DAX 2018-04-26 11:02:14 +02:00
dcache.c fs/dcache: Fix incorrect nr_dentry_unused accounting in shrink_dcache_sb() 2019-02-06 17:31:34 +01:00
dcookies.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
direct-io.c iomap: report collisions between directio and buffered writes to userspace 2019-04-27 09:35:41 +02:00
drop_caches.c fs/drop_caches.c: avoid softlockups in drop_pagecache_sb() 2019-03-13 14:03:18 -07:00
eventfd.c There has been a fair amount of activity in the docs tree this time 2017-07-03 21:13:25 -07:00
eventpoll.c fs/epoll: drop ovflist branch prediction 2019-02-12 19:46:10 +01:00
exec.c sched/fair: Don't free p->numa_faults with concurrent readers 2019-08-04 09:32:03 +02:00
fcntl.c fcntl: don't cap l_start and l_end values for F_GETLK64 in compat syscall 2017-12-17 15:07:59 +01:00
fhandle.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
file.c fs/file.c: initialize init_files.resize_wait 2019-04-05 22:31:28 +02:00
file_table.c fput: Don't reinvent the wheel but use existing llist API 2017-08-28 00:50:23 -04:00
filesystems.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
fs-writeback.c blkcg, writeback: dead memcgs shouldn't contribute to writeback ownership arbitration 2019-07-31 07:28:25 +02:00
fs_pin.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
fs_struct.c sched/headers: Prepare for new header dependencies before moving code to <linux/sched/task.h> 2017-03-02 08:42:35 +01:00
inode.c Abort file_remove_privs() for non-reg. files 2019-06-22 08:16:19 +02:00
internal.h Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs 2017-09-13 09:11:44 -07:00
ioctl.c vfs: swap names of {do,vfs}_clone_file_range() 2018-11-10 07:48:33 -08:00
iomap.c iomap: report collisions between directio and buffered writes to userspace 2019-04-27 09:35:41 +02:00
libfs.c fs: convert __generic_file_fsync to use errseq_t based reporting 2017-07-06 07:02:29 -04:00
locks.c fs/lock: skip lock owner pid translation in case we are in init_pid_ns 2018-10-03 17:00:53 -07:00
mbcache.c mbcache: initialize entry->e_referenced in mb_cache_entry_create() 2018-02-22 15:42:25 +01:00
mount.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
mpage.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
namei.c namei: allow restricted O_CREAT of FIFOs and regular files 2018-12-01 09:42:59 +01:00
namespace.c mount: Prevent MNT_DETACH from disconnecting locked mounts 2018-11-21 09:24:14 +01:00
no-block.c
nsfs.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
open.c access: avoid the RCU grace period for the temporary subjective credentials 2019-07-31 07:28:58 +02:00
pipe.c fs: prevent page refcount overflow in pipe_buf_get 2019-05-04 09:15:18 +02:00
pnode.c mnt: Make propagate_umount less slow for overlapping mount propagation trees 2017-05-23 08:41:17 -05:00
pnode.h mnt: Tuck mounts under others instead of creating shadow/side mounts. 2017-02-04 00:01:06 +13:00
posix_acl.c sched/headers: Prepare to remove <linux/cred.h> inclusion from <linux/sched.h> 2017-03-02 08:42:31 +01:00
proc_namespace.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
read_write.c vfs: fix page locking deadlocks when deduping files 2019-09-10 10:32:15 +01:00
readdir.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
select.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
seq_file.c seq_file: fix incomplete reset on read from zero offset 2018-02-22 15:42:28 +01:00
signalfd.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
splice.c fs: prevent page refcount overflow in pipe_buf_get 2019-05-04 09:15:18 +02:00
stack.c
stat.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
statfs.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
super.c fs: don't scan the inode cache before SB_BORN is set 2018-05-30 07:51:47 +02:00
sync.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
timerfd.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
userfaultfd.c userfaultfd_release: always remove uffd flags and clear vm_userfaultfd_ctx 2019-08-29 08:26:43 +02:00
utimes.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xattr.c sysfs: Do not return POSIX ACL xattrs via listxattr 2018-10-10 08:54:27 +02:00