aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/security.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/security/security.c b/security/security.c
index 3b11b3b72fe2..3efc9b12aef4 100644
--- a/security/security.c
+++ b/security/security.c
@@ -660,36 +660,46 @@ int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
660 return security_ops->file_ioctl(file, cmd, arg); 660 return security_ops->file_ioctl(file, cmd, arg);
661} 661}
662 662
663int security_mmap_file(struct file *file, unsigned long prot, 663static inline unsigned long mmap_prot(struct file *file, unsigned long prot)
664 unsigned long flags)
665{ 664{
666 unsigned long reqprot = prot;
667 int ret;
668 /* 665 /*
669 * Does the application expect PROT_READ to imply PROT_EXEC? 666 * Does we have PROT_READ and does the application expect
670 * 667 * it to imply PROT_EXEC? If not, nothing to talk about...
671 * (the exception is when the underlying filesystem is noexec
672 * mounted, in which case we dont add PROT_EXEC.)
673 */ 668 */
674 if (!(reqprot & PROT_READ)) 669 if ((prot & (PROT_READ | PROT_EXEC)) != PROT_READ)
675 goto out; 670 return prot;
676 if (!(current->personality & READ_IMPLIES_EXEC)) 671 if (!(current->personality & READ_IMPLIES_EXEC))
677 goto out; 672 return prot;
678 if (!file) { 673 /*
679 prot |= PROT_EXEC; 674 * if that's an anonymous mapping, let it.
680 } else if (!(file->f_path.mnt->mnt_flags & MNT_NOEXEC)) { 675 */
676 if (!file)
677 return prot | PROT_EXEC;
678 /*
679 * ditto if it's not on noexec mount, except that on !MMU we need
680 * BDI_CAP_EXEC_MMAP (== VM_MAYEXEC) in this case
681 */
682 if (!(file->f_path.mnt->mnt_flags & MNT_NOEXEC)) {
681#ifndef CONFIG_MMU 683#ifndef CONFIG_MMU
682 unsigned long caps = 0; 684 unsigned long caps = 0;
683 struct address_space *mapping = file->f_mapping; 685 struct address_space *mapping = file->f_mapping;
684 if (mapping && mapping->backing_dev_info) 686 if (mapping && mapping->backing_dev_info)
685 caps = mapping->backing_dev_info->capabilities; 687 caps = mapping->backing_dev_info->capabilities;
686 if (!(caps & BDI_CAP_EXEC_MAP)) 688 if (!(caps & BDI_CAP_EXEC_MAP))
687 goto out; 689 return prot;
688#endif 690#endif
689 prot |= PROT_EXEC; 691 return prot | PROT_EXEC;
690 } 692 }
691out: 693 /* anything on noexec mount won't get PROT_EXEC */
692 ret = security_ops->mmap_file(file, reqprot, prot, flags); 694 return prot;
695}
696
697int security_mmap_file(struct file *file, unsigned long prot,
698 unsigned long flags)
699{
700 int ret;
701 ret = security_ops->mmap_file(file, prot,
702 mmap_prot(file, prot), flags);
693 if (ret) 703 if (ret)
694 return ret; 704 return ret;
695 return ima_file_mmap(file, prot); 705 return ima_file_mmap(file, prot);