Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 788084ab authored by Eric Paris's avatar Eric Paris Committed by James Morris
Browse files

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.

Signed-off-by: default avatarEric Paris <eparis@redhat.com>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 8cf948e7
Loading
Loading
Loading
Loading
+0 −15
Original line number Diff line number Diff line
@@ -34,8 +34,6 @@ extern int sysctl_legacy_va_layout;
#define sysctl_legacy_va_layout 0
#endif

extern unsigned long mmap_min_addr;

#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
@@ -574,19 +572,6 @@ static inline void set_page_links(struct page *page, enum zone_type zone,
	set_page_section(page, pfn_to_section_nr(pfn));
}

/*
 * If a hint addr is less than mmap_min_addr change hint to be as
 * low as possible but still greater than mmap_min_addr
 */
static inline unsigned long round_hint_to_min(unsigned long hint)
{
	hint &= PAGE_MASK;
	if (((void *)hint != NULL) &&
	    (hint < mmap_min_addr))
		return PAGE_ALIGN(mmap_min_addr);
	return hint;
}

/*
 * Some inline functions in vmstat.h depend on page_zone()
 */
+17 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/resource.h>
#include <linux/sem.h>
#include <linux/shm.h>
#include <linux/mm.h> /* PAGE_ALIGN */
#include <linux/msg.h>
#include <linux/sched.h>
#include <linux/key.h>
@@ -95,6 +96,7 @@ extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
extern int cap_netlink_recv(struct sk_buff *skb, int cap);

extern unsigned long mmap_min_addr;
extern unsigned long dac_mmap_min_addr;
/*
 * Values used in the task_security_ops calls
 */
@@ -147,6 +149,21 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
	opts->num_mnt_opts = 0;
}

/*
 * If a hint addr is less than mmap_min_addr change hint to be as
 * low as possible but still greater than mmap_min_addr
 */
static inline unsigned long round_hint_to_min(unsigned long hint)
{
	hint &= PAGE_MASK;
	if (((void *)hint != NULL) &&
	    (hint < mmap_min_addr))
		return PAGE_ALIGN(mmap_min_addr);
	return hint;
}

extern int mmap_min_addr_handler(struct ctl_table *table, int write, struct file *filp,
				 void __user *buffer, size_t *lenp, loff_t *ppos);
/**
 * struct security_operations - main security structure
 *
+4 −3
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@
#include <linux/acpi.h>
#include <linux/reboot.h>
#include <linux/ftrace.h>
#include <linux/security.h>
#include <linux/slow-work.h>
#include <linux/perf_counter.h>

@@ -1306,10 +1307,10 @@ static struct ctl_table vm_table[] = {
	{
		.ctl_name	= CTL_UNNUMBERED,
		.procname	= "mmap_min_addr",
		.data		= &mmap_min_addr,
		.data		= &dac_mmap_min_addr,
		.maxlen		= sizeof(unsigned long),
		.mode		= 0644,
		.proc_handler	= &proc_doulongvec_minmax,
		.proc_handler	= &mmap_min_addr_handler,
	},
#ifdef CONFIG_NUMA
	{
+3 −3
Original line number Diff line number Diff line
@@ -225,9 +225,9 @@ config DEFAULT_MMAP_MIN_ADDR
	  For most ia64, ppc64 and x86 users with lots of address space
	  a value of 65536 is reasonable and should cause no problems.
	  On arm and other archs it should not be higher than 32768.
	  Programs which use vm86 functionality would either need additional
	  permissions from either the LSM or the capabilities module or have
	  this protection disabled.
	  Programs which use vm86 functionality or have some need to map
	  this low address space will need CAP_SYS_RAWIO or disable this
	  protection by setting the value to 0.

	  This value can be changed after boot using the
	  /proc/sys/vm/mmap_min_addr tunable.
+0 −3
Original line number Diff line number Diff line
@@ -88,9 +88,6 @@ int sysctl_overcommit_ratio = 50; /* default is 50% */
int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
struct percpu_counter vm_committed_as;

/* amount of vm to protect from userspace access */
unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;

/*
 * Check that a process has enough memory to allocate a new virtual
 * mapping. 0 means there is enough memory for the allocation to
Loading