diff options
| -rw-r--r-- | Documentation/sysctl/vm.txt | 15 | ||||
| -rw-r--r-- | include/linux/security.h | 17 | ||||
| -rw-r--r-- | kernel/sysctl.c | 10 | ||||
| -rw-r--r-- | mm/mmap.c | 4 | ||||
| -rw-r--r-- | mm/mremap.c | 13 | ||||
| -rw-r--r-- | mm/nommu.c | 2 | ||||
| -rw-r--r-- | security/dummy.c | 6 | ||||
| -rw-r--r-- | security/security.c | 1 | ||||
| -rw-r--r-- | security/selinux/avc.c | 12 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 42 | ||||
| -rw-r--r-- | security/selinux/include/av_perm_to_string.h | 1 | ||||
| -rw-r--r-- | security/selinux/include/av_permissions.h | 1 | ||||
| -rw-r--r-- | security/selinux/include/avc.h | 6 | ||||
| -rw-r--r-- | security/selinux/include/class_to_string.h | 1 | ||||
| -rw-r--r-- | security/selinux/include/flask.h | 1 | ||||
| -rw-r--r-- | security/selinux/include/security.h | 4 | ||||
| -rw-r--r-- | security/selinux/netlabel.c | 34 | ||||
| -rw-r--r-- | security/selinux/selinuxfs.c | 269 | ||||
| -rw-r--r-- | security/selinux/ss/policydb.c | 7 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 144 |
20 files changed, 504 insertions, 86 deletions
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 1d192565e182..8cfca173d4bc 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt | |||
| @@ -31,6 +31,7 @@ Currently, these files are in /proc/sys/vm: | |||
| 31 | - min_unmapped_ratio | 31 | - min_unmapped_ratio |
| 32 | - min_slab_ratio | 32 | - min_slab_ratio |
| 33 | - panic_on_oom | 33 | - panic_on_oom |
| 34 | - mmap_min_address | ||
| 34 | 35 | ||
| 35 | ============================================================== | 36 | ============================================================== |
| 36 | 37 | ||
| @@ -216,3 +217,17 @@ above-mentioned. | |||
| 216 | The default value is 0. | 217 | The default value is 0. |
| 217 | 1 and 2 are for failover of clustering. Please select either | 218 | 1 and 2 are for failover of clustering. Please select either |
| 218 | according to your policy of failover. | 219 | according to your policy of failover. |
| 220 | |||
| 221 | ============================================================== | ||
| 222 | |||
| 223 | mmap_min_addr | ||
| 224 | |||
| 225 | This file indicates the amount of address space which a user process will | ||
| 226 | be restricted from mmaping. Since kernel null dereference bugs could | ||
| 227 | accidentally operate based on the information in the first couple of pages | ||
| 228 | of memory userspace processes should not be allowed to write to them. By | ||
| 229 | default this value is set to 0 and no protections will be enforced by the | ||
| 230 | security module. Setting this value to something like 64k will allow the | ||
| 231 | vast majority of applications to work correctly and provide defense in depth | ||
| 232 | against future potential kernel bugs. | ||
| 233 | |||
diff --git a/include/linux/security.h b/include/linux/security.h index 9eb9e0fe0331..c11dc8aa0351 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -71,6 +71,7 @@ struct xfrm_user_sec_ctx; | |||
| 71 | extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); | 71 | extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); |
| 72 | extern int cap_netlink_recv(struct sk_buff *skb, int cap); | 72 | extern int cap_netlink_recv(struct sk_buff *skb, int cap); |
| 73 | 73 | ||
| 74 | extern unsigned long mmap_min_addr; | ||
| 74 | /* | 75 | /* |
| 75 | * Values used in the task_security_ops calls | 76 | * Values used in the task_security_ops calls |
| 76 | */ | 77 | */ |
| @@ -1241,8 +1242,9 @@ struct security_operations { | |||
| 1241 | int (*file_ioctl) (struct file * file, unsigned int cmd, | 1242 | int (*file_ioctl) (struct file * file, unsigned int cmd, |
| 1242 | unsigned long arg); | 1243 | unsigned long arg); |
| 1243 | int (*file_mmap) (struct file * file, | 1244 | int (*file_mmap) (struct file * file, |
| 1244 | unsigned long reqprot, | 1245 | unsigned long reqprot, unsigned long prot, |
| 1245 | unsigned long prot, unsigned long flags); | 1246 | unsigned long flags, unsigned long addr, |
| 1247 | unsigned long addr_only); | ||
| 1246 | int (*file_mprotect) (struct vm_area_struct * vma, | 1248 | int (*file_mprotect) (struct vm_area_struct * vma, |
| 1247 | unsigned long reqprot, | 1249 | unsigned long reqprot, |
| 1248 | unsigned long prot); | 1250 | unsigned long prot); |
| @@ -1814,9 +1816,12 @@ static inline int security_file_ioctl (struct file *file, unsigned int cmd, | |||
| 1814 | 1816 | ||
| 1815 | static inline int security_file_mmap (struct file *file, unsigned long reqprot, | 1817 | static inline int security_file_mmap (struct file *file, unsigned long reqprot, |
| 1816 | unsigned long prot, | 1818 | unsigned long prot, |
| 1817 | unsigned long flags) | 1819 | unsigned long flags, |
| 1820 | unsigned long addr, | ||
| 1821 | unsigned long addr_only) | ||
| 1818 | { | 1822 | { |
| 1819 | return security_ops->file_mmap (file, reqprot, prot, flags); | 1823 | return security_ops->file_mmap (file, reqprot, prot, flags, addr, |
| 1824 | addr_only); | ||
| 1820 | } | 1825 | } |
| 1821 | 1826 | ||
| 1822 | static inline int security_file_mprotect (struct vm_area_struct *vma, | 1827 | static inline int security_file_mprotect (struct vm_area_struct *vma, |
| @@ -2489,7 +2494,9 @@ static inline int security_file_ioctl (struct file *file, unsigned int cmd, | |||
| 2489 | 2494 | ||
| 2490 | static inline int security_file_mmap (struct file *file, unsigned long reqprot, | 2495 | static inline int security_file_mmap (struct file *file, unsigned long reqprot, |
| 2491 | unsigned long prot, | 2496 | unsigned long prot, |
| 2492 | unsigned long flags) | 2497 | unsigned long flags, |
| 2498 | unsigned long addr, | ||
| 2499 | unsigned long addr_only) | ||
| 2493 | { | 2500 | { |
| 2494 | return 0; | 2501 | return 0; |
| 2495 | } | 2502 | } |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 51f5dac42a00..d93e13d93f24 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
| @@ -949,6 +949,16 @@ static ctl_table vm_table[] = { | |||
| 949 | .strategy = &sysctl_jiffies, | 949 | .strategy = &sysctl_jiffies, |
| 950 | }, | 950 | }, |
| 951 | #endif | 951 | #endif |
| 952 | #ifdef CONFIG_SECURITY | ||
| 953 | { | ||
| 954 | .ctl_name = CTL_UNNUMBERED, | ||
| 955 | .procname = "mmap_min_addr", | ||
| 956 | .data = &mmap_min_addr, | ||
| 957 | .maxlen = sizeof(unsigned long), | ||
| 958 | .mode = 0644, | ||
| 959 | .proc_handler = &proc_doulongvec_minmax, | ||
| 960 | }, | ||
| 961 | #endif | ||
| 952 | #if defined(CONFIG_X86_32) || \ | 962 | #if defined(CONFIG_X86_32) || \ |
| 953 | (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL)) | 963 | (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL)) |
| 954 | { | 964 | { |
| @@ -1023,10 +1023,10 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, | |||
| 1023 | } | 1023 | } |
| 1024 | } | 1024 | } |
| 1025 | 1025 | ||
| 1026 | error = security_file_mmap(file, reqprot, prot, flags); | 1026 | error = security_file_mmap(file, reqprot, prot, flags, addr, 0); |
| 1027 | if (error) | 1027 | if (error) |
| 1028 | return error; | 1028 | return error; |
| 1029 | 1029 | ||
| 1030 | /* Clear old maps */ | 1030 | /* Clear old maps */ |
| 1031 | error = -ENOMEM; | 1031 | error = -ENOMEM; |
| 1032 | munmap_back: | 1032 | munmap_back: |
diff --git a/mm/mremap.c b/mm/mremap.c index 5d4bd4f95b8e..bc7c52efc71b 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
| @@ -291,6 +291,10 @@ unsigned long do_mremap(unsigned long addr, | |||
| 291 | if ((addr <= new_addr) && (addr+old_len) > new_addr) | 291 | if ((addr <= new_addr) && (addr+old_len) > new_addr) |
| 292 | goto out; | 292 | goto out; |
| 293 | 293 | ||
| 294 | ret = security_file_mmap(0, 0, 0, 0, new_addr, 1); | ||
| 295 | if (ret) | ||
| 296 | goto out; | ||
| 297 | |||
| 294 | ret = do_munmap(mm, new_addr, new_len); | 298 | ret = do_munmap(mm, new_addr, new_len); |
| 295 | if (ret) | 299 | if (ret) |
| 296 | goto out; | 300 | goto out; |
| @@ -390,8 +394,13 @@ unsigned long do_mremap(unsigned long addr, | |||
| 390 | 394 | ||
| 391 | new_addr = get_unmapped_area(vma->vm_file, 0, new_len, | 395 | new_addr = get_unmapped_area(vma->vm_file, 0, new_len, |
| 392 | vma->vm_pgoff, map_flags); | 396 | vma->vm_pgoff, map_flags); |
| 393 | ret = new_addr; | 397 | if (new_addr & ~PAGE_MASK) { |
| 394 | if (new_addr & ~PAGE_MASK) | 398 | ret = new_addr; |
| 399 | goto out; | ||
| 400 | } | ||
| 401 | |||
| 402 | ret = security_file_mmap(0, 0, 0, 0, new_addr, 1); | ||
| 403 | if (ret) | ||
| 395 | goto out; | 404 | goto out; |
| 396 | } | 405 | } |
| 397 | ret = move_vma(vma, addr, old_len, new_len, new_addr); | 406 | ret = move_vma(vma, addr, old_len, new_len, new_addr); |
diff --git a/mm/nommu.c b/mm/nommu.c index 2b16b00a5b11..989e2e9af5c3 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
| @@ -639,7 +639,7 @@ static int validate_mmap_request(struct file *file, | |||
| 639 | } | 639 | } |
| 640 | 640 | ||
| 641 | /* allow the security API to have its say */ | 641 | /* allow the security API to have its say */ |
| 642 | ret = security_file_mmap(file, reqprot, prot, flags); | 642 | ret = security_file_mmap(file, reqprot, prot, flags, addr, 0); |
| 643 | if (ret < 0) | 643 | if (ret < 0) |
| 644 | return ret; | 644 | return ret; |
| 645 | |||
