Commit 98de59bfe4b2ff6344d9ad8e5296f80de5dcc5b6
1 parent
9ac4ed4bd0
Exists in
master
and in
20 other branches
take calculation of final prot in security_mmap_file() into a helper
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 1 changed file with 28 additions and 18 deletions Side-by-side Diff
security/security.c
... | ... | @@ -660,36 +660,46 @@ |
660 | 660 | return security_ops->file_ioctl(file, cmd, arg); |
661 | 661 | } |
662 | 662 | |
663 | -int security_mmap_file(struct file *file, unsigned long prot, | |
664 | - unsigned long flags) | |
663 | +static inline unsigned long mmap_prot(struct file *file, unsigned long prot) | |
665 | 664 | { |
666 | - unsigned long reqprot = prot; | |
667 | - int ret; | |
668 | 665 | /* |
669 | - * Does the application expect PROT_READ to imply PROT_EXEC? | |
670 | - * | |
671 | - * (the exception is when the underlying filesystem is noexec | |
672 | - * mounted, in which case we dont add PROT_EXEC.) | |
666 | + * Does we have PROT_READ and does the application expect | |
667 | + * it to imply PROT_EXEC? If not, nothing to talk about... | |
673 | 668 | */ |
674 | - if (!(reqprot & PROT_READ)) | |
675 | - goto out; | |
669 | + if ((prot & (PROT_READ | PROT_EXEC)) != PROT_READ) | |
670 | + return prot; | |
676 | 671 | if (!(current->personality & READ_IMPLIES_EXEC)) |
677 | - goto out; | |
678 | - if (!file) { | |
679 | - prot |= PROT_EXEC; | |
680 | - } else if (!(file->f_path.mnt->mnt_flags & MNT_NOEXEC)) { | |
672 | + return prot; | |
673 | + /* | |
674 | + * if that's an anonymous mapping, let it. | |
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 | 683 | #ifndef CONFIG_MMU |
682 | 684 | unsigned long caps = 0; |
683 | 685 | struct address_space *mapping = file->f_mapping; |
684 | 686 | if (mapping && mapping->backing_dev_info) |
685 | 687 | caps = mapping->backing_dev_info->capabilities; |
686 | 688 | if (!(caps & BDI_CAP_EXEC_MAP)) |
687 | - goto out; | |
689 | + return prot; | |
688 | 690 | #endif |
689 | - prot |= PROT_EXEC; | |
691 | + return prot | PROT_EXEC; | |
690 | 692 | } |
691 | -out: | |
692 | - ret = security_ops->mmap_file(file, reqprot, prot, flags); | |
693 | + /* anything on noexec mount won't get PROT_EXEC */ | |
694 | + return prot; | |
695 | +} | |
696 | + | |
697 | +int 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 | 703 | if (ret) |
694 | 704 | return ret; |
695 | 705 | return ima_file_mmap(file, prot); |