[RFC][PATCH] Security hook for vm_enough_memory

Stephen Smalley (sds@epoch.ncsc.mil)
23 Jun 2003 12:25:28 -0400


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/