diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-05-30 17:11:23 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-06-01 10:37:01 -0400 |
commit | 8b3ec6814c83d76b85bd13badc48552836c24839 (patch) | |
tree | 2430a4511c7ea41f67b0d841f4c42eac43828db3 /security | |
parent | e5467859f7f79b69fc49004403009dfdba3bec53 (diff) |
take security_mmap_file() outside of ->mmap_sem
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'security')
-rw-r--r-- | security/security.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/security/security.c b/security/security.c index d91c66d3956b..3b11b3b72fe2 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,11 +660,35 @@ 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_mmap_file(struct file *file, unsigned long reqprot, | 663 | int security_mmap_file(struct file *file, unsigned long prot, |
661 | unsigned long prot, unsigned long flags) | 664 | unsigned long flags) |
662 | { | 665 | { |
666 | unsigned long reqprot = prot; | ||
663 | int ret; | 667 | int ret; |
664 | 668 | /* | |
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.) | ||
673 | */ | ||
674 | if (!(reqprot & PROT_READ)) | ||
675 | goto out; | ||
676 | 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)) { | ||
681 | #ifndef CONFIG_MMU | ||
682 | unsigned long caps = 0; | ||
683 | struct address_space *mapping = file->f_mapping; | ||
684 | if (mapping && mapping->backing_dev_info) | ||
685 | caps = mapping->backing_dev_info->capabilities; | ||
686 | if (!(caps & BDI_CAP_EXEC_MAP)) | ||
687 | goto out; | ||
688 | #endif | ||
689 | prot |= PROT_EXEC; | ||
690 | } | ||
691 | out: | ||
665 | ret = security_ops->mmap_file(file, reqprot, prot, flags); | 692 | ret = security_ops->mmap_file(file, reqprot, prot, flags); |
666 | if (ret) | 693 | if (ret) |
667 | return ret; | 694 | return ret; |