History

Security/SELinux: seperate lsm specific mmap_min_addr

Currently SELinux enforcement of controls on the ability to map low memory is determined by the mmap_min_addr tunable. This patch causes SELinux to ignore the tunable and instead use a seperate Kconfig option specific to how much space the LSM should protect. The tunable will now only control the need for CAP_SYS_RAWIO and SELinux permissions will always protect the amount of low memory designated by CONFIG_LSM_MMAP_MIN_ADDR. This allows users who need to disable the mmap_min_addr controls (usual reason being they run WINE as a non-root user) to do so and still have SELinux controls preventing confined domains (like a web server) from being able to map some area of low memory.

Eric Paris committed 17 years ago

Commit 788084a1 parent 8cf948e11 files · +92 −30Browse files

Unified · Split

11 files
  1. include/linux/mm.h +0 −15
  2. include/linux/security.h +17 −0
  3. kernel/sysctl.c +4 −3
  4. mm/Kconfig +3 −3
  5. mm/mmap.c +0 −3
  6. mm/nommu.c +0 −3
  7. security/Kconfig +16 −0
  8. security/Makefile +1 −1
  9. security/commoncap.c +1 −1
  10. security/min_addr.c +49 −0
  11. security/selinux/hooks.c +1 −1
include/linux/mm.h+0−15
@@ -34,8 +34,6 @@ extern int sysctl_legacy_va_layout; · 33 unmodified lines
34#define sysctl_legacy_va_layout 034#define sysctl_legacy_va_layout 0
35#endif35#endif
36 36
37extern unsigned long mmap_min_addr;
38
39#include <asm/page.h>37#include <asm/page.h>
40#include <asm/pgtable.h>38#include <asm/pgtable.h>
41#include <asm/processor.h>39#include <asm/processor.h>
@@ -574,19 +572,6 @@ static inline void set_page_links(struct page *page, enum zone_type zone, · 532 unmodified lines
574 set_page_section(page, pfn_to_section_nr(pfn));572 set_page_section(page, pfn_to_section_nr(pfn));
575}573}
576 574
577/*
578 * If a hint addr is less than mmap_min_addr change hint to be as
579 * low as possible but still greater than mmap_min_addr
580 */
581static inline unsigned long round_hint_to_min(unsigned long hint)
582{
583 hint &= PAGE_MASK;
584 if (((void *)hint != NULL) &&
585 (hint < mmap_min_addr))
586 return PAGE_ALIGN(mmap_min_addr);
587 return hint;
588}
589
590/*575/*
591 * Some inline functions in vmstat.h depend on page_zone()576 * Some inline functions in vmstat.h depend on page_zone()
592 */577 */
include/linux/security.h+17−0
@@ -28,6 +28,7 @@ · 27 unmodified lines
28#include <linux/resource.h>28#include <linux/resource.h>
29#include <linux/sem.h>29#include <linux/sem.h>
30#include <linux/shm.h>30#include <linux/shm.h>
31#include <linux/mm.h> /* PAGE_ALIGN */
31#include <linux/msg.h>32#include <linux/msg.h>
32#include <linux/sched.h>33#include <linux/sched.h>
33#include <linux/key.h>34#include <linux/key.h>
@@ -95,6 +96,7 @@ extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); · 61 unmodified lines
95extern int cap_netlink_recv(struct sk_buff *skb, int cap);96extern int cap_netlink_recv(struct sk_buff *skb, int cap);
96 97
97extern unsigned long mmap_min_addr;98extern unsigned long mmap_min_addr;
99extern unsigned long dac_mmap_min_addr;
98/*100/*
99 * Values used in the task_security_ops calls101 * Values used in the task_security_ops calls
100 */102 */
@@ -147,6 +149,21 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) · 46 unmodified lines
147 opts->num_mnt_opts = 0;149 opts->num_mnt_opts = 0;
148}150}
149 151
152/*
153 * If a hint addr is less than mmap_min_addr change hint to be as
154 * low as possible but still greater than mmap_min_addr
155 */
156static inline unsigned long round_hint_to_min(unsigned long hint)
157{
158 hint &= PAGE_MASK;
159 if (((void *)hint != NULL) &&
160 (hint < mmap_min_addr))
161 return PAGE_ALIGN(mmap_min_addr);
162 return hint;
163}
164
165extern int mmap_min_addr_handler(struct ctl_table *table, int write, struct file *filp,
166 void __user *buffer, size_t *lenp, loff_t *ppos);
150/**167/**
151 * struct security_operations - main security structure168 * struct security_operations - main security structure
152 *169 *
kernel/sysctl.c+4−3
@@ -49,6 +49,7 @@ · 48 unmodified lines
49#include <linux/acpi.h>49#include <linux/acpi.h>
50#include <linux/reboot.h>50#include <linux/reboot.h>
51#include <linux/ftrace.h>51#include <linux/ftrace.h>
52#include <linux/security.h>
52#include <linux/slow-work.h>53#include <linux/slow-work.h>
53#include <linux/perf_counter.h>54#include <linux/perf_counter.h>
54 55
@@ -1306,10 +1307,10 @@ static struct ctl_table vm_table[] = { · 1251 unmodified lines
1306 {1307 {
1307 .ctl_name = CTL_UNNUMBERED,1308 .ctl_name = CTL_UNNUMBERED,
1308 .procname = "mmap_min_addr",1309 .procname = "mmap_min_addr",
1309 .data = &mmap_min_addr,1310 .data = &dac_mmap_min_addr,
1310 .maxlen = sizeof(unsigned long),1311 .maxlen = sizeof(unsigned long),
1311 .mode = 0644,1312 .mode = 0644,
1312 .proc_handler = &proc_doulongvec_minmax,1313 .proc_handler = &mmap_min_addr_handler,
1313 },1314 },
1314#ifdef CONFIG_NUMA1315#ifdef CONFIG_NUMA
1315 {1316 {
mm/Kconfig+3−3
@@ -225,9 +225,9 @@ config DEFAULT_MMAP_MIN_ADDR · 224 unmodified lines
225 For most ia64, ppc64 and x86 users with lots of address space225 For most ia64, ppc64 and x86 users with lots of address space
226 a value of 65536 is reasonable and should cause no problems.226 a value of 65536 is reasonable and should cause no problems.
227 On arm and other archs it should not be higher than 32768.227 On arm and other archs it should not be higher than 32768.
228 Programs which use vm86 functionality would either need additional228 Programs which use vm86 functionality or have some need to map
229 permissions from either the LSM or the capabilities module or have229 this low address space will need CAP_SYS_RAWIO or disable this
230 this protection disabled.230 protection by setting the value to 0.
231 231
232 This value can be changed after boot using the232 This value can be changed after boot using the
233 /proc/sys/vm/mmap_min_addr tunable.233 /proc/sys/vm/mmap_min_addr tunable.
mm/mmap.c+0−3
@@ -88,9 +88,6 @@ int sysctl_overcommit_ratio = 50; /* default is 50% */ · 87 unmodified lines
88int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;88int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
89struct percpu_counter vm_committed_as;89struct percpu_counter vm_committed_as;
90 90
91/* amount of vm to protect from userspace access */
92unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
93
94/*91/*
95 * Check that a process has enough memory to allocate a new virtual92 * Check that a process has enough memory to allocate a new virtual
96 * mapping. 0 means there is enough memory for the allocation to93 * mapping. 0 means there is enough memory for the allocation to
mm/nommu.c+0−3
@@ -69,9 +69,6 @@ int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT; · 68 unmodified lines
69int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;69int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;
70int heap_stack_gap = 0;70int heap_stack_gap = 0;
71 71
72/* amount of vm to protect from userspace access */
73unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
74
75atomic_long_t mmap_pages_allocated;72atomic_long_t mmap_pages_allocated;
76 73
77EXPORT_SYMBOL(mem_map);74EXPORT_SYMBOL(mem_map);
security/Kconfig+16−0
@@ -113,6 +113,22 @@ config SECURITY_ROOTPLUG · 112 unmodified lines
113 113
114 If you are unsure how to answer this question, answer N.114 If you are unsure how to answer this question, answer N.
115 115
116config 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
116source security/selinux/Kconfig132source security/selinux/Kconfig
117source security/smack/Kconfig133source security/smack/Kconfig
118source security/tomoyo/Kconfig134source security/tomoyo/Kconfig
security/Makefile+1−1
@@ -8,7 +8,7 @@ subdir-$(CONFIG_SECURITY_SMACK) += smack · 7 unmodified lines
8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo
9 9
10# always enable default capabilities10# always enable default capabilities
11obj-y += commoncap.o11obj-y += commoncap.o min_addr.o
12 12
13# Object file lists13# Object file lists
14obj-$(CONFIG_SECURITY) += security.o capability.o14obj-$(CONFIG_SECURITY) += security.o capability.o
security/commoncap.c+1−1
@@ -1005,7 +1005,7 @@ int cap_file_mmap(struct file *file, unsigned long reqprot, · 1004 unmodified lines
1005{1005{
1006 int ret = 0;1006 int ret = 0;
1007 1007
1008 if (addr < mmap_min_addr) {1008 if (addr < dac_mmap_min_addr) {
1009 ret = cap_capable(current, current_cred(), CAP_SYS_RAWIO,1009 ret = cap_capable(current, current_cred(), CAP_SYS_RAWIO,
1010 SECURITY_CAP_AUDIT);1010 SECURITY_CAP_AUDIT);
1011 /* set PF_SUPERPRIV if it turns out we allow the low mmap */1011 /* set PF_SUPERPRIV if it turns out we allow the low mmap */
security/min_addr.c+49−0
@@ -0,0 +1,49 @@
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*/
7unsigned long mmap_min_addr;
8/* amount of vm to protect from userspace using CAP_SYS_RAWIO (DAC) */
9unsigned 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 */
15static 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 */
31int 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
43int __init init_mmap_min_addr(void)
44{
45 update_mmap_min_addr();
46
47 return 0;
48}
49pure_initcall(init_mmap_min_addr);
security/selinux/hooks.c+1−1
@@ -3036,7 +3036,7 @@ static int selinux_file_mmap(struct file *file, unsigned long reqprot, · 3035 unmodified lines
3036 * at bad behaviour/exploit that we always want to get the AVC, even3036 * at bad behaviour/exploit that we always want to get the AVC, even
3037 * if DAC would have also denied the operation.3037 * if DAC would have also denied the operation.
3038 */3038 */
3039 if (addr < mmap_min_addr) {3039 if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
3040 rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,3040 rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
3041 MEMPROTECT__MMAP_ZERO, NULL);3041 MEMPROTECT__MMAP_ZERO, NULL);
3042 if (rc)3042 if (rc)