aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2007-06-28 15:55:21 -0400
committerJames Morris <jmorris@namei.org>2007-07-11 22:52:29 -0400
commited0321895182ffb6ecf210e066d87911b270d587 (patch)
tree832bb54666f73b06e55322df40f915c5e9ef64d7 /security
parent13bddc2e9d591e31bf20020dc19ea6ca85de420e (diff)
security: Protection for exploiting null dereference using mmap
Add a new security check on mmap operations to see if the user is attempting to mmap to low area of the address space. The amount of space protected is indicated by the new proc tunable /proc/sys/vm/mmap_min_addr and defaults to 0, preserving existing behavior. This patch uses a new SELinux security class "memprotect." Policy already contains a number of allow rules like a_t self:process * (unconfined_t being one of them) which mean that putting this check in the process class (its best current fit) would make it useless as all user processes, which we also want to protect against, would be allowed. By taking the memprotect name of the new class it will also make it possible for us to move some of the other memory protect permissions out of 'process' and into the new class next time we bump the policy version number (which I also think is a good future idea) Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Acked-by: Chris Wright <chrisw@sous-sol.org> Signed-off-by: Eric Paris <eparis@redhat.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
-rw-r--r--security/dummy.c6
-rw-r--r--security/security.c2
-rw-r--r--security/selinux/hooks.c12
-rw-r--r--security/selinux/include/av_perm_to_string.h1
-rw-r--r--security/selinux/include/av_permissions.h1
-rw-r--r--security/selinux/include/class_to_string.h1
-rw-r--r--security/selinux/include/flask.h1
7 files changed, 19 insertions, 5 deletions
diff --git a/security/dummy.c b/security/dummy.c
index 8ffd76405b5b..d6a112ce2975 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -420,8 +420,12 @@ static int dummy_file_ioctl (struct file *file, unsigned int command,
420 420
421static int dummy_file_mmap (struct file *file, unsigned long reqprot, 421static int dummy_file_mmap (struct file *file, unsigned long reqprot,
422 unsigned long prot, 422 unsigned long prot,
423 unsigned long flags) 423 unsigned long flags,
424 unsigned long addr,
425 unsigned long addr_only)
424{ 426{
427 if (addr < mmap_min_addr)
428 return -EACCES;
425 return 0; 429 return 0;
426} 430}
427 431
diff --git a/security/security.c b/security/security.c
index fc8601b2b7ac..024484fc59b0 100644
--- a/security/security.c
+++ b/security/security.c
@@ -24,6 +24,7 @@ extern struct security_operations dummy_security_ops;
24extern void security_fixup_ops(struct security_operations *ops); 24extern void security_fixup_ops(struct security_operations *ops);
25 25
26struct security_operations *security_ops; /* Initialized to NULL */ 26struct security_operations *security_ops; /* Initialized to NULL */
27unsigned long mmap_min_addr; /* 0 means no protection */
27 28
28static inline int verify(struct security_operations *ops) 29static inline int verify(struct security_operations *ops)
29{ 30{
@@ -176,4 +177,5 @@ EXPORT_SYMBOL_GPL(register_security);
176EXPORT_SYMBOL_GPL(unregister_security); 177EXPORT_SYMBOL_GPL(unregister_security);
177EXPORT_SYMBOL_GPL(mod_reg_security); 178EXPORT_SYMBOL_GPL(mod_reg_security);
178EXPORT_SYMBOL_GPL(mod_unreg_security); 179EXPORT_SYMBOL_GPL(mod_unreg_security);
180EXPORT_SYMBOL_GPL(mmap_min_addr);
179EXPORT_SYMBOL(security_ops); 181EXPORT_SYMBOL(security_ops);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b29059ecc045..78c3f98fcdcf 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2569,12 +2569,16 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
2569} 2569}
2570 2570
2571static int selinux_file_mmap(struct file *file, unsigned long reqprot, 2571static int selinux_file_mmap(struct file *file, unsigned long reqprot,
2572 unsigned long prot, unsigned long flags) 2572 unsigned long prot, unsigned long flags,
2573 unsigned long addr, unsigned long addr_only)
2573{ 2574{
2574 int rc; 2575 int rc = 0;
2576 u32 sid = ((struct task_security_struct*)(current->security))->sid;
2575 2577
2576 rc = secondary_ops->file_mmap(file, reqprot, prot, flags); 2578 if (addr < mmap_min_addr)
2577 if (rc) 2579 rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
2580 MEMPROTECT__MMAP_ZERO, NULL);
2581 if (rc || addr_only)
2578 return rc; 2582 return rc;
2579 2583
2580 if (selinux_checkreqprot) 2584 if (selinux_checkreqprot)
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index b83e74012a97..049bf69429b6 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -158,3 +158,4 @@
158 S_(SECCLASS_KEY, KEY__CREATE, "create") 158 S_(SECCLASS_KEY, KEY__CREATE, "create")
159 S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind") 159 S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind")
160 S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect") 160 S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect")
161 S_(SECCLASS_MEMPROTECT, MEMPROTECT__MMAP_ZERO, "mmap_zero")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index 5fee1735bffe..eda89a2ec635 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -823,3 +823,4 @@
823#define DCCP_SOCKET__NAME_BIND 0x00200000UL 823#define DCCP_SOCKET__NAME_BIND 0x00200000UL
824#define DCCP_SOCKET__NODE_BIND 0x00400000UL 824#define DCCP_SOCKET__NODE_BIND 0x00400000UL
825#define DCCP_SOCKET__NAME_CONNECT 0x00800000UL 825#define DCCP_SOCKET__NAME_CONNECT 0x00800000UL
826#define MEMPROTECT__MMAP_ZERO 0x00000001UL
diff --git a/security/selinux/include/class_to_string.h b/security/selinux/include/class_to_string.h
index 378799068441..e77de0e62ea0 100644
--- a/security/selinux/include/class_to_string.h
+++ b/security/selinux/include/class_to_string.h
@@ -63,3 +63,4 @@
63 S_("key") 63 S_("key")
64 S_(NULL) 64 S_(NULL)
65 S_("dccp_socket") 65 S_("dccp_socket")
66 S_("memprotect")
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
index 35f309f47873..a9c2b20f14b5 100644
--- a/security/selinux/include/flask.h
+++ b/security/selinux/include/flask.h
@@ -49,6 +49,7 @@
49#define SECCLASS_PACKET 57 49#define SECCLASS_PACKET 57
50#define SECCLASS_KEY 58 50#define SECCLASS_KEY 58
51#define SECCLASS_DCCP_SOCKET 60 51#define SECCLASS_DCCP_SOCKET 60
52#define SECCLASS_MEMPROTECT 61
52 53
53/* 54/*
54 * Security identifier indices for initial entities 55 * Security identifier indices for initial entities