linux/fs
Hugh Dickins cfc0eb4038 mm: larger stack guard gap, between vmas
commit 1be7107fbe upstream.

Stack guard page is a useful feature to reduce a risk of stack smashing
into a different mapping. We have been using a single page gap which
is sufficient to prevent having stack adjacent to a different mapping.
But this seems to be insufficient in the light of the stack usage in
userspace. E.g. glibc uses as large as 64kB alloca() in many commonly
used functions. Others use constructs liks gid_t buffer[NGROUPS_MAX]
which is 256kB or stack strings with MAX_ARG_STRLEN.

This will become especially dangerous for suid binaries and the default
no limit for the stack size limit because those applications can be
tricked to consume a large portion of the stack and a single glibc call
could jump over the guard page. These attacks are not theoretical,
unfortunatelly.

Make those attacks less probable by increasing the stack guard gap
to 1MB (on systems with 4k pages; but make it depend on the page size
because systems with larger base pages might cap stack allocations in
the PAGE_SIZE units) which should cover larger alloca() and VLA stack
allocations. It is obviously not a full fix because the problem is
somehow inherent, but it should reduce attack space a lot.

One could argue that the gap size should be configurable from userspace,
but that can be done later when somebody finds that the new 1MB is wrong
for some special case applications.  For now, add a kernel command line
option (stack_guard_gap) to specify the stack gap size (in page units).

Implementation wise, first delete all the old code for stack guard page:
because although we could get away with accounting one extra page in a
stack vma, accounting a larger gap can break userspace - case in point,
a program run with "ulimit -S -v 20000" failed when the 1MB gap was
counted for RLIMIT_AS; similar problems could come with RLIMIT_MLOCK
and strict non-overcommit mode.

Instead of keeping gap inside the stack vma, maintain the stack guard
gap as a gap between vmas: using vm_start_gap() in place of vm_start
(or vm_end_gap() in place of vm_end if VM_GROWSUP) in just those few
places which need to respect the gap - mainly arch_get_unmapped_area(),
and and the vma tree's subtree_gap support for that.

Original-patch-by: Oleg Nesterov <oleg@redhat.com>
Original-patch-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Hugh Dickins <hughd@google.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Tested-by: Helge Deller <deller@gmx.de> # parisc
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[wt: backport to 4.11: adjust context]
[wt: backport to 4.9: adjust context ; kernel doc was not in admin-guide]
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2017-06-24 07:11:18 +02:00
..
9p 9p: fix a potential acl leak 2017-05-14 14:00:13 +02:00
adfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
affs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
afs fs: Better permission checking for submounts 2017-03-15 10:02:44 +08:00
autofs4 fs: Better permission checking for submounts 2017-03-15 10:02:44 +08:00
befs befs fixes for 4.9-rc1 2016-10-15 12:09:13 -07:00
bfs Merge remote-tracking branch 'ovl/rename2' into for-linus 2016-10-10 23:02:51 -04:00
btrfs crypto: Work around deallocated stack frame reference gcc bug on sparc. 2017-06-24 07:11:17 +02:00
cachefiles Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
ceph fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
cifs CIFS: add misssing SFM mapping for doublequote 2017-05-20 14:28:40 +02:00
coda Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
configfs configfs: Fix race between create_link and configfs_rmdir 2017-06-24 07:11:12 +02:00
cramfs more trivial ->iterate_shared conversions 2016-05-09 11:41:14 -04:00
crypto fscrypt: avoid collisions when presenting long encrypted filenames 2017-05-25 15:44:38 +02:00
debugfs fs: Better permission checking for submounts 2017-03-15 10:02:44 +08:00
devpts Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
dlm dlm: free workqueues after the connections 2016-10-10 09:54:00 -05:00
ecryptfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
efivarfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
efs fs/efs/super.c: fix return value 2016-05-20 17:58:30 -07:00
exofs fs: exofs: print a hex number after a 0x prefix 2016-10-27 18:43:43 -07:00
exportfs exportfs: be careful to only return expected errors. 2016-10-06 09:07:44 -04:00
ext2 ext2: avoid bogus -Wmaybe-uninitialized warning 2016-10-18 11:29:35 +02:00
ext4 fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
f2fs crypto: Work around deallocated stack frame reference gcc bug on sparc. 2017-06-24 07:11:17 +02:00
fat fat: fix using uninitialized fields of fat_inode/fsinfo_inode 2017-03-15 10:02:52 +08:00
freevxfs freevxfs: update Kconfig information 2016-06-13 10:20:39 +02:00
fscache FS-Cache: Initialise stores_lock in netfs cookie 2017-06-17 06:41:52 +02:00
fuse fuse: add missing FR_FORCE 2017-03-12 06:41:47 +01:00
gfs2 gfs2: Use rhashtable walk interface in glock_hash_walk 2017-06-17 06:41:50 +02:00
hfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
hfsplus Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
hostfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
hpfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
hugetlbfs mm: larger stack guard gap, between vmas 2017-06-24 07:11:18 +02:00
isofs isofs: add KERN_CONT to printing of ER records 2016-11-30 10:41:26 -08:00
jbd2 jbd2: don't leak memory if setting up journal fails 2017-03-30 09:41:27 +02:00
jffs2 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
jfs fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
kernfs kernfs: Add noop_fsync to supported kernfs_file_fops 2016-10-27 17:47:11 +02:00
lockd treewide: remove redundant #include <linux/kconfig.h> 2016-10-11 15:06:33 -07:00
logfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
minix Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
ncpfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
nfs nfs: Fix "Don't increment lock sequence ID after NFS4ERR_MOVED" 2017-06-17 06:41:55 +02:00
nfs_common lockd: NLM grace period shouldn't block NFSv4 opens 2015-08-13 10:22:06 -04:00
nfsd fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
nilfs2 fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
nls nls: have register_nls() set ->owner 2014-01-25 03:14:05 -05:00
notify fanotify: don't expose EOPENSTALE to userspace 2017-05-25 15:44:31 +02:00
ntfs fs: remove the never implemented aio_fsync file operation 2016-10-30 13:09:42 -04:00
ocfs2 fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
omfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
openpromfs fs: Replace CURRENT_TIME with current_time() for inode timestamps 2016-09-27 21:06:21 -04:00
orangefs fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
overlayfs ovl: fix d_real() for stacked fs 2016-11-29 10:20:24 +01:00
proc mm: larger stack guard gap, between vmas 2017-06-24 07:11:18 +02:00
pstore pstore: Shut down worker when unregistering 2017-05-20 14:28:42 +02:00
qnx4 more trivial ->iterate_shared conversions 2016-05-09 11:41:14 -04:00
qnx6 more trivial ->iterate_shared conversions 2016-05-09 11:41:14 -04:00
quota quota: fill in Q_XGETQSTAT inode information for inactive quotas 2016-08-15 17:43:31 +02:00
ramfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
reiserfs fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
romfs romfs: use different way to generate fsid for BLOCK or MTD 2017-06-17 06:41:56 +02:00
squashfs vfs: Remove {get,set,remove}xattr inode operations 2016-10-07 21:48:36 -04:00
sysfs sysfs: be careful of error returns from ops->show() 2017-04-12 12:41:11 +02:00
sysv Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
tracefs fs: Replace CURRENT_TIME with current_time() for inode timestamps 2016-09-27 21:06:21 -04:00
ubifs ubifs: Fix O_TMPFILE corner case in ubifs_link() 2017-04-27 09:10:38 +02:00
udf fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
ufs ufs_getfrag_block(): we only grab ->truncate_mutex on block creation path 2017-06-14 15:06:01 +02:00
xfs fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
aio.c aio: fix freeze protection of aio writes 2016-10-30 13:09:42 -04:00
anon_inodes.c vfs: Allocate anon_inode_inode in anon_inode_init() 2014-03-27 09:52:54 -07:00
attr.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
bad_inode.c bad_inode: add missing i_op initializers 2017-01-09 08:32:24 +01:00
binfmt_aout.c fs: fix binfmt_aout.c build error 2016-05-28 16:34:59 -07:00
binfmt_elf.c x86/coredump: Use pr_reg size, rather that TIF_IA32 flag 2016-09-14 21:28:10 +02:00
binfmt_elf_fdpic.c elf_fdpic_transfer_args_to_stack(): make it generic 2016-07-25 16:51:49 +10:00
binfmt_em86.c fs/binfmt_em86.c: fix incompatible pointer type 2016-08-02 19:35:15 -04:00
binfmt_flat.c binfmt_flat: allow compressed flat binary format to work on MMU systems 2016-07-28 13:29:12 +10:00
binfmt_misc.c fs: Replace current_fs_time() with current_time() 2016-09-27 21:06:22 -04:00
binfmt_script.c syscalls: implement execveat() system call 2014-12-13 12:42:51 -08:00
block_dev.c fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
buffer.c fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
char_dev.c dax: define a unified inode/address_space for device-dax mappings 2016-08-23 22:58:51 -07:00
compat.c compat: remove compat_printk() 2016-09-27 21:20:53 -04:00
compat_binfmt_elf.c binfmt_elf: add ELF_HWCAP2 to compat auxv entries 2014-03-04 08:05:21 +00:00
compat_ioctl.c fs: compat_ioctl: add pretimeout functions for watchdogs 2016-09-24 09:27:18 +02:00
coredump.c coredump: fix unfreezable coredumping task 2016-11-11 08:12:37 -08:00
dax.c fs: break out of iomap_file_buffered_write on fatal signals 2017-02-09 08:08:31 +01:00
dcache.c mnt: Protect the mountpoint hashtable with mount_lock 2017-01-19 20:18:03 +01:00
dcookies.c fs/compat: fix lookup_dcookie() parameter handling 2014-01-29 16:22:40 -08:00
direct-io.c fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
drop_caches.c inode: convert inode_sb_list_lock to per-sb 2015-08-17 18:39:46 -04:00
eventfd.c eventfd: document lockless access in eventfd_poll 2016-03-22 15:36:02 -07:00
eventpoll.c fs: poll/select/recvmmsg: use timespec64 for timeout events 2016-05-19 19:12:14 -07:00
exec.c ptrace: Capture the ptracer's creds not PT_PTRACE_CAP 2017-01-06 10:40:13 +01:00
fcntl.c fcntl: allow to set O_DIRECT flag on pipe 2016-01-09 02:55:37 -05:00
fhandle.c fs/coredump: prevent fsuid=0 dumps into user-controlled directories 2016-03-22 15:36:02 -07:00
file.c fs/file: more unsigned file descriptors 2016-09-27 18:47:38 -04:00
file_table.c fs, file table: reinit files_stat.max_files after deferred memory initialisation 2015-08-07 04:39:40 +03:00
filesystems.c find_filesystem(): simplify comparison 2016-01-19 12:02:23 -05:00
fs-writeback.c mm, writeback: flush plugged IO in wakeup_flusher_threads() 2016-08-09 19:58:06 -06:00
fs_pin.c fs_pin: Allow for the possibility that m_list or s_list go unused. 2015-04-09 11:39:55 -05:00
fs_struct.c seqcount: Add lockdep functionality to seqcount/seqlock structures 2013-11-06 12:40:26 +01:00
inode.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
internal.h Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 13:04:49 -07:00
ioctl.c vfs: cap dedupe request structure size at PAGE_SIZE 2016-09-15 13:29:52 -07:00
iomap.c fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
Kconfig mm/hugetlb: introduce ARCH_HAS_GIGANTIC_PAGE 2016-10-07 18:46:29 -07:00
Kconfig.binfmt ARM: 8594/1: enable binfmt_flat on systems with an MMU 2016-08-12 16:47:05 +01:00
libfs.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
locks.c locking, fs/locks: Add missing file_sem locks 2016-10-18 12:21:28 +02:00
Makefile fs: introduce iomap infrastructure 2016-06-21 09:23:11 +10:00
mbcache.c mbcache: fix to detect failure of register_shrinker 2016-08-31 11:44:36 -04:00
mount.h mnt: Tuck mounts under others instead of creating shadow/side mounts. 2017-03-15 10:02:43 +08:00
mpage.c fs: add i_blocksize() 2017-06-14 15:06:00 +02:00
namei.c fs: Better permission checking for submounts 2017-03-15 10:02:44 +08:00
namespace.c fs: Better permission checking for submounts 2017-03-15 10:02:44 +08:00
no-block.c llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
nsfs.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
open.c xfs: reflink update for 4.9-rc1 2016-10-13 20:28:22 -07:00
pipe.c pipe: cap initial pipe capacity according to pipe-max-size limit 2016-10-11 15:06:32 -07:00
pnode.c mnt: Tuck mounts under others instead of creating shadow/side mounts. 2017-03-15 10:02:43 +08:00
pnode.h mnt: Tuck mounts under others instead of creating shadow/side mounts. 2017-03-15 10:02:43 +08:00
posix_acl.c tmpfs: clear S_ISGID when setting posix ACLs 2017-01-26 08:24:37 +01:00
proc_namespace.c vfs: show_vfsstat: do not ignore errors from show_devname method 2016-03-16 13:09:08 -04:00
read_write.c fs: pass on flags in compat_writev 2017-06-24 07:11:12 +02:00
readdir.c restore killability of old mutex_lock_killable(&inode->i_mutex) users 2016-05-26 00:13:25 -04:00
select.c fs/select: add vmalloc fallback for select(2) 2016-10-11 15:06:30 -07:00
seq_file.c seq/proc: modify seq_put_decimal_[u]ll to take a const char *, not char 2016-10-07 18:46:30 -07:00
signalfd.c signalfd: fix information leak in signalfd_copyinfo 2015-08-07 04:39:40 +03:00
splice.c vfs: fix uninitialized flags in splice_to_pipe() 2017-02-23 17:44:35 +01:00
stack.c fs: fix comment for 'CONFIG_LBADF' 2014-08-26 09:35:56 +02:00
stat.c ufs: restore maintaining ->i_blocks 2017-06-14 15:06:01 +02:00
statfs.c vfs: allow O_PATH file descriptors for fstatfs() 2013-10-12 13:12:31 -07:00
super.c fs: Better permission checking for submounts 2017-03-15 10:02:44 +08:00
sync.c mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros 2016-04-04 10:41:08 -07:00
timerfd.c timerfd: Protect the might cancel mechanism proper 2017-05-08 07:47:54 +02:00
userfaultfd.c userfaultfd: fix SIGBUS resulting from false rwsem wakeups 2017-06-17 06:41:56 +02:00
utimes.c Merge remote-tracking branch 'jk/vfs' into work.misc 2016-10-08 11:06:08 -04:00
xattr.c fs/xattr.c: zero out memory copied to userspace in getxattr 2017-05-20 14:28:39 +02:00