All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Kees Cook <keescook@chromium.org>,
	Dan Carpenter <dan.carpenter@oracle.com>,
	Al Viro <viro@zeniv.linux.org.uk>, Willy Tarreau <w@1wt.eu>,
	Dave Airlie <airlied@redhat.com>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 3.18 09/21] mmap: introduce sane default mmap limits
Date: Tue, 12 Jun 2018 18:52:06 +0200	[thread overview]
Message-ID: <20180612164825.789715889@linuxfoundation.org> (raw)
In-Reply-To: <20180612164825.401145490@linuxfoundation.org>

3.18-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Linus Torvalds <torvalds@linux-foundation.org>

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 <keescook@chromium.org>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Willy Tarreau <w@1wt.eu>
Cc: Dave Airlie <airlied@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 mm/mmap.c |   32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1271,6 +1271,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(&current->mm->mmap_sem).
  */
@@ -1338,6 +1367,9 @@ unsigned long do_mmap_pgoff(struct file
 	if (file) {
 		struct inode *inode = file_inode(file);
 
+		if (!file_mmap_ok(file, inode, pgoff, len))
+			return -EOVERFLOW;
+
 		switch (flags & MAP_TYPE) {
 		case MAP_SHARED:
 			if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE))



  parent reply	other threads:[~2018-06-12 16:55 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-12 16:51 [PATCH 3.18 00/21] 3.18.113-stable review Greg Kroah-Hartman
2018-06-12 16:51 ` [PATCH 3.18 01/21] tracing: Fix crash when freeing instances with event triggers Greg Kroah-Hartman
2018-06-12 16:51 ` [PATCH 3.18 02/21] selinux: KASAN: slab-out-of-bounds in xattr_getsecurity Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 03/21] cfg80211: further limit wiphy names to 64 bytes Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 04/21] tcp: avoid integer overflows in tcp_rcv_space_adjust() Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 05/21] MIPS: ptrace: Fix PTRACE_PEEKUSR requests for 64-bit FGRs Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 07/21] fix io_destroy()/aio_complete() race Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 08/21] mm: fix the NULL mapping case in __isolate_lru_page() Greg Kroah-Hartman
2018-06-12 16:52 ` Greg Kroah-Hartman [this message]
2018-06-12 16:52 ` [PATCH 3.18 10/21] mmap: relax file size limit for regular files Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 11/21] drm: set FMODE_UNSIGNED_OFFSET for drm files Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 12/21] bnx2x: use the right constant Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 13/21] dccp: dont free ccid2_hc_tx_sock struct in dccp_disconnect() Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 14/21] enic: set DMA mask to 47 bit Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 15/21] ip6mr: only set ip6mr_table from setsockopt when ip6mr_new_table succeeds Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 16/21] isdn: eicon: fix a missing-check bug Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 17/21] net/packet: refine check for priv area size Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 19/21] net/mlx4: Fix irq-unsafe spinlock usage Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 20/21] team: use netdev_features_t instead of u32 Greg Kroah-Hartman
2018-06-12 16:52 ` [PATCH 3.18 21/21] rtnetlink: validate attributes in do_setlink() Greg Kroah-Hartman
2018-06-12 18:19 ` [PATCH 3.18 00/21] 3.18.113-stable review Nathan Chancellor
2018-06-12 18:20 ` Harsh Shandilya
2018-06-12 18:49   ` Greg Kroah-Hartman
2018-06-12 21:00 ` Shuah Khan
     [not found] ` <5b20444c.1c69fb81.cb5e6.5a8d@mx.google.com>
2018-06-13  4:40   ` Greg Kroah-Hartman
2018-06-14  0:09     ` Kevin Hilman
2018-06-14 15:51       ` Guenter Roeck
2018-06-20  0:36         ` Kevin Hilman
2018-06-20  2:18           ` Guenter Roeck
2018-06-13 13:48 ` Guenter Roeck
2018-06-13 14:09   ` Greg Kroah-Hartman
2018-06-13 14:58     ` Greg Kroah-Hartman
2018-06-13 17:39       ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180612164825.789715889@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=airlied@redhat.com \
    --cc=dan.carpenter@oracle.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=w@1wt.eu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.