[RFC][PATCH] Security hook for vm_enough_memory

From: Stephen Smalley (sds@epoch.ncsc.mil)
Date: Mon Jun 23 2003 - 11:25:28 EST


This patch for 2.5.73 replaces the CAP_SYS_ADMIN test in
vm_enough_memory with a security_vm_allocate hook call so that security
modules such as SELinux can distinguish this test from other
CAP_SYS_ADMIN checks. This change is necessary since the
vm_enough_memory capability check is applied to all processes that
allocate mappings and we don't want to spuriously audit CAP_SYS_ADMIN
denials generated by this test. If anyone has any objections to this
patch, please let me know. Thanks.

 include/linux/security.h | 22 ++++++++++++++++++++++
 mm/mmap.c | 2 +-
 security/capability.c | 2 ++
 security/dummy.c | 8 ++++++++
 4 files changed, 33 insertions(+), 1 deletion(-)

Index: linux-2.5/include/linux/security.h
===================================================================
RCS file: /nfshome/pal/CVS/linux-2.5/include/linux/security.h,v
retrieving revision 1.23
diff -u -r1.23 security.h
--- linux-2.5/include/linux/security.h 16 Jun 2003 17:54:19 -0000 1.23
+++ linux-2.5/include/linux/security.h 23 Jun 2003 13:54:48 -0000
@@ -63,6 +63,13 @@
         return 0;
 }
 
+static inline int cap_vm_allocate (void)
+{
+ if (capable(CAP_SYS_ADMIN))
+ return 0;
+ return -EPERM;
+}
+
 /*
  * Values used in the task_security_ops calls
  */
@@ -958,6 +965,10 @@
  * See the syslog(2) manual page for an explanation of the @type values.
  * @type contains the type of action.
  * Return 0 if permission is granted.
+ * @vm_allocate:
+ * Check permissions for allocating memory reserved for privileged
+ * processes. Called by vm_enough_memory.
+ * Return 0 if permission is granted.
  *
  * @register_security:
  * allow module stacking.
@@ -989,6 +1000,7 @@
         int (*quotactl) (int cmds, int type, int id, struct super_block * sb);
         int (*quota_on) (struct file * f);
         int (*syslog) (int type);
+ int (*vm_allocate) (void);
 
         int (*bprm_alloc_security) (struct linux_binprm * bprm);
         void (*bprm_free_security) (struct linux_binprm * bprm);
@@ -1238,6 +1250,11 @@
         return security_ops->syslog(type);
 }
 
+static inline int security_vm_allocate(void)
+{
+ return security_ops->vm_allocate();
+}
+
 static inline int security_bprm_alloc (struct linux_binprm *bprm)
 {
         return security_ops->bprm_alloc_security (bprm);
@@ -1896,6 +1913,11 @@
 static inline int security_syslog(int type)
 {
         return cap_syslog(type);
+}
+
+static inline int security_vm_allocate(void)
+{
+ return cap_vm_allocate();
 }
 
 static inline int security_bprm_alloc (struct linux_binprm *bprm)
Index: linux-2.5/mm/mmap.c
===================================================================
RCS file: /nfshome/pal/CVS/linux-2.5/mm/mmap.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 mmap.c
--- linux-2.5/mm/mmap.c 16 Jun 2003 13:26:01 -0000 1.1.1.7
+++ linux-2.5/mm/mmap.c 23 Jun 2003 13:55:40 -0000
@@ -93,7 +93,7 @@
                 /*
                  * Leave the last 3% for root
                  */
- if (!capable(CAP_SYS_ADMIN))
+ if (security_vm_allocate())
                         free -= free / 32;
                 
                 if (free > pages)
Index: linux-2.5/security/capability.c
===================================================================
RCS file: /nfshome/pal/CVS/linux-2.5/security/capability.c,v
retrieving revision 1.6
diff -u -r1.6 capability.c
--- linux-2.5/security/capability.c 16 Jun 2003 15:27:36 -0000 1.6
+++ linux-2.5/security/capability.c 23 Jun 2003 13:54:48 -0000
@@ -307,6 +307,8 @@
         .task_reparent_to_init = cap_task_reparent_to_init,
 
         .syslog = cap_syslog,
+
+ .vm_allocate = cap_vm_allocate,
 };
 
 #if defined(CONFIG_SECURITY_CAPABILITIES_MODULE)
Index: linux-2.5/security/dummy.c
===================================================================
RCS file: /nfshome/pal/CVS/linux-2.5/security/dummy.c,v
retrieving revision 1.19
diff -u -r1.19 dummy.c
--- linux-2.5/security/dummy.c 16 Jun 2003 15:27:36 -0000 1.19
+++ linux-2.5/security/dummy.c 23 Jun 2003 13:54:48 -0000
@@ -97,6 +97,13 @@
         return 0;
 }
 
+static int dummy_vm_allocate (void)
+{
+ if (current->euid)
+ return -EPERM;
+ return 0;
+}
+
 static int dummy_bprm_alloc_security (struct linux_binprm *bprm)
 {
         return 0;
@@ -793,6 +800,7 @@
         set_to_dummy_if_null(ops, quota_on);
         set_to_dummy_if_null(ops, sysctl);
         set_to_dummy_if_null(ops, syslog);
+ set_to_dummy_if_null(ops, vm_allocate);
         set_to_dummy_if_null(ops, bprm_alloc_security);
         set_to_dummy_if_null(ops, bprm_free_security);
         set_to_dummy_if_null(ops, bprm_compute_creds);

-- 
Stephen Smalley <sds@epoch.ncsc.mil>
National Security Agency

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Jun 23 2003 - 22:00:41 EST