int security_file_alloc(struct file *file);
 void security_file_free(struct file *file);
 int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-int security_mmap_file(struct file *file, unsigned long reqprot,
-                       unsigned long prot, unsigned long flags);
+int security_mmap_file(struct file *file, unsigned long prot,
+                       unsigned long flags);
 int security_mmap_addr(unsigned long addr);
 int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
                           unsigned long prot);
        return 0;
 }
 
-static inline int security_mmap_file(struct file *file, unsigned long reqprot,
-                                    unsigned long prot,
+static inline int security_mmap_file(struct file *file, unsigned long prot,
                                     unsigned long flags)
 {
        return 0;
 
        sfd->file = shp->shm_file;
        sfd->vm_ops = NULL;
 
+       err = security_mmap_file(file, prot, flags);
+       if (err)
+               goto out_fput;
+
        down_write(¤t->mm->mmap_sem);
        if (addr && !(shmflg & SHM_REMAP)) {
                err = -EINVAL;
 invalid:
        up_write(¤t->mm->mmap_sem);
 
+out_fput:
        fput(file);
 
 out_nattch:
 
        struct inode *inode;
        vm_flags_t vm_flags;
        int error;
-       unsigned long reqprot = prot;
 
        /*
         * Does the application expect PROT_READ to imply PROT_EXEC?
        if (error)
                return error;
 
-       error = security_mmap_file(file, reqprot, prot, flags);
-       if (error)
-               return error;
-
        return mmap_region(file, addr, len, flags, vm_flags, pgoff);
 }
 
        unsigned long ret;
        struct mm_struct *mm = current->mm;
 
-       down_write(&mm->mmap_sem);
-       ret = do_mmap(file, addr, len, prot, flag, offset);
-       up_write(&mm->mmap_sem);
+       ret = security_mmap_file(file, prot, flag);
+       if (!ret) {
+               down_write(&mm->mmap_sem);
+               ret = do_mmap(file, addr, len, prot, flag, offset);
+               up_write(&mm->mmap_sem);
+       }
        return ret;
 }
 EXPORT_SYMBOL(vm_mmap);
 
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
-       down_write(¤t->mm->mmap_sem);
-       retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-       up_write(¤t->mm->mmap_sem);
+       retval = security_mmap_file(file, prot, flags);
+       if (!retval) {
+               down_write(¤t->mm->mmap_sem);
+               retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+               up_write(¤t->mm->mmap_sem);
+       }
 
        if (file)
                fput(file);
 
                                 unsigned long *_capabilities)
 {
        unsigned long capabilities, rlen;
-       unsigned long reqprot = prot;
        int ret;
 
        /* do the simple checks first */
 
        /* allow the security API to have its say */
        ret = security_mmap_addr(addr);
-       if (ret < 0)
-               return ret;
-       ret = security_mmap_file(file, reqprot, prot, flags);
        if (ret < 0)
                return ret;
 
        unsigned long ret;
        struct mm_struct *mm = current->mm;
 
-       down_write(&mm->mmap_sem);
-       ret = do_mmap(file, addr, len, prot, flag, offset);
-       up_write(&mm->mmap_sem);
+       ret = security_mmap_file(file, prot, flag);
+       if (!ret) {
+               down_write(&mm->mmap_sem);
+               ret = do_mmap(file, addr, len, prot, flag, offset);
+               up_write(&mm->mmap_sem);
+       }
        return ret;
 }
 EXPORT_SYMBOL(vm_mmap);
 
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
-       down_write(¤t->mm->mmap_sem);
-       retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-       up_write(¤t->mm->mmap_sem);
+       ret = security_mmap_file(file, prot, flags);
+       if (!ret) {
+               down_write(¤t->mm->mmap_sem);
+               retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+               up_write(¤t->mm->mmap_sem);
+       }
 
        if (file)
                fput(file);
 
 #include <linux/ima.h>
 #include <linux/evm.h>
 #include <linux/fsnotify.h>
+#include <linux/mman.h>
+#include <linux/mount.h>
+#include <linux/personality.h>
 #include <net/flow.h>
 
 #define MAX_LSM_EVM_XATTR      2
        return security_ops->file_ioctl(file, cmd, arg);
 }
 
-int security_mmap_file(struct file *file, unsigned long reqprot,
-                       unsigned long prot, unsigned long flags)
+int security_mmap_file(struct file *file, unsigned long prot,
+                       unsigned long flags)
 {
+       unsigned long reqprot = prot;
        int ret;
-
+       /*
+        * Does the application expect PROT_READ to imply PROT_EXEC?
+        *
+        * (the exception is when the underlying filesystem is noexec
+        *  mounted, in which case we dont add PROT_EXEC.)
+        */
+       if (!(reqprot & PROT_READ))
+               goto out;
+       if (!(current->personality & READ_IMPLIES_EXEC))
+               goto out;
+       if (!file) {
+               prot |= PROT_EXEC;
+       } else if (!(file->f_path.mnt->mnt_flags & MNT_NOEXEC)) {
+#ifndef CONFIG_MMU
+               unsigned long caps = 0;
+               struct address_space *mapping = file->f_mapping;
+               if (mapping && mapping->backing_dev_info)
+                       caps = mapping->backing_dev_info->capabilities;
+               if (!(caps & BDI_CAP_EXEC_MAP))
+                       goto out;
+#endif
+               prot |= PROT_EXEC;
+       }
+out:
        ret = security_ops->mmap_file(file, reqprot, prot, flags);
        if (ret)
                return ret;