From a1ec9e41a162513525e861ef713ce50d40a436bb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 7 Jun 2018 12:36:41 +0200 Subject: [PATCH] 4.16-stable patches added patches: mmap-introduce-sane-default-mmap-limits.patch mmap-relax-file-size-limit-for-regular-files.patch --- ...p-introduce-sane-default-mmap-limits.patch | 124 ++++++++++++++++++ ...ax-file-size-limit-for-regular-files.patch | 54 ++++++++ queue-4.16/series | 2 + 3 files changed, 180 insertions(+) create mode 100644 queue-4.16/mmap-introduce-sane-default-mmap-limits.patch create mode 100644 queue-4.16/mmap-relax-file-size-limit-for-regular-files.patch diff --git a/queue-4.16/mmap-introduce-sane-default-mmap-limits.patch b/queue-4.16/mmap-introduce-sane-default-mmap-limits.patch new file mode 100644 index 00000000000..3463077b503 --- /dev/null +++ b/queue-4.16/mmap-introduce-sane-default-mmap-limits.patch @@ -0,0 +1,124 @@ +From be83bbf806822b1b89e0a0f23cd87cddc409e429 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Fri, 11 May 2018 09:52:01 -0700 +Subject: mmap: introduce sane default mmap limits + +From: Linus Torvalds + +commit be83bbf806822b1b89e0a0f23cd87cddc409e429 upstream. + +The internal VM "mmap()" interfaces are based on the mmap target doing +everything using page indexes rather than byte offsets, because +traditionally (ie 32-bit) we had the situation that the byte offset +didn't fit in a register. So while the mmap virtual address was limited +by the word size of the architecture, the backing store was not. + +So we're basically passing "pgoff" around as a page index, in order to +be able to describe backing store locations that are much bigger than +the word size (think files larger than 4GB etc). + +But while this all makes a ton of sense conceptually, we've been dogged +by various drivers that don't really understand this, and internally +work with byte offsets, and then try to work with the page index by +turning it into a byte offset with "pgoff << PAGE_SHIFT". + +Which obviously can overflow. + +Adding the size of the mapping to it to get the byte offset of the end +of the backing store just exacerbates the problem, and if you then use +this overflow-prone value to check various limits of your device driver +mmap capability, you're just setting yourself up for problems. + +The correct thing for drivers to do is to do their limit math in page +indices, the way the interface is designed. Because the generic mmap +code _does_ test that the index doesn't overflow, since that's what the +mmap code really cares about. + +HOWEVER. + +Finding and fixing various random drivers is a sisyphean task, so let's +just see if we can just make the core mmap() code do the limiting for +us. Realistically, the only "big" backing stores we need to care about +are regular files and block devices, both of which are known to do this +properly, and which have nice well-defined limits for how much data they +can access. + +So let's special-case just those two known cases, and then limit other +random mmap users to a backing store that still fits in "unsigned long". +Realistically, that's not much of a limit at all on 64-bit, and on +32-bit architectures the only worry might be the GPU drivers, which can +have big physical address spaces. + +To make it possible for drivers like that to say that they are 64-bit +clean, this patch does repurpose the "FMODE_UNSIGNED_OFFSET" bit in the +file flags to allow drivers to mark their file descriptors as safe in +the full 64-bit mmap address space. + +[ The timing for doing this is less than optimal, and this should really + go in a merge window. But realistically, this needs wide testing more + than it needs anything else, and being main-line is the only way to do + that. + + So the earlier the better, even if it's outside the proper development + cycle - Linus ] + +Cc: Kees Cook +Cc: Dan Carpenter +Cc: Al Viro +Cc: Willy Tarreau +Cc: Dave Airlie +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/mmap.c | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -1315,6 +1315,35 @@ static inline int mlock_future_check(str + return 0; + } + ++static inline u64 file_mmap_size_max(struct file *file, struct inode *inode) ++{ ++ if (S_ISREG(inode->i_mode)) ++ return inode->i_sb->s_maxbytes; ++ ++ if (S_ISBLK(inode->i_mode)) ++ return MAX_LFS_FILESIZE; ++ ++ /* Special "we do even unsigned file positions" case */ ++ if (file->f_mode & FMODE_UNSIGNED_OFFSET) ++ return 0; ++ ++ /* Yes, random drivers might want more. But I'm tired of buggy drivers */ ++ return ULONG_MAX; ++} ++ ++static inline bool file_mmap_ok(struct file *file, struct inode *inode, ++ unsigned long pgoff, unsigned long len) ++{ ++ u64 maxsize = file_mmap_size_max(file, inode); ++ ++ if (maxsize && len > maxsize) ++ return false; ++ maxsize -= len; ++ if (pgoff > maxsize >> PAGE_SHIFT) ++ return false; ++ return true; ++} ++ + /* + * The caller must hold down_write(¤t->mm->mmap_sem). + */ +@@ -1389,6 +1418,9 @@ unsigned long do_mmap(struct file *file, + struct inode *inode = file_inode(file); + unsigned long flags_mask; + ++ if (!file_mmap_ok(file, inode, pgoff, len)) ++ return -EOVERFLOW; ++ + flags_mask = LEGACY_MAP_MASK | file->f_op->mmap_supported_flags; + + switch (flags & MAP_TYPE) { diff --git a/queue-4.16/mmap-relax-file-size-limit-for-regular-files.patch b/queue-4.16/mmap-relax-file-size-limit-for-regular-files.patch new file mode 100644 index 00000000000..575ced7477c --- /dev/null +++ b/queue-4.16/mmap-relax-file-size-limit-for-regular-files.patch @@ -0,0 +1,54 @@ +From 423913ad4ae5b3e8fb8983f70969fb522261ba26 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Sat, 19 May 2018 09:29:11 -0700 +Subject: mmap: relax file size limit for regular files + +From: Linus Torvalds + +commit 423913ad4ae5b3e8fb8983f70969fb522261ba26 upstream. + +Commit be83bbf80682 ("mmap: introduce sane default mmap limits") was +introduced to catch problems in various ad-hoc character device drivers +doing mmap and getting the size limits wrong. In the process, it used +"known good" limits for the normal cases of mapping regular files and +block device drivers. + +It turns out that the "s_maxbytes" limit was less "known good" than I +thought. In particular, /proc doesn't set it, but exposes one regular +file to mmap: /proc/vmcore. As a result, that file got limited to the +default MAX_INT s_maxbytes value. + +This went unnoticed for a while, because apparently the only thing that +needs it is the s390 kernel zfcpdump, but there might be other tools +that use this too. + +Vasily suggested just changing s_maxbytes for all of /proc, which isn't +wrong, but makes me nervous at this stage. So instead, just make the +new mmap limit always be MAX_LFS_FILESIZE for regular files, which won't +affect anything else. It wasn't the regular file case I was worried +about. + +I'd really prefer for maxsize to have been per-inode, but that is not +how things are today. + +Fixes: be83bbf80682 ("mmap: introduce sane default mmap limits") +Reported-by: Vasily Gorbik +Cc: Al Viro +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/mmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -1318,7 +1318,7 @@ static inline int mlock_future_check(str + static inline u64 file_mmap_size_max(struct file *file, struct inode *inode) + { + if (S_ISREG(inode->i_mode)) +- return inode->i_sb->s_maxbytes; ++ return MAX_LFS_FILESIZE; + + if (S_ISBLK(inode->i_mode)) + return MAX_LFS_FILESIZE; diff --git a/queue-4.16/series b/queue-4.16/series index e69de29bb2d..d10b5a3337f 100644 --- a/queue-4.16/series +++ b/queue-4.16/series @@ -0,0 +1,2 @@ +mmap-introduce-sane-default-mmap-limits.patch +mmap-relax-file-size-limit-for-regular-files.patch -- 2.47.3