···17451745int security_file_alloc(struct file *file);17461746void security_file_free(struct file *file);17471747int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);17481748-int security_mmap_file(struct file *file, unsigned long reqprot,17491749- unsigned long prot, unsigned long flags);17481748+int security_mmap_file(struct file *file, unsigned long prot,17491749+ unsigned long flags);17501750int security_mmap_addr(unsigned long addr);17511751int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,17521752 unsigned long prot);···21832183 return 0;21842184}2185218521862186-static inline int security_mmap_file(struct file *file, unsigned long reqprot,21872187- unsigned long prot,21862186+static inline int security_mmap_file(struct file *file, unsigned long prot,21882187 unsigned long flags)21892188{21902189 return 0;
···979979 struct inode *inode;980980 vm_flags_t vm_flags;981981 int error;982982- unsigned long reqprot = prot;983982984983 /*985984 * Does the application expect PROT_READ to imply PROT_EXEC?···11041105 if (error)11051106 return error;1106110711071107- error = security_mmap_file(file, reqprot, prot, flags);11081108- if (error)11091109- return error;11101110-11111108 return mmap_region(file, addr, len, flags, vm_flags, pgoff);11121109}11131110···11251130 unsigned long ret;11261131 struct mm_struct *mm = current->mm;1127113211281128- down_write(&mm->mmap_sem);11291129- ret = do_mmap(file, addr, len, prot, flag, offset);11301130- up_write(&mm->mmap_sem);11331133+ ret = security_mmap_file(file, prot, flag);11341134+ if (!ret) {11351135+ down_write(&mm->mmap_sem);11361136+ ret = do_mmap(file, addr, len, prot, flag, offset);11371137+ up_write(&mm->mmap_sem);11381138+ }11311139 return ret;11321140}11331141EXPORT_SYMBOL(vm_mmap);···1166116811671169 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);1168117011691169- down_write(¤t->mm->mmap_sem);11701170- retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);11711171- up_write(¤t->mm->mmap_sem);11711171+ retval = security_mmap_file(file, prot, flags);11721172+ if (!retval) {11731173+ down_write(¤t->mm->mmap_sem);11741174+ retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);11751175+ up_write(¤t->mm->mmap_sem);11761176+ }1172117711731178 if (file)11741179 fput(file);
+12-10
mm/nommu.c
···889889 unsigned long *_capabilities)890890{891891 unsigned long capabilities, rlen;892892- unsigned long reqprot = prot;893892 int ret;894893895894 /* do the simple checks first */···1047104810481049 /* allow the security API to have its say */10491050 ret = security_mmap_addr(addr);10501050- if (ret < 0)10511051- return ret;10521052- ret = security_mmap_file(file, reqprot, prot, flags);10531051 if (ret < 0)10541052 return ret;10551053···14881492 unsigned long ret;14891493 struct mm_struct *mm = current->mm;1490149414911491- down_write(&mm->mmap_sem);14921492- ret = do_mmap(file, addr, len, prot, flag, offset);14931493- up_write(&mm->mmap_sem);14951495+ ret = security_mmap_file(file, prot, flag);14961496+ if (!ret) {14971497+ down_write(&mm->mmap_sem);14981498+ ret = do_mmap(file, addr, len, prot, flag, offset);14991499+ up_write(&mm->mmap_sem);15001500+ }14941501 return ret;14951502}14961503EXPORT_SYMBOL(vm_mmap);···1514151515151516 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);1516151715171517- down_write(¤t->mm->mmap_sem);15181518- retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);15191519- up_write(¤t->mm->mmap_sem);15181518+ ret = security_mmap_file(file, prot, flags);15191519+ if (!ret) {15201520+ down_write(¤t->mm->mmap_sem);15211521+ retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);15221522+ up_write(¤t->mm->mmap_sem);15231523+ }1520152415211525 if (file)15221526 fput(file);
+30-3
security/security.c
···2020#include <linux/ima.h>2121#include <linux/evm.h>2222#include <linux/fsnotify.h>2323+#include <linux/mman.h>2424+#include <linux/mount.h>2525+#include <linux/personality.h>2326#include <net/flow.h>24272528#define MAX_LSM_EVM_XATTR 2···660657 return security_ops->file_ioctl(file, cmd, arg);661658}662659663663-int security_mmap_file(struct file *file, unsigned long reqprot,664664- unsigned long prot, unsigned long flags)660660+int security_mmap_file(struct file *file, unsigned long prot,661661+ unsigned long flags)665662{663663+ unsigned long reqprot = prot;666664 int ret;667667-665665+ /*666666+ * Does the application expect PROT_READ to imply PROT_EXEC?667667+ *668668+ * (the exception is when the underlying filesystem is noexec669669+ * mounted, in which case we dont add PROT_EXEC.)670670+ */671671+ if (!(reqprot & PROT_READ))672672+ goto out;673673+ if (!(current->personality & READ_IMPLIES_EXEC))674674+ goto out;675675+ if (!file) {676676+ prot |= PROT_EXEC;677677+ } else if (!(file->f_path.mnt->mnt_flags & MNT_NOEXEC)) {678678+#ifndef CONFIG_MMU679679+ unsigned long caps = 0;680680+ struct address_space *mapping = file->f_mapping;681681+ if (mapping && mapping->backing_dev_info)682682+ caps = mapping->backing_dev_info->capabilities;683683+ if (!(caps & BDI_CAP_EXEC_MAP))684684+ goto out;685685+#endif686686+ prot |= PROT_EXEC;687687+ }688688+out:668689 ret = security_ops->mmap_file(file, reqprot, prot, flags);669690 if (ret)670691 return ret;