[kernel] r14349 - in dists/lenny-security/linux-2.6/debian: . config patches/bugfix/all patches/series
Dann Frazier
dannf at alioth.debian.org
Thu Oct 8 04:50:29 UTC 2009
Author: dannf
Date: Thu Oct 8 04:50:27 2009
New Revision: 14349
Log:
selinux: prevent local users from bypassing mmap_min_addr
in unconfined domains (CVE-2009-2695)
Added:
dists/lenny-security/linux-2.6/debian/patches/bugfix/all/capabilities-move-cap_file_mmap-to-commoncap.c.patch
dists/lenny-security/linux-2.6/debian/patches/bugfix/all/security-define-round_hint_to_min-when-CONFIG_SECURITY-is-off.patch
dists/lenny-security/linux-2.6/debian/patches/bugfix/all/security-seperate-lsm-specific-mmap_min_addr.patch
dists/lenny-security/linux-2.6/debian/patches/bugfix/all/security-use-mmap_min_addr-independently-of-security-models.patch
dists/lenny-security/linux-2.6/debian/patches/bugfix/all/selinux-call-cap_file_mmap-in-selinux_file_mmap.patch
Modified:
dists/lenny-security/linux-2.6/debian/changelog
dists/lenny-security/linux-2.6/debian/config/config
dists/lenny-security/linux-2.6/debian/patches/series/19lenny1
Modified: dists/lenny-security/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny-security/linux-2.6/debian/changelog Thu Oct 8 01:59:54 2009 (r14348)
+++ dists/lenny-security/linux-2.6/debian/changelog Thu Oct 8 04:50:27 2009 (r14349)
@@ -4,6 +4,8 @@
(CVE-2009-2903)
* KVM: x86: Disallow hypercalls for guest callers in rings > 0
(CVE-2009-3290)
+ * selinux: prevent local users from bypassing mmap_min_addr
+ in unconfined domains (CVE-2009-2695)
-- dann frazier <dannf at debian.org> Tue, 15 Sep 2009 22:54:06 -0600
Modified: dists/lenny-security/linux-2.6/debian/config/config
==============================================================================
--- dists/lenny-security/linux-2.6/debian/config/config Thu Oct 8 01:59:54 2009 (r14348)
+++ dists/lenny-security/linux-2.6/debian/config/config Thu Oct 8 04:50:27 2009 (r14349)
@@ -2034,6 +2034,11 @@
# CONFIG_KGDB is not set
##
+## file: mm/Kconfig
+##
+CONFIG_DEFAULT_MMAP_MIN_ADDR=0
+
+##
## file: net/Kconfig
##
CONFIG_NET=y
@@ -2516,7 +2521,6 @@
CONFIG_SECURITY_CAPABILITIES=y
CONFIG_SECURITY_FILE_CAPABILITIES=y
# CONFIG_SECURITY_ROOTPLUG is not set
-CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
##
## file: security/selinux/Kconfig
Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/capabilities-move-cap_file_mmap-to-commoncap.c.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/capabilities-move-cap_file_mmap-to-commoncap.c.patch Thu Oct 8 04:50:27 2009 (r14349)
@@ -0,0 +1,91 @@
+commit 9c0d90103c7e0eb6e638e5b649e9f6d8d9c1b4b3
+Author: Eric Paris <eparis at redhat.com>
+Date: Fri Jul 31 12:53:58 2009 -0400
+
+ Capabilities: move cap_file_mmap to commoncap.c
+
+ Currently we duplicate the mmap_min_addr test in cap_file_mmap and in
+ security_file_mmap if !CONFIG_SECURITY. This patch moves cap_file_mmap
+ into commoncap.c and then calls that function directly from
+ security_file_mmap ifndef CONFIG_SECURITY like all of the other capability
+ checks are done.
+
+ Signed-off-by: Eric Paris <eparis at redhat.com>
+ Acked-by: Serge Hallyn <serue at us.ibm.com>
+ Signed-off-by: James Morris <jmorris at namei.org>
+
+Backported to Debian's 2.6.26 by dann frazier <dannf at debian.org>
+
+diff -urpN linux-source-2.6.26.orig/include/linux/security.h linux-source-2.6.26/include/linux/security.h
+--- linux-source-2.6.26.orig/include/linux/security.h 2009-09-30 09:13:56.000000000 -0600
++++ linux-source-2.6.26/include/linux/security.h 2009-09-30 09:14:23.000000000 -0600
+@@ -58,6 +58,9 @@ extern int cap_inode_setxattr(struct den
+ extern int cap_inode_removexattr(struct dentry *dentry, const char *name);
+ extern int cap_inode_need_killpriv(struct dentry *dentry);
+ extern int cap_inode_killpriv(struct dentry *dentry);
++extern int cap_file_mmap(struct file *file, unsigned long reqprot,
++ unsigned long prot, unsigned long flags,
++ unsigned long addr, unsigned long addr_only);
+ extern int cap_task_post_setuid(uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
+ extern void cap_task_reparent_to_init(struct task_struct *p);
+ extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
+@@ -2135,9 +2138,7 @@ static inline int security_file_mmap(str
+ unsigned long addr,
+ unsigned long addr_only)
+ {
+- if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO))
+- return -EACCES;
+- return 0;
++ return cap_file_mmap(file, reqprot, prot, flags, addr, addr_only);
+ }
+
+ static inline int security_file_mprotect(struct vm_area_struct *vma,
+diff -urpN linux-source-2.6.26.orig/security/commoncap.c linux-source-2.6.26/security/commoncap.c
+--- linux-source-2.6.26.orig/security/commoncap.c 2009-08-18 23:15:10.000000000 -0600
++++ linux-source-2.6.26/security/commoncap.c 2009-09-30 09:17:19.000000000 -0600
+@@ -689,3 +689,31 @@ int cap_vm_enough_memory(struct mm_struc
+ return __vm_enough_memory(mm, pages, cap_sys_admin);
+ }
+
++/*
++ * cap_file_mmap - check if able to map given addr
++ * @file: unused
++ * @reqprot: unused
++ * @prot: unused
++ * @flags: unused
++ * @addr: address attempting to be mapped
++ * @addr_only: unused
++ *
++ * If the process is attempting to map memory below mmap_min_addr they need
++ * CAP_SYS_RAWIO. The other parameters to this function are unused by the
++ * capability security module. Returns 0 if this mapping should be allowed
++ * -EPERM if not.
++ */
++int cap_file_mmap(struct file *file, unsigned long reqprot,
++ unsigned long prot, unsigned long flags,
++ unsigned long addr, unsigned long addr_only)
++{
++ int ret = 0;
++
++ if (addr < mmap_min_addr) {
++ ret = cap_capable(current, CAP_SYS_RAWIO);
++ /* set PF_SUPERPRIV if it turns out we allow the low mmap */
++ if (ret == 0)
++ current->flags |= PF_SUPERPRIV;
++ }
++ return ret;
++}
+diff -urpN linux-source-2.6.26.orig/security/dummy.c linux-source-2.6.26/security/dummy.c
+--- linux-source-2.6.26.orig/security/dummy.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/security/dummy.c 2009-09-30 09:14:23.000000000 -0600
+@@ -459,9 +459,7 @@ static int dummy_file_mmap (struct file
+ unsigned long addr,
+ unsigned long addr_only)
+ {
+- if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO))
+- return -EACCES;
+- return 0;
++ return cap_file_mmap(file, reqprot, prot, flags, addr, addr_only);
+ }
+
+ static int dummy_file_mprotect (struct vm_area_struct *vma,
Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/security-define-round_hint_to_min-when-CONFIG_SECURITY-is-off.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/security-define-round_hint_to_min-when-CONFIG_SECURITY-is-off.patch Thu Oct 8 04:50:27 2009 (r14349)
@@ -0,0 +1,63 @@
+commit 1d9959734a1949ea4f2427bd2d8b21ede6b2441c
+Author: Eric Paris <eparis at redhat.com>
+Date: Fri Aug 7 14:53:57 2009 -0400
+
+ security: define round_hint_to_min in !CONFIG_SECURITY
+
+ Fix the header files to define round_hint_to_min() and to define
+ mmap_min_addr_handler() in the !CONFIG_SECURITY case.
+
+ Built and tested with !CONFIG_SECURITY
+
+ Signed-off-by: Eric Paris <eparis at redhat.com>
+ Signed-off-by: James Morris <jmorris at namei.org>
+
+Adjusted to apply to Debian's 2.6.26 by dann frazier <dannf at debian.org>
+
+diff -urpN linux-source-2.6.26.orig/include/linux/security.h linux-source-2.6.26/include/linux/security.h
+--- linux-source-2.6.26.orig/include/linux/security.h 2009-09-30 09:21:57.000000000 -0600
++++ linux-source-2.6.26/include/linux/security.h 2009-09-30 10:08:42.000000000 -0600
+@@ -115,6 +115,21 @@ struct request_sock;
+ #define LSM_UNSAFE_PTRACE 2
+ #define LSM_UNSAFE_PTRACE_CAP 4
+
++/*
++ * 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);
++
+ #ifdef CONFIG_SECURITY
+
+ struct security_mnt_opts {
+@@ -143,21 +158,6 @@ static inline void security_free_mnt_opt
+ 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
+ *
Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/security-seperate-lsm-specific-mmap_min_addr.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/security-seperate-lsm-specific-mmap_min_addr.patch Thu Oct 8 04:50:27 2009 (r14349)
@@ -0,0 +1,320 @@
+commit a2551df7ec568d87793d2eea4ca744e86318f205
+Author: Eric Paris <eparis at redhat.com>
+Date: Fri Jul 31 12:54:11 2009 -0400
+
+ 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: Eric Paris <eparis at redhat.com>
+ Signed-off-by: James Morris <jmorris at namei.org>
+
+Backported to Debian's 2.6.26 by dann frazier <dannf at debian.org>
+
+diff -urpN linux-source-2.6.26.orig/include/linux/mm.h linux-source-2.6.26/include/linux/mm.h
+--- linux-source-2.6.26.orig/include/linux/mm.h 2009-09-30 09:13:56.000000000 -0600
++++ linux-source-2.6.26/include/linux/mm.h 2009-09-30 09:21:57.000000000 -0600
+@@ -33,8 +33,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>
+@@ -558,19 +556,6 @@ static inline void set_page_links(struct
+ }
+
+ /*
+- * 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()
+ */
+ #include <linux/vmstat.h>
+diff -urpN linux-source-2.6.26.orig/include/linux/security.h linux-source-2.6.26/include/linux/security.h
+--- linux-source-2.6.26.orig/include/linux/security.h 2009-09-30 09:13:56.000000000 -0600
++++ linux-source-2.6.26/include/linux/security.h 2009-09-30 09:21:57.000000000 -0600
+@@ -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>
+@@ -58,6 +59,9 @@ extern int cap_inode_setxattr(struct den
+ extern int cap_inode_removexattr(struct dentry *dentry, const char *name);
+ extern int cap_inode_need_killpriv(struct dentry *dentry);
+ extern int cap_inode_killpriv(struct dentry *dentry);
++extern int cap_file_mmap(struct file *file, unsigned long reqprot,
++ unsigned long prot, unsigned long flags,
++ unsigned long addr, unsigned long addr_only);
+ extern int cap_task_post_setuid(uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
+ extern void cap_task_reparent_to_init(struct task_struct *p);
+ extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
+@@ -84,6 +88,7 @@ extern int cap_netlink_send(struct sock
+ 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
+ */
+@@ -138,6 +143,21 @@ static inline void security_free_mnt_opt
+ 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
+ *
+@@ -2135,9 +2155,7 @@ static inline int security_file_mmap(str
+ unsigned long addr,
+ unsigned long addr_only)
+ {
+- if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO))
+- return -EACCES;
+- return 0;
++ return cap_file_mmap(file, reqprot, prot, flags, addr, addr_only);
+ }
+
+ static inline int security_file_mprotect(struct vm_area_struct *vma,
+diff -urpN linux-source-2.6.26.orig/kernel/sysctl.c linux-source-2.6.26/kernel/sysctl.c
+--- linux-source-2.6.26.orig/kernel/sysctl.c 2009-09-30 09:13:56.000000000 -0600
++++ linux-source-2.6.26/kernel/sysctl.c 2009-09-30 09:21:57.000000000 -0600
+@@ -1096,10 +1096,10 @@ static struct ctl_table vm_table[] = {
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "mmap_min_addr",
+- .data = &mmap_min_addr,
+- .maxlen = sizeof(unsigned long),
++ .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
+ {
+diff -urpN linux-source-2.6.26.orig/mm/Kconfig linux-source-2.6.26/mm/Kconfig
+--- linux-source-2.6.26.orig/mm/Kconfig 2009-09-30 09:13:56.000000000 -0600
++++ linux-source-2.6.26/mm/Kconfig 2009-09-30 09:21:57.000000000 -0600
+@@ -217,9 +217,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.
+diff -urpN linux-source-2.6.26.orig/mm/mmap.c linux-source-2.6.26/mm/mmap.c
+--- linux-source-2.6.26.orig/mm/mmap.c 2009-09-30 09:13:56.000000000 -0600
++++ linux-source-2.6.26/mm/mmap.c 2009-09-30 09:21:57.000000000 -0600
+@@ -82,9 +82,6 @@ int sysctl_overcommit_ratio = 50; /* def
+ int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
+ atomic_long_t vm_committed_space = ATOMIC_LONG_INIT(0);
+
+-/* 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
+diff -urpN linux-source-2.6.26.orig/security/commoncap.c linux-source-2.6.26/security/commoncap.c
+--- linux-source-2.6.26.orig/security/commoncap.c 2009-08-18 23:15:10.000000000 -0600
++++ linux-source-2.6.26/security/commoncap.c 2009-09-30 09:34:11.000000000 -0600
+@@ -689,3 +689,31 @@ int cap_vm_enough_memory(struct mm_struc
+ return __vm_enough_memory(mm, pages, cap_sys_admin);
+ }
+
++/*
++ * cap_file_mmap - check if able to map given addr
++ * @file: unused
++ * @reqprot: unused
++ * @prot: unused
++ * @flags: unused
++ * @addr: address attempting to be mapped
++ * @addr_only: unused
++ *
++ * If the process is attempting to map memory below mmap_min_addr they need
++ * CAP_SYS_RAWIO. The other parameters to this function are unused by the
++ * capability security module. Returns 0 if this mapping should be allowed
++ * -EPERM if not.
++ */
++int cap_file_mmap(struct file *file, unsigned long reqprot,
++ unsigned long prot, unsigned long flags,
++ unsigned long addr, unsigned long addr_only)
++{
++ int ret = 0;
++
++ if (addr < dac_mmap_min_addr) {
++ ret = cap_capable(current, CAP_SYS_RAWIO);
++ /* set PF_SUPERPRIV if it turns out we allow the low mmap */
++ if (ret == 0)
++ current->flags |= PF_SUPERPRIV;
++ }
++ return ret;
++}
+diff -urpN linux-source-2.6.26.orig/security/dummy.c linux-source-2.6.26/security/dummy.c
+--- linux-source-2.6.26.orig/security/dummy.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/security/dummy.c 2009-09-30 09:14:23.000000000 -0600
+@@ -459,9 +459,7 @@ static int dummy_file_mmap (struct file
+ unsigned long addr,
+ unsigned long addr_only)
+ {
+- if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO))
+- return -EACCES;
+- return 0;
++ return cap_file_mmap(file, reqprot, prot, flags, addr, addr_only);
+ }
+
+ static int dummy_file_mprotect (struct vm_area_struct *vma,
+diff -urpN linux-source-2.6.26.orig/security/Kconfig linux-source-2.6.26/security/Kconfig
+--- linux-source-2.6.26.orig/security/Kconfig 2009-09-30 09:13:56.000000000 -0600
++++ linux-source-2.6.26/security/Kconfig 2009-09-30 09:21:57.000000000 -0600
+@@ -104,6 +104,22 @@ config SECURITY_ROOTPLUG
+
+ If you are unsure how to answer this question, answer N.
+
++config LSM_MMAP_MIN_ADDR
++ int "Low address space for LSM to from user allocation"
++ depends on SECURITY && SECURITY_SELINUX
++ default 65535
++ help
++ This is the portion of low virtual memory which should be protected
++ from userspace allocation. Keeping a user from writing to low pages
++ can help reduce the impact of kernel NULL pointer bugs.
++
++ 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 or have some need to map
++ this low address space will need the permission specific to the
++ systems running LSM.
++
+ source security/selinux/Kconfig
+ source security/smack/Kconfig
+
+diff -urpN linux-source-2.6.26.orig/security/Makefile linux-source-2.6.26/security/Makefile
+--- linux-source-2.6.26.orig/security/Makefile 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/security/Makefile 2009-09-30 09:33:07.000000000 -0600
+@@ -6,10 +6,7 @@ obj-$(CONFIG_KEYS) += keys/
+ subdir-$(CONFIG_SECURITY_SELINUX) += selinux
+ subdir-$(CONFIG_SECURITY_SMACK) += smack
+
+-# if we don't select a security model, use the default capabilities
+-ifneq ($(CONFIG_SECURITY),y)
+-obj-y += commoncap.o
+-endif
++obj-y += commoncap.o min_addr.o # Is it ok to enable commoncap when CONFIG_SECURITY=y? have to now that we moved cap_file_mmap there
+
+ # Object file lists
+ obj-$(CONFIG_SECURITY) += security.o dummy.o inode.o
+diff -urpN linux-source-2.6.26.orig/security/min_addr.c linux-source-2.6.26/security/min_addr.c
+--- linux-source-2.6.26.orig/security/min_addr.c 1969-12-31 17:00:00.000000000 -0700
++++ linux-source-2.6.26/security/min_addr.c 2009-09-30 09:21:57.000000000 -0600
+@@ -0,0 +1,49 @@
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/security.h>
++#include <linux/sysctl.h>
++
++/* amount of vm to protect from userspace access by both DAC and the LSM*/
++unsigned long mmap_min_addr;
++/* amount of vm to protect from userspace using CAP_SYS_RAWIO (DAC) */
++unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
++/* amount of vm to protect from userspace using the LSM = CONFIG_LSM_MMAP_MIN_ADDR */
++
++/*
++ * Update mmap_min_addr = max(dac_mmap_min_addr, CONFIG_LSM_MMAP_MIN_ADDR)
++ */
++static void update_mmap_min_addr(void)
++{
++#ifdef CONFIG_LSM_MMAP_MIN_ADDR
++ if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR)
++ mmap_min_addr = dac_mmap_min_addr;
++ else
++ mmap_min_addr = CONFIG_LSM_MMAP_MIN_ADDR;
++#else
++ mmap_min_addr = dac_mmap_min_addr;
++#endif
++}
++
++/*
++ * sysctl handler which just sets dac_mmap_min_addr = the new value and then
++ * calls update_mmap_min_addr() so non MAP_FIXED hints get rounded properly
++ */
++int mmap_min_addr_handler(struct ctl_table *table, int write, struct file *filp,
++ void __user *buffer, size_t *lenp, loff_t *ppos)
++{
++ int ret;
++
++ ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos);
++
++ update_mmap_min_addr();
++
++ return ret;
++}
++
++int __init init_mmap_min_addr(void)
++{
++ update_mmap_min_addr();
++
++ return 0;
++}
++pure_initcall(init_mmap_min_addr);
+diff -urpN linux-source-2.6.26.orig/security/selinux/hooks.c linux-source-2.6.26/security/selinux/hooks.c
+--- linux-source-2.6.26.orig/security/selinux/hooks.c 2009-09-30 09:14:01.000000000 -0600
++++ linux-source-2.6.26/security/selinux/hooks.c 2009-09-30 09:21:57.000000000 -0600
+@@ -2951,7 +2951,7 @@ static int selinux_file_mmap(struct file
+ * at bad behaviour/exploit that we always want to get the AVC, even
+ * if DAC would have also denied the operation.
+ */
+- if (addr < mmap_min_addr) {
++ if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
+ rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
+ MEMPROTECT__MMAP_ZERO, NULL);
+ if (rc)
Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/security-use-mmap_min_addr-independently-of-security-models.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/security-use-mmap_min_addr-independently-of-security-models.patch Thu Oct 8 04:50:27 2009 (r14349)
@@ -0,0 +1,152 @@
+commit e0a94c2a63f2644826069044649669b5e7ca75d3
+Author: Christoph Lameter <cl at linux-foundation.org>
+Date: Wed Jun 3 16:04:31 2009 -0400
+
+ security: use mmap_min_addr indepedently of security models
+
+ This patch removes the dependency of mmap_min_addr on CONFIG_SECURITY.
+ It also sets a default mmap_min_addr of 4096.
+
+ mmapping of addresses below 4096 will only be possible for processes
+ with CAP_SYS_RAWIO.
+
+ Signed-off-by: Christoph Lameter <cl at linux-foundation.org>
+ Acked-by: Eric Paris <eparis at redhat.com>
+ Looks-ok-by: Linus Torvalds <torvalds at linux-foundation.org>
+ Signed-off-by: James Morris <jmorris at namei.org>
+
+Adjusted to apply to Debian's 2.6.26 by dann frazier <dannf at debian.org>
+
+diff -urpN linux-source-2.6.26.orig/include/linux/mm.h linux-source-2.6.26/include/linux/mm.h
+--- linux-source-2.6.26.orig/include/linux/mm.h 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/linux/mm.h 2009-09-29 23:26:05.000000000 -0600
+@@ -563,12 +563,10 @@ static inline void set_page_links(struct
+ */
+ static inline unsigned long round_hint_to_min(unsigned long hint)
+ {
+-#ifdef CONFIG_SECURITY
+ hint &= PAGE_MASK;
+ if (((void *)hint != NULL) &&
+ (hint < mmap_min_addr))
+ return PAGE_ALIGN(mmap_min_addr);
+-#endif
+ return hint;
+ }
+
+diff -urpN linux-source-2.6.26.orig/include/linux/security.h linux-source-2.6.26/include/linux/security.h
+--- linux-source-2.6.26.orig/include/linux/security.h 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/include/linux/security.h 2009-09-29 23:26:05.000000000 -0600
+@@ -2135,6 +2135,8 @@ static inline int security_file_mmap(str
+ unsigned long addr,
+ unsigned long addr_only)
+ {
++ if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO))
++ return -EACCES;
+ return 0;
+ }
+
+diff -urpN linux-source-2.6.26.orig/kernel/sysctl.c linux-source-2.6.26/kernel/sysctl.c
+--- linux-source-2.6.26.orig/kernel/sysctl.c 2009-08-18 23:15:11.000000000 -0600
++++ linux-source-2.6.26/kernel/sysctl.c 2009-09-29 23:26:05.000000000 -0600
+@@ -1093,7 +1093,6 @@ static struct ctl_table vm_table[] = {
+ .strategy = &sysctl_jiffies,
+ },
+ #endif
+-#ifdef CONFIG_SECURITY
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "mmap_min_addr",
+@@ -1102,7 +1101,6 @@ static struct ctl_table vm_table[] = {
+ .mode = 0644,
+ .proc_handler = &proc_doulongvec_minmax,
+ },
+-#endif
+ #ifdef CONFIG_NUMA
+ {
+ .ctl_name = CTL_UNNUMBERED,
+diff -urpN linux-source-2.6.26.orig/mm/Kconfig linux-source-2.6.26/mm/Kconfig
+--- linux-source-2.6.26.orig/mm/Kconfig 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/mm/Kconfig 2009-09-29 23:28:51.000000000 -0600
+@@ -205,3 +205,23 @@ config NR_QUICK
+ config VIRT_TO_BUS
+ def_bool y
+ depends on !ARCH_NO_VIRT_TO_BUS
++
++config DEFAULT_MMAP_MIN_ADDR
++ int "Low address space to protect from user allocation"
++ default 4096
++ help
++ This is the portion of low virtual memory which should be protected
++ from userspace allocation. Keeping a user from writing to low pages
++ can help reduce the impact of kernel NULL pointer bugs.
++
++ 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.
++
++ This value can be changed after boot using the
++ /proc/sys/vm/mmap_min_addr tunable.
++
++
+diff -urpN linux-source-2.6.26.orig/mm/mmap.c linux-source-2.6.26/mm/mmap.c
+--- linux-source-2.6.26.orig/mm/mmap.c 2009-08-18 23:15:11.000000000 -0600
++++ linux-source-2.6.26/mm/mmap.c 2009-09-29 23:26:05.000000000 -0600
+@@ -82,6 +82,9 @@ int sysctl_overcommit_ratio = 50; /* def
+ int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
+ atomic_long_t vm_committed_space = ATOMIC_LONG_INIT(0);
+
++/* 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
+diff -urpN linux-source-2.6.26.orig/security/Kconfig linux-source-2.6.26/security/Kconfig
+--- linux-source-2.6.26.orig/security/Kconfig 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/security/Kconfig 2009-09-29 23:26:05.000000000 -0600
+@@ -101,28 +101,8 @@ config SECURITY_ROOTPLUG
+
+ See <http://www.linuxjournal.com/article.php?sid=6279> for
+ more information about this module.
+-
+- If you are unsure how to answer this question, answer N.
+-
+-config SECURITY_DEFAULT_MMAP_MIN_ADDR
+- int "Low address space to protect from user allocation"
+- depends on SECURITY
+- default 0
+- help
+- This is the portion of low virtual memory which should be protected
+- from userspace allocation. Keeping a user from writing to low pages
+- can help reduce the impact of kernel NULL pointer bugs.
+-
+- 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.
+-
+- This value can be changed after boot using the
+- /proc/sys/vm/mmap_min_addr tunable.
+
++ If you are unsure how to answer this question, answer N.
+
+ source security/selinux/Kconfig
+ source security/smack/Kconfig
+diff -urpN linux-source-2.6.26.orig/security/security.c linux-source-2.6.26/security/security.c
+--- linux-source-2.6.26.orig/security/security.c 2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/security/security.c 2009-09-29 23:26:05.000000000 -0600
+@@ -26,9 +26,6 @@ extern void security_fixup_ops(struct se
+
+ struct security_operations *security_ops; /* Initialized to NULL */
+
+-/* amount of vm to protect from userspace access */
+-unsigned long mmap_min_addr = CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR;
+-
+ static inline int verify(struct security_operations *ops)
+ {
+ /* verify the security_operations structure exists */
Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/selinux-call-cap_file_mmap-in-selinux_file_mmap.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/selinux-call-cap_file_mmap-in-selinux_file_mmap.patch Thu Oct 8 04:50:27 2009 (r14349)
@@ -0,0 +1,44 @@
+commit 8cf948e744e0218af604c32edecde10006dc8e9e
+Author: Eric Paris <eparis at redhat.com>
+Date: Fri Jul 31 12:54:05 2009 -0400
+
+ SELinux: call cap_file_mmap in selinux_file_mmap
+
+ Currently SELinux does not check CAP_SYS_RAWIO in the file_mmap hook. This
+ means there is no DAC check on the ability to mmap low addresses in the
+ memory space. This function adds the DAC check for CAP_SYS_RAWIO while
+ maintaining the selinux check on mmap_zero. This means that processes
+ which need to mmap low memory will need CAP_SYS_RAWIO and mmap_zero but will
+ NOT need the SELinux sys_rawio capability.
+
+ Signed-off-by: Eric Paris <eparis at redhat.com>
+ Signed-off-by: James Morris <jmorris at namei.org>
+
+Adjusted to apply to Debian's 2.6.26 by dann frazier <dannf at debian.org>
+
+diff -urpN linux-source-2.6.26.orig/security/selinux/hooks.c linux-source-2.6.26/security/selinux/hooks.c
+--- linux-source-2.6.26.orig/security/selinux/hooks.c 2009-08-18 23:15:14.000000000 -0600
++++ linux-source-2.6.26/security/selinux/hooks.c 2009-09-29 23:38:01.000000000 -0600
+@@ -2945,9 +2945,21 @@ static int selinux_file_mmap(struct file
+ int rc = 0;
+ u32 sid = ((struct task_security_struct *)(current->security))->sid;
+
+- if (addr < mmap_min_addr)
++ /*
++ * notice that we are intentionally putting the SELinux check before
++ * the secondary cap_file_mmap check. This is such a likely attempt
++ * at bad behaviour/exploit that we always want to get the AVC, even
++ * if DAC would have also denied the operation.
++ */
++ if (addr < mmap_min_addr) {
+ rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
+ MEMPROTECT__MMAP_ZERO, NULL);
++ if (rc)
++ return rc;
++ }
++
++ /* do DAC check on address space usage */
++ rc = cap_file_mmap(file, reqprot, prot, flags, addr, addr_only);
+ if (rc || addr_only)
+ return rc;
+
Modified: dists/lenny-security/linux-2.6/debian/patches/series/19lenny1
==============================================================================
--- dists/lenny-security/linux-2.6/debian/patches/series/19lenny1 Thu Oct 8 01:59:54 2009 (r14348)
+++ dists/lenny-security/linux-2.6/debian/patches/series/19lenny1 Thu Oct 8 04:50:27 2009 (r14349)
@@ -1,3 +1,8 @@
+ bugfix/all/appletalk-use-correct-returns-for-atalk_rcv.patch
+ bugfix/all/appletalk-fix-skb-leak-when-ipddp-interface-is-not-loaded.patch
+ bugfix/x86/kvm-disallow-hypercalls-for-guest-callers-in-rings-gt-0.patch
++ bugfix/all/security-use-mmap_min_addr-independently-of-security-models.patch
++ bugfix/all/selinux-call-cap_file_mmap-in-selinux_file_mmap.patch
++ bugfix/all/capabilities-move-cap_file_mmap-to-commoncap.c.patch
++ bugfix/all/security-seperate-lsm-specific-mmap_min_addr.patch
++ bugfix/all/security-define-round_hint_to_min-when-CONFIG_SECURITY-is-off.patch
More information about the Kernel-svn-changes
mailing list