Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

Al Viro e5467859 d007794a

+64 -78
-4
fs/exec.c
··· 280 280 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 281 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 283 err = insert_vm_struct(mm, vma); 288 284 if (err) 289 285 goto err;
+20 -16
include/linux/security.h
··· 87 87 extern int cap_inode_need_killpriv(struct dentry *dentry); 88 88 extern int cap_inode_killpriv(struct dentry *dentry); 89 89 extern int cap_mmap_addr(unsigned long addr); 90 - extern int cap_file_mmap(struct file *file, unsigned long reqprot, 91 - unsigned long prot, unsigned long flags, 92 - unsigned long addr, unsigned long addr_only); 90 + extern int cap_mmap_file(struct file *file, unsigned long reqprot, 91 + unsigned long prot, unsigned long flags); 93 92 extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags); 94 93 extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, 95 94 unsigned long arg4, unsigned long arg5); ··· 586 587 * simple integer value. When @arg represents a user space pointer, it 587 588 * should never be used by the security module. 588 589 * Return 0 if permission is granted. 589 - * @file_mmap : 590 + * @mmap_addr : 591 + * Check permissions for a mmap operation at @addr. 592 + * @addr contains virtual address that will be used for the operation. 593 + * Return 0 if permission is granted. 594 + * @mmap_file : 590 595 * Check permissions for a mmap operation. The @file may be NULL, e.g. 591 596 * if mapping anonymous memory. 592 597 * @file contains the file structure for file to map (may be NULL). 593 598 * @reqprot contains the protection requested by the application. 594 599 * @prot contains the protection that will be applied by the kernel. 595 600 * @flags contains the operational flags. 596 - * @addr contains virtual address that will be used for the operation. 597 - * @addr_only contains a boolean: 0 if file-backed VMA, otherwise 1. 598 601 * Return 0 if permission is granted. 599 602 * @file_mprotect: 600 603 * Check permissions before changing memory access permissions. ··· 1483 1482 void (*file_free_security) (struct file *file); 1484 1483 int (*file_ioctl) (struct file *file, unsigned int cmd, 1485 1484 unsigned long arg); 1486 - int (*file_mmap) (struct file *file, 1485 + int (*mmap_addr) (unsigned long addr); 1486 + int (*mmap_file) (struct file *file, 1487 1487 unsigned long reqprot, unsigned long prot, 1488 - unsigned long flags, unsigned long addr, 1489 - unsigned long addr_only); 1488 + unsigned long flags); 1490 1489 int (*file_mprotect) (struct vm_area_struct *vma, 1491 1490 unsigned long reqprot, 1492 1491 unsigned long prot); ··· 1745 1744 int security_file_alloc(struct file *file); 1746 1745 void security_file_free(struct file *file); 1747 1746 int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg); 1748 - int security_file_mmap(struct file *file, unsigned long reqprot, 1749 - unsigned long prot, unsigned long flags, 1750 - unsigned long addr, unsigned long addr_only); 1747 + int security_mmap_file(struct file *file, unsigned long reqprot, 1748 + unsigned long prot, unsigned long flags); 1749 + int security_mmap_addr(unsigned long addr); 1751 1750 int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, 1752 1751 unsigned long prot); 1753 1752 int security_file_lock(struct file *file, unsigned int cmd); ··· 2183 2182 return 0; 2184 2183 } 2185 2184 2186 - static inline int security_file_mmap(struct file *file, unsigned long reqprot, 2185 + static inline int security_mmap_file(struct file *file, unsigned long reqprot, 2187 2186 unsigned long prot, 2188 - unsigned long flags, 2189 - unsigned long addr, 2190 - unsigned long addr_only) 2187 + unsigned long flags) 2188 + { 2189 + return 0; 2190 + } 2191 + 2192 + static inline int security_mmap_addr(unsigned long addr) 2191 2193 { 2192 2194 return cap_mmap_addr(addr); 2193 2195 }
+8 -4
mm/mmap.c
··· 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 1109 if (error) 1106 1110 return error; 1107 1111 ··· 1821 1817 return -ENOMEM; 1822 1818 1823 1819 address &= PAGE_MASK; 1824 - error = security_file_mmap(NULL, 0, 0, 0, address, 1); 1820 + error = security_mmap_addr(address); 1825 1821 if (error) 1826 1822 return error; 1827 1823 ··· 2209 2205 if (!len) 2210 2206 return addr; 2211 2207 2212 - error = security_file_mmap(NULL, 0, 0, 0, addr, 1); 2208 + error = security_mmap_addr(addr); 2213 2209 if (error) 2214 2210 return error; 2215 2211 ··· 2565 2561 vma->vm_ops = &special_mapping_vmops; 2566 2562 vma->vm_private_data = pages; 2567 2563 2568 - ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1); 2564 + ret = security_mmap_addr(vma->vm_start); 2569 2565 if (ret) 2570 2566 goto out; 2571 2567
+2 -2
mm/mremap.c
··· 371 371 if ((addr <= new_addr) && (addr+old_len) > new_addr) 372 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 375 if (ret) 376 376 goto out; 377 377 ··· 532 532 goto out; 533 533 } 534 534 535 - ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1); 535 + ret = security_mmap_addr(new_addr); 536 536 if (ret) 537 537 goto out; 538 538 ret = move_vma(vma, addr, old_len, new_len, new_addr);
+4 -1
mm/nommu.c
··· 1047 1047 } 1048 1048 1049 1049 /* allow the security API to have its say */ 1050 - ret = security_file_mmap(file, reqprot, prot, flags, addr, 0); 1050 + ret = security_mmap_addr(addr); 1051 + if (ret < 0) 1052 + return ret; 1053 + ret = security_mmap_file(file, reqprot, prot, flags); 1051 1054 if (ret < 0) 1052 1055 return ret; 1053 1056
+4 -11
security/apparmor/lsm.c
··· 490 490 return common_file_perm(op, file, mask); 491 491 } 492 492 493 - static int apparmor_file_mmap(struct file *file, unsigned long reqprot, 494 - unsigned long prot, unsigned long flags, 495 - unsigned long addr, unsigned long addr_only) 493 + static int apparmor_mmap_file(struct file *file, unsigned long reqprot, 494 + unsigned long prot, unsigned long flags) 496 495 { 497 - int rc = 0; 498 - 499 - /* do DAC check */ 500 - rc = cap_mmap_addr(addr); 501 - if (rc || addr_only) 502 - return rc; 503 - 504 496 return common_mmap(OP_FMMAP, file, prot, flags); 505 497 } 506 498 ··· 638 646 .file_permission = apparmor_file_permission, 639 647 .file_alloc_security = apparmor_file_alloc_security, 640 648 .file_free_security = apparmor_file_free_security, 641 - .file_mmap = apparmor_file_mmap, 649 + .mmap_file = apparmor_mmap_file, 650 + .mmap_addr = cap_mmap_addr, 642 651 .file_mprotect = apparmor_file_mprotect, 643 652 .file_lock = apparmor_file_lock, 644 653
+2 -1
security/capability.c
··· 949 949 set_to_cap_if_null(ops, file_alloc_security); 950 950 set_to_cap_if_null(ops, file_free_security); 951 951 set_to_cap_if_null(ops, file_ioctl); 952 - set_to_cap_if_null(ops, file_mmap); 952 + set_to_cap_if_null(ops, mmap_addr); 953 + set_to_cap_if_null(ops, mmap_file); 953 954 set_to_cap_if_null(ops, file_mprotect); 954 955 set_to_cap_if_null(ops, file_lock); 955 956 set_to_cap_if_null(ops, file_fcntl);
+3 -18
security/commoncap.c
··· 980 980 return ret; 981 981 } 982 982 983 - /* 984 - * cap_file_mmap - check if able to map given addr 985 - * @file: unused 986 - * @reqprot: unused 987 - * @prot: unused 988 - * @flags: unused 989 - * @addr: address attempting to be mapped 990 - * @addr_only: unused 991 - * 992 - * If the process is attempting to map memory below dac_mmap_min_addr they need 993 - * CAP_SYS_RAWIO. The other parameters to this function are unused by the 994 - * capability security module. Returns 0 if this mapping should be allowed 995 - * -EPERM if not. 996 - */ 997 - int cap_file_mmap(struct file *file, unsigned long reqprot, 998 - unsigned long prot, unsigned long flags, 999 - unsigned long addr, unsigned long addr_only) 983 + int cap_mmap_file(struct file *file, unsigned long reqprot, 984 + unsigned long prot, unsigned long flags) 1000 985 { 1001 - return cap_mmap_addr(addr); 986 + return 0; 1002 987 }
+8 -4
security/security.c
··· 657 657 return security_ops->file_ioctl(file, cmd, arg); 658 658 } 659 659 660 - int security_file_mmap(struct file *file, unsigned long reqprot, 661 - unsigned long prot, unsigned long flags, 662 - unsigned long addr, unsigned long addr_only) 660 + int security_mmap_file(struct file *file, unsigned long reqprot, 661 + unsigned long prot, unsigned long flags) 663 662 { 664 663 int ret; 665 664 666 - ret = security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only); 665 + ret = security_ops->mmap_file(file, reqprot, prot, flags); 667 666 if (ret) 668 667 return ret; 669 668 return ima_file_mmap(file, prot); 669 + } 670 + 671 + int security_mmap_addr(unsigned long addr) 672 + { 673 + return security_ops->mmap_addr(addr); 670 674 } 671 675 672 676 int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
+8 -7
security/selinux/hooks.c
··· 3083 3083 return rc; 3084 3084 } 3085 3085 3086 - static int selinux_file_mmap(struct file *file, unsigned long reqprot, 3087 - unsigned long prot, unsigned long flags, 3088 - unsigned long addr, unsigned long addr_only) 3086 + static int selinux_mmap_addr(unsigned long addr) 3089 3087 { 3090 3088 int rc = 0; 3091 3089 u32 sid = current_sid(); ··· 3102 3104 } 3103 3105 3104 3106 /* do DAC check on address space usage */ 3105 - rc = cap_mmap_addr(addr); 3106 - if (rc || addr_only) 3107 - return rc; 3107 + return cap_mmap_addr(addr); 3108 + } 3108 3109 3110 + static int selinux_mmap_file(struct file *file, unsigned long reqprot, 3111 + unsigned long prot, unsigned long flags) 3112 + { 3109 3113 if (selinux_checkreqprot) 3110 3114 prot = reqprot; 3111 3115 ··· 5570 5570 .file_alloc_security = selinux_file_alloc_security, 5571 5571 .file_free_security = selinux_file_free_security, 5572 5572 .file_ioctl = selinux_file_ioctl, 5573 - .file_mmap = selinux_file_mmap, 5573 + .mmap_file = selinux_mmap_file, 5574 + .mmap_addr = selinux_mmap_addr, 5574 5575 .file_mprotect = selinux_file_mprotect, 5575 5576 .file_lock = selinux_file_lock, 5576 5577 .file_fcntl = selinux_file_fcntl,
+5 -10
security/smack/smack_lsm.c
··· 1171 1171 } 1172 1172 1173 1173 /** 1174 - * smack_file_mmap : 1174 + * smack_mmap_file : 1175 1175 * Check permissions for a mmap operation. The @file may be NULL, e.g. 1176 1176 * if mapping anonymous memory. 1177 1177 * @file contains the file structure for file to map (may be NULL). ··· 1180 1180 * @flags contains the operational flags. 1181 1181 * Return 0 if permission is granted. 1182 1182 */ 1183 - static int smack_file_mmap(struct file *file, 1183 + static int smack_mmap_file(struct file *file, 1184 1184 unsigned long reqprot, unsigned long prot, 1185 - unsigned long flags, unsigned long addr, 1186 - unsigned long addr_only) 1185 + unsigned long flags) 1187 1186 { 1188 1187 struct smack_known *skp; 1189 1188 struct smack_rule *srp; ··· 1196 1197 int mmay; 1197 1198 int tmay; 1198 1199 int rc; 1199 - 1200 - /* do DAC check on address space usage */ 1201 - rc = cap_mmap_addr(addr); 1202 - if (rc || addr_only) 1203 - return rc; 1204 1200 1205 1201 if (file == NULL || file->f_dentry == NULL) 1206 1202 return 0; ··· 3476 3482 .file_ioctl = smack_file_ioctl, 3477 3483 .file_lock = smack_file_lock, 3478 3484 .file_fcntl = smack_file_fcntl, 3479 - .file_mmap = smack_file_mmap, 3485 + .mmap_file = smack_mmap_file, 3486 + .mmap_addr = cap_mmap_addr, 3480 3487 .file_set_fowner = smack_file_set_fowner, 3481 3488 .file_send_sigiotask = smack_file_send_sigiotask, 3482 3489 .file_receive = smack_file_receive,