Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6:
security: define round_hint_to_min in !CONFIG_SECURITY
Security/SELinux: seperate lsm specific mmap_min_addr
SELinux: call cap_file_mmap in selinux_file_mmap
Capabilities: move cap_file_mmap to commoncap.c

+137 -41
-15
include/linux/mm.h
··· 34 34 #define sysctl_legacy_va_layout 0 35 35 #endif 36 36 37 - extern unsigned long mmap_min_addr; 38 - 39 37 #include <asm/page.h> 40 38 #include <asm/pgtable.h> 41 39 #include <asm/processor.h> ··· 570 572 set_page_zone(page, zone); 571 573 set_page_node(page, node); 572 574 set_page_section(page, pfn_to_section_nr(pfn)); 573 - } 574 - 575 - /* 576 - * If a hint addr is less than mmap_min_addr change hint to be as 577 - * low as possible but still greater than mmap_min_addr 578 - */ 579 - static inline unsigned long round_hint_to_min(unsigned long hint) 580 - { 581 - hint &= PAGE_MASK; 582 - if (((void *)hint != NULL) && 583 - (hint < mmap_min_addr)) 584 - return PAGE_ALIGN(mmap_min_addr); 585 - return hint; 586 575 } 587 576 588 577 /*
+21 -3
include/linux/security.h
··· 28 28 #include <linux/resource.h> 29 29 #include <linux/sem.h> 30 30 #include <linux/shm.h> 31 + #include <linux/mm.h> /* PAGE_ALIGN */ 31 32 #include <linux/msg.h> 32 33 #include <linux/sched.h> 33 34 #include <linux/key.h> ··· 67 66 extern int cap_inode_removexattr(struct dentry *dentry, const char *name); 68 67 extern int cap_inode_need_killpriv(struct dentry *dentry); 69 68 extern int cap_inode_killpriv(struct dentry *dentry); 69 + extern int cap_file_mmap(struct file *file, unsigned long reqprot, 70 + unsigned long prot, unsigned long flags, 71 + unsigned long addr, unsigned long addr_only); 70 72 extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags); 71 73 extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, 72 74 unsigned long arg4, unsigned long arg5); ··· 96 92 extern int cap_netlink_recv(struct sk_buff *skb, int cap); 97 93 98 94 extern unsigned long mmap_min_addr; 95 + extern unsigned long dac_mmap_min_addr; 99 96 /* 100 97 * Values used in the task_security_ops calls 101 98 */ ··· 120 115 #define LSM_UNSAFE_SHARE 1 121 116 #define LSM_UNSAFE_PTRACE 2 122 117 #define LSM_UNSAFE_PTRACE_CAP 4 118 + 119 + /* 120 + * If a hint addr is less than mmap_min_addr change hint to be as 121 + * low as possible but still greater than mmap_min_addr 122 + */ 123 + static inline unsigned long round_hint_to_min(unsigned long hint) 124 + { 125 + hint &= PAGE_MASK; 126 + if (((void *)hint != NULL) && 127 + (hint < mmap_min_addr)) 128 + return PAGE_ALIGN(mmap_min_addr); 129 + return hint; 130 + } 131 + extern int mmap_min_addr_handler(struct ctl_table *table, int write, struct file *filp, 132 + void __user *buffer, size_t *lenp, loff_t *ppos); 123 133 124 134 #ifdef CONFIG_SECURITY 125 135 ··· 2217 2197 unsigned long addr, 2218 2198 unsigned long addr_only) 2219 2199 { 2220 - if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) 2221 - return -EACCES; 2222 - return 0; 2200 + return cap_file_mmap(file, reqprot, prot, flags, addr, addr_only); 2223 2201 } 2224 2202 2225 2203 static inline int security_file_mprotect(struct vm_area_struct *vma,
+4 -3
kernel/sysctl.c
··· 49 49 #include <linux/acpi.h> 50 50 #include <linux/reboot.h> 51 51 #include <linux/ftrace.h> 52 + #include <linux/security.h> 52 53 #include <linux/slow-work.h> 53 54 #include <linux/perf_counter.h> 54 55 ··· 1307 1306 { 1308 1307 .ctl_name = CTL_UNNUMBERED, 1309 1308 .procname = "mmap_min_addr", 1310 - .data = &mmap_min_addr, 1311 - .maxlen = sizeof(unsigned long), 1309 + .data = &dac_mmap_min_addr, 1310 + .maxlen = sizeof(unsigned long), 1312 1311 .mode = 0644, 1313 - .proc_handler = &proc_doulongvec_minmax, 1312 + .proc_handler = &mmap_min_addr_handler, 1314 1313 }, 1315 1314 #ifdef CONFIG_NUMA 1316 1315 {
+3 -3
mm/Kconfig
··· 225 225 For most ia64, ppc64 and x86 users with lots of address space 226 226 a value of 65536 is reasonable and should cause no problems. 227 227 On arm and other archs it should not be higher than 32768. 228 - Programs which use vm86 functionality would either need additional 229 - permissions from either the LSM or the capabilities module or have 230 - this protection disabled. 228 + Programs which use vm86 functionality or have some need to map 229 + this low address space will need CAP_SYS_RAWIO or disable this 230 + protection by setting the value to 0. 231 231 232 232 This value can be changed after boot using the 233 233 /proc/sys/vm/mmap_min_addr tunable.
-3
mm/mmap.c
··· 88 88 int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT; 89 89 struct percpu_counter vm_committed_as; 90 90 91 - /* amount of vm to protect from userspace access */ 92 - unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; 93 - 94 91 /* 95 92 * Check that a process has enough memory to allocate a new virtual 96 93 * mapping. 0 means there is enough memory for the allocation to
-3
mm/nommu.c
··· 69 69 int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS; 70 70 int heap_stack_gap = 0; 71 71 72 - /* amount of vm to protect from userspace access */ 73 - unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; 74 - 75 72 atomic_long_t mmap_pages_allocated; 76 73 77 74 EXPORT_SYMBOL(mem_map);
+16
security/Kconfig
··· 113 113 114 114 If you are unsure how to answer this question, answer N. 115 115 116 + config LSM_MMAP_MIN_ADDR 117 + int "Low address space for LSM to from user allocation" 118 + depends on SECURITY && SECURITY_SELINUX 119 + default 65535 120 + help 121 + This is the portion of low virtual memory which should be protected 122 + from userspace allocation. Keeping a user from writing to low pages 123 + can help reduce the impact of kernel NULL pointer bugs. 124 + 125 + For most ia64, ppc64 and x86 users with lots of address space 126 + a value of 65536 is reasonable and should cause no problems. 127 + On arm and other archs it should not be higher than 32768. 128 + Programs which use vm86 functionality or have some need to map 129 + this low address space will need the permission specific to the 130 + systems running LSM. 131 + 116 132 source security/selinux/Kconfig 117 133 source security/smack/Kconfig 118 134 source security/tomoyo/Kconfig
+1 -1
security/Makefile
··· 8 8 subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo 9 9 10 10 # always enable default capabilities 11 - obj-y += commoncap.o 11 + obj-y += commoncap.o min_addr.o 12 12 13 13 # Object file lists 14 14 obj-$(CONFIG_SECURITY) += security.o capability.o
-9
security/capability.c
··· 330 330 return 0; 331 331 } 332 332 333 - static int cap_file_mmap(struct file *file, unsigned long reqprot, 334 - unsigned long prot, unsigned long flags, 335 - unsigned long addr, unsigned long addr_only) 336 - { 337 - if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) 338 - return -EACCES; 339 - return 0; 340 - } 341 - 342 333 static int cap_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, 343 334 unsigned long prot) 344 335 {
+30
security/commoncap.c
··· 984 984 cap_sys_admin = 1; 985 985 return __vm_enough_memory(mm, pages, cap_sys_admin); 986 986 } 987 + 988 + /* 989 + * cap_file_mmap - check if able to map given addr 990 + * @file: unused 991 + * @reqprot: unused 992 + * @prot: unused 993 + * @flags: unused 994 + * @addr: address attempting to be mapped 995 + * @addr_only: unused 996 + * 997 + * If the process is attempting to map memory below mmap_min_addr they need 998 + * CAP_SYS_RAWIO. The other parameters to this function are unused by the 999 + * capability security module. Returns 0 if this mapping should be allowed 1000 + * -EPERM if not. 1001 + */ 1002 + int cap_file_mmap(struct file *file, unsigned long reqprot, 1003 + unsigned long prot, unsigned long flags, 1004 + unsigned long addr, unsigned long addr_only) 1005 + { 1006 + int ret = 0; 1007 + 1008 + if (addr < dac_mmap_min_addr) { 1009 + ret = cap_capable(current, current_cred(), CAP_SYS_RAWIO, 1010 + SECURITY_CAP_AUDIT); 1011 + /* set PF_SUPERPRIV if it turns out we allow the low mmap */ 1012 + if (ret == 0) 1013 + current->flags |= PF_SUPERPRIV; 1014 + } 1015 + return ret; 1016 + }
+49
security/min_addr.c
··· 1 + #include <linux/init.h> 2 + #include <linux/mm.h> 3 + #include <linux/security.h> 4 + #include <linux/sysctl.h> 5 + 6 + /* amount of vm to protect from userspace access by both DAC and the LSM*/ 7 + unsigned long mmap_min_addr; 8 + /* amount of vm to protect from userspace using CAP_SYS_RAWIO (DAC) */ 9 + unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; 10 + /* amount of vm to protect from userspace using the LSM = CONFIG_LSM_MMAP_MIN_ADDR */ 11 + 12 + /* 13 + * Update mmap_min_addr = max(dac_mmap_min_addr, CONFIG_LSM_MMAP_MIN_ADDR) 14 + */ 15 + static void update_mmap_min_addr(void) 16 + { 17 + #ifdef CONFIG_LSM_MMAP_MIN_ADDR 18 + if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR) 19 + mmap_min_addr = dac_mmap_min_addr; 20 + else 21 + mmap_min_addr = CONFIG_LSM_MMAP_MIN_ADDR; 22 + #else 23 + mmap_min_addr = dac_mmap_min_addr; 24 + #endif 25 + } 26 + 27 + /* 28 + * sysctl handler which just sets dac_mmap_min_addr = the new value and then 29 + * calls update_mmap_min_addr() so non MAP_FIXED hints get rounded properly 30 + */ 31 + int mmap_min_addr_handler(struct ctl_table *table, int write, struct file *filp, 32 + void __user *buffer, size_t *lenp, loff_t *ppos) 33 + { 34 + int ret; 35 + 36 + ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos); 37 + 38 + update_mmap_min_addr(); 39 + 40 + return ret; 41 + } 42 + 43 + int __init init_mmap_min_addr(void) 44 + { 45 + update_mmap_min_addr(); 46 + 47 + return 0; 48 + } 49 + pure_initcall(init_mmap_min_addr);
+13 -1
security/selinux/hooks.c
··· 3030 3030 int rc = 0; 3031 3031 u32 sid = current_sid(); 3032 3032 3033 - if (addr < mmap_min_addr) 3033 + /* 3034 + * notice that we are intentionally putting the SELinux check before 3035 + * the secondary cap_file_mmap check. This is such a likely attempt 3036 + * at bad behaviour/exploit that we always want to get the AVC, even 3037 + * if DAC would have also denied the operation. 3038 + */ 3039 + if (addr < CONFIG_LSM_MMAP_MIN_ADDR) { 3034 3040 rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, 3035 3041 MEMPROTECT__MMAP_ZERO, NULL); 3042 + if (rc) 3043 + return rc; 3044 + } 3045 + 3046 + /* do DAC check on address space usage */ 3047 + rc = cap_file_mmap(file, reqprot, prot, flags, addr, addr_only); 3036 3048 if (rc || addr_only) 3037 3049 return rc; 3038 3050