]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - mm/mmap.c
mm/tlb, x86/mm: Support invalidating TLB caches for RCU_TABLE_FREE
[mirror_ubuntu-bionic-kernel.git] / mm / mmap.c
index d04803205bdb0297d9f21b501582c4a8b9f73da7..9641ef6fb7d1b4ee4ee2fc92c168298710927bc5 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1324,6 +1324,35 @@ static inline int mlock_future_check(struct mm_struct *mm,
        return 0;
 }
 
+static inline u64 file_mmap_size_max(struct file *file, struct inode *inode)
+{
+       if (S_ISREG(inode->i_mode))
+               return MAX_LFS_FILESIZE;
+
+       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).
  */
@@ -1398,6 +1427,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
                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) {