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; |
