diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-07-04 16:13:55 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-07-04 16:13:55 -0400 |
commit | 404c3bc30cb1361e1b3533643326ab472d24a618 (patch) | |
tree | 156cc9032c8aee17167d926c5bdae009ba8f36d2 /security/security.c | |
parent | 6795a524f0b049ceb5417d5036ab5e233345b900 (diff) | |
parent | 6887a4131da3adaab011613776d865f4bcfb5678 (diff) |
Merge commit 'v3.5-rc5' into next
Diffstat (limited to 'security/security.c')
-rw-r--r-- | security/security.c | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/security/security.c b/security/security.c index bf619ffc9a4d..3efc9b12aef4 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -20,6 +20,9 @@ | |||
20 | #include <linux/ima.h> | 20 | #include <linux/ima.h> |
21 | #include <linux/evm.h> | 21 | #include <linux/evm.h> |
22 | #include <linux/fsnotify.h> | 22 | #include <linux/fsnotify.h> |
23 | #include <linux/mman.h> | ||
24 | #include <linux/mount.h> | ||
25 | #include <linux/personality.h> | ||
23 | #include <net/flow.h> | 26 | #include <net/flow.h> |
24 | 27 | ||
25 | #define MAX_LSM_EVM_XATTR 2 | 28 | #define MAX_LSM_EVM_XATTR 2 |
@@ -657,18 +660,56 @@ int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
657 | return security_ops->file_ioctl(file, cmd, arg); | 660 | return security_ops->file_ioctl(file, cmd, arg); |
658 | } | 661 | } |
659 | 662 | ||
660 | int security_file_mmap(struct file *file, unsigned long reqprot, | 663 | static inline unsigned long mmap_prot(struct file *file, unsigned long prot) |
661 | unsigned long prot, unsigned long flags, | ||
662 | unsigned long addr, unsigned long addr_only) | ||
663 | { | 664 | { |
664 | int ret; | 665 | /* |
666 | * Does we have PROT_READ and does the application expect | ||
667 | * it to imply PROT_EXEC? If not, nothing to talk about... | ||
668 | */ | ||
669 | if ((prot & (PROT_READ | PROT_EXEC)) != PROT_READ) | ||
670 | return prot; | ||
671 | if (!(current->personality & READ_IMPLIES_EXEC)) | ||
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)) { | ||
683 | #ifndef CONFIG_MMU | ||
684 | unsigned long caps = 0; | ||
685 | struct address_space *mapping = file->f_mapping; | ||
686 | if (mapping && mapping->backing_dev_info) | ||
687 | caps = mapping->backing_dev_info->capabilities; | ||
688 | if (!(caps & BDI_CAP_EXEC_MAP)) | ||
689 | return prot; | ||
690 | #endif | ||
691 | return prot | PROT_EXEC; | ||
692 | } | ||
693 | /* anything on noexec mount won't get PROT_EXEC */ | ||
694 | return prot; | ||
695 | } | ||
665 | 696 | ||
666 | ret = security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only); | 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); | ||
667 | if (ret) | 703 | if (ret) |
668 | return ret; | 704 | return ret; |
669 | return ima_file_mmap(file, prot); | 705 | return ima_file_mmap(file, prot); |
670 | } | 706 | } |
671 | 707 | ||
708 | int security_mmap_addr(unsigned long addr) | ||
709 | { | ||
710 | return security_ops->mmap_addr(addr); | ||
711 | } | ||
712 | |||
672 | int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, | 713 | int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, |
673 | unsigned long prot) | 714 | unsigned long prot) |
674 | { | 715 | { |
@@ -701,11 +742,11 @@ int security_file_receive(struct file *file) | |||
701 | return security_ops->file_receive(file); | 742 | return security_ops->file_receive(file); |
702 | } | 743 | } |
703 | 744 | ||
704 | int security_dentry_open(struct file *file, const struct cred *cred) | 745 | int security_file_open(struct file *file, const struct cred *cred) |
705 | { | 746 | { |
706 | int ret; | 747 | int ret; |
707 | 748 | ||
708 | ret = security_ops->dentry_open(file, cred); | 749 | ret = security_ops->file_open(file, cred); |
709 | if (ret) | 750 | if (ret) |
710 | return ret; | 751 | return ret; |
711 | 752 | ||