• Linus Torvalds's avatar
    mmap: introduce sane default mmap limits · be83bbf8
    Linus Torvalds authored
    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: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    be83bbf8
mmap.c 99.2 KB