diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2012-05-30 13:30:51 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-05-31 13:11:54 -0400 |
| commit | e5467859f7f79b69fc49004403009dfdba3bec53 (patch) | |
| tree | 73b011daf79eeddd61bbcaf65cd197b5e5f6f149 | |
| parent | d007794a182bc072a7b7479909dbd0d67ba341be (diff) | |
split ->file_mmap() into ->mmap_addr()/->mmap_file()
... i.e. file-dependent and address-dependent checks.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/exec.c | 4 | ||||
| -rw-r--r-- | include/linux/security.h | 36 | ||||
| -rw-r--r-- | mm/mmap.c | 12 | ||||
| -rw-r--r-- | mm/mremap.c | 4 | ||||
| -rw-r--r-- | mm/nommu.c | 5 | ||||
| -rw-r--r-- | security/apparmor/lsm.c | 15 | ||||
| -rw-r--r-- | security/capability.c | 3 | ||||
| -rw-r--r-- | security/commoncap.c | 21 | ||||
| -rw-r--r-- | security/security.c | 12 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 15 | ||||
| -rw-r--r-- | security/smack/smack_lsm.c | 15 |
11 files changed, 64 insertions, 78 deletions
| @@ -280,10 +280,6 @@ static int __bprm_mm_init(struct linux_binprm *bprm) | |||
| 280 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | 280 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
| 281 | INIT_LIST_HEAD(&vma->anon_vma_chain); | 281 | INIT_LIST_HEAD(&vma->anon_vma_chain); |
| 282 | 282 | ||
| 283 | err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1); | ||
| 284 | if (err) | ||
| 285 | goto err; | ||
| 286 | |||
| 287 | err = insert_vm_struct(mm, vma); | 283 | err = insert_vm_struct(mm, vma); |
| 288 | if (err) | 284 | if (err) |
| 289 | goto err; | 285 | goto err; |
diff --git a/include/linux/security.h b/include/linux/security.h index 4ad59c9fa731..f1bae0963ddc 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -87,9 +87,8 @@ extern int cap_inode_removexattr(struct dentry *dentry, const char *name); | |||
| 87 | extern int cap_inode_need_killpriv(struct dentry *dentry); | 87 | extern int cap_inode_need_killpriv(struct dentry *dentry); |
| 88 | extern int cap_inode_killpriv(struct dentry *dentry); | 88 | extern int cap_inode_killpriv(struct dentry *dentry); |
| 89 | extern int cap_mmap_addr(unsigned long addr); | 89 | extern int cap_mmap_addr(unsigned long addr); |
| 90 | extern int cap_file_mmap(struct file *file, unsigned long reqprot, | 90 | extern int cap_mmap_file(struct file *file, unsigned long reqprot, |
| 91 | unsigned long prot, unsigned long flags, | 91 | unsigned long prot, unsigned long flags); |
| 92 | unsigned long addr, unsigned long addr_only); | ||
| 93 | extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags); | 92 | extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags); |
| 94 | extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, | 93 | extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, |
| 95 | unsigned long arg4, unsigned long arg5); | 94 | unsigned long arg4, unsigned long arg5); |
| @@ -587,15 +586,17 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
| 587 | * simple integer value. When @arg represents a user space pointer, it | 586 | * simple integer value. When @arg represents a user space pointer, it |
| 588 | * should never be used by the security module. | 587 | * should never be used by the security module. |
| 589 | * Return 0 if permission is granted. | 588 | * Return 0 if permission is granted. |
| 590 | * @file_mmap : | 589 | * @mmap_addr : |
| 590 | * Check permissions for a mmap operation at @addr. | ||
| 591 | * @addr contains virtual address that will be used for the operation. | ||
| 592 | * Return 0 if permission is granted. | ||
| 593 | * @mmap_file : | ||
| 591 | * Check permissions for a mmap operation. The @file may be NULL, e.g. | 594 | * Check permissions for a mmap operation. The @file may be NULL, e.g. |
| 592 | * if mapping anonymous memory. | 595 | * if mapping anonymous memory. |
| 593 | * @file contains the file structure for file to map (may be NULL). | 596 | * @file contains the file structure for file to map (may be NULL). |
| 594 | * @reqprot contains the protection requested by the application. | 597 | * @reqprot contains the protection requested by the application. |
| 595 | * @prot contains the protection that will be applied by the kernel. | 598 | * @prot contains the protection that will be applied by the kernel. |
| 596 | * @flags contains the operational flags. | 599 | * @flags contains the operational flags. |
| 597 | * @addr contains virtual address that will be used for the operation. | ||
| 598 | * @addr_only contains a boolean: 0 if file-backed VMA, otherwise 1. | ||
| 599 | * Return 0 if permission is granted. | 600 | * Return 0 if permission is granted. |
| 600 | * @file_mprotect: | 601 | * @file_mprotect: |
| 601 | * Check permissions before changing memory access permissions. | 602 | * Check permissions before changing memory access permissions. |
| @@ -1482,10 +1483,10 @@ struct security_operations { | |||
| 1482 | void (*file_free_security) (struct file *file); | 1483 | void (*file_free_security) (struct file *file); |
| 1483 | int (*file_ioctl) (struct file *file, unsigned int cmd, | 1484 | int (*file_ioctl) (struct file *file, unsigned int cmd, |
| 1484 | unsigned long arg); | 1485 | unsigned long arg); |
| 1485 | int (*file_mmap) (struct file *file, | 1486 | int (*mmap_addr) (unsigned long addr); |
| 1487 | int (*mmap_file) (struct file *file, | ||
| 1486 | unsigned long reqprot, unsigned long prot, | 1488 | unsigned long reqprot, unsigned long prot, |
| 1487 | unsigned long flags, unsigned long addr, | 1489 | unsigned long flags); |
| 1488 | unsigned long addr_only); | ||
| 1489 | int (*file_mprotect) (struct vm_area_struct *vma, | 1490 | int (*file_mprotect) (struct vm_area_struct *vma, |
| 1490 | unsigned long reqprot, | 1491 | unsigned long reqprot, |
| 1491 | unsigned long prot); | 1492 | unsigned long prot); |
| @@ -1744,9 +1745,9 @@ int security_file_permission(struct file *file, int mask); | |||
| 1744 | int security_file_alloc(struct file *file); | 1745 | int security_file_alloc(struct file *file); |
| 1745 | void security_file_free(struct file *file); | 1746 | void security_file_free(struct file *file); |
| 1746 | int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | 1747 | int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
| 1747 | int security_file_mmap(struct file *file, unsigned long reqprot, | 1748 | int security_mmap_file(struct file *file, unsigned long reqprot, |
| 1748 | unsigned long prot, unsigned long flags, | 1749 | unsigned long prot, unsigned long flags); |
| 1749 | unsigned long addr, unsigned long addr_only); | 1750 | int security_mmap_addr(unsigned long addr); |
| 1750 | int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, | 1751 | int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, |
| 1751 | unsigned long prot); | 1752 | unsigned long prot); |
| 1752 | int security_file_lock(struct file *file, unsigned int cmd); | 1753 | int security_file_lock(struct file *file, unsigned int cmd); |
| @@ -2182,11 +2183,14 @@ static inline int security_file_ioctl(struct file *file, unsigned int cmd, | |||
| 2182 | return 0; | 2183 | return 0; |
| 2183 | } | 2184 | } |
| 2184 | 2185 | ||
| 2185 | static inline int security_file_mmap(struct file *file, unsigned long reqprot, | 2186 | static inline int security_mmap_file(struct file *file, unsigned long reqprot, |
| 2186 | unsigned long prot, | 2187 | unsigned long prot, |
| 2187 | unsigned long flags, | 2188 | unsigned long flags) |
| 2188 | unsigned long addr, | 2189 | { |
| 2189 | unsigned long addr_only) | 2190 | return 0; |
| 2191 | } | ||
| 2192 | |||
| 2193 | static inline int security_mmap_addr(unsigned long addr) | ||
| 2190 | { | 2194 | { |
| 2191 | return cap_mmap_addr(addr); | 2195 | return cap_mmap_addr(addr); |
| 2192 | } | 2196 | } |
| @@ -1101,7 +1101,11 @@ static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | |||
| 1101 | } | 1101 | } |
| 1102 | } | 1102 | } |
| 1103 | 1103 | ||
| 1104 | error = security_file_mmap(file, reqprot, prot, flags, addr, 0); | 1104 | error = security_mmap_addr(addr); |
| 1105 | if (error) | ||
| 1106 | return error; | ||
| 1107 | |||
| 1108 | error = security_mmap_file(file, reqprot, prot, flags); | ||
| 1105 | if (error) | 1109 | if (error) |
| 1106 | return error; | 1110 | return error; |
| 1107 | 1111 | ||
| @@ -1817,7 +1821,7 @@ int expand_downwards(struct vm_area_struct *vma, | |||
| 1817 | return -ENOMEM; | 1821 | return -ENOMEM; |
| 1818 | 1822 | ||
| 1819 | address &= PAGE_MASK; | 1823 | address &= PAGE_MASK; |
| 1820 | error = security_file_mmap(NULL, 0, 0, 0, address, 1); | 1824 | error = security_mmap_addr(address); |
| 1821 | if (error) | 1825 | if (error) |
| 1822 | return error; | 1826 | return error; |
| 1823 | 1827 | ||
| @@ -2205,7 +2209,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) | |||
| 2205 | if (!len) | 2209 | if (!len) |
| 2206 | return addr; | 2210 | return addr; |
| 2207 | 2211 | ||
| 2208 | error = security_file_mmap(NULL, 0, 0, 0, addr, 1); | 2212 | error = security_mmap_addr(addr); |
| 2209 | if (error) | 2213 | if (error) |
| 2210 | return error; | 2214 | return error; |
| 2211 | 2215 | ||
| @@ -2561,7 +2565,7 @@ int install_special_mapping(struct mm_struct *mm, | |||
| 2561 | vma->vm_ops = &special_mapping_vmops; | 2565 | vma->vm_ops = &special_mapping_vmops; |
| 2562 | vma->vm_private_data = pages; | 2566 | vma->vm_private_data = pages; |
| 2563 | 2567 | ||
| 2564 | ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1); | 2568 | ret = security_mmap_addr(vma->vm_start); |
| 2565 | if (ret) | 2569 | if (ret) |
| 2566 | goto out; | 2570 | goto out; |
| 2567 | 2571 | ||
diff --git a/mm/mremap.c b/mm/mremap.c index 169c53b87749..ebf10892b63d 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
| @@ -371,7 +371,7 @@ static unsigned long mremap_to(unsigned long addr, | |||
| 371 | if ((addr <= new_addr) && (addr+old_len) > new_addr) | 371 | if ((addr <= new_addr) && (addr+old_len) > new_addr) |
| 372 | goto out; | 372 | goto out; |
| 373 | 373 | ||
| 374 | ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1); | 374 | ret = security_mmap_addr(new_addr); |
| 375 | if (ret) | 375 | if (ret) |
| 376 | goto out; | 376 | goto out; |
| 377 | 377 | ||
| @@ -532,7 +532,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, | |||
| 532 | goto out; | 532 | goto out; |
| 533 | } | 533 | } |
| 534 | 534 | ||
