
From: James Morris <jmorris@redhat.com>

This patch adds controls to the SELinux module over the setting and
inheritance of resource limits.  With these controls, the ability to set
hard limits can be limited to specific processes such as login, and when an
untrusted process invokes a more trusted program, soft limits can be reset,
thereby avoiding failures in the trusted program due to malicious setting
of the soft limit by the untrusted process.  Roland McGrath provided input
and feedback on the patch, which was implemented by Stephen Smalley
<sds@epoch.ncsc.mil>.



---

 25-akpm/security/selinux/hooks.c                     |   34 ++++++++++++++++---
 25-akpm/security/selinux/include/av_perm_to_string.h |    2 +
 25-akpm/security/selinux/include/av_permissions.h    |    2 +
 3 files changed, 34 insertions(+), 4 deletions(-)

diff -puN security/selinux/hooks.c~selinux-01-resource-limit-control security/selinux/hooks.c
--- 25/security/selinux/hooks.c~selinux-01-resource-limit-control	Fri Jan  9 12:49:27 2004
+++ 25-akpm/security/selinux/hooks.c	Fri Jan  9 12:49:27 2004
@@ -1516,6 +1516,7 @@ static void selinux_bprm_compute_creds(s
 	u32 sid;
 	struct av_decision avd;
 	struct itimerval itimer;
+	struct rlimit *rlim, *initrlim;
 	int rc, i;
 
 	secondary_ops->bprm_compute_creds(bprm);
@@ -1586,6 +1587,26 @@ static void selinux_bprm_compute_creds(s
 			spin_unlock_irq(&current->sighand->siglock);
 		}
 
+		/* Check whether the new SID can inherit resource limits
+		   from the old SID.  If not, reset all soft limits to
+		   the lower of the current task's hard limit and the init
+		   task's soft limit.  Note that the setting of hard limits 
+		   (even to lower them) can be controlled by the setrlimit 
+		   check. The inclusion of the init task's soft limit into
+	           the computation is to avoid resetting soft limits higher
+		   than the default soft limit for cases where the default
+		   is lower than the hard limit, e.g. RLIMIT_CORE or 
+		   RLIMIT_STACK.*/
+		rc = avc_has_perm(tsec->osid, tsec->sid, SECCLASS_PROCESS,
+				  PROCESS__RLIMITINH, NULL, NULL);
+		if (rc) {
+			for (i = 0; i < RLIM_NLIMITS; i++) {
+				rlim = current->rlim + i;
+				initrlim = init_task.rlim+i;
+				rlim->rlim_cur = min(rlim->rlim_max,initrlim->rlim_cur);
+			}
+		}
+
 		/* Wake up the parent if it is waiting so that it can
 		   recheck wait permission to the new task SID. */
 		wake_up_interruptible(&current->parent->wait_chldexit);
@@ -2222,10 +2243,15 @@ static int selinux_task_setnice(struct t
 
 static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
 {
-	/* SELinux does not currently provide a process
-	   resource limit policy based on security contexts.
-	   It does control the use of the CAP_SYS_RESOURCE capability
-	   using the capable hook. */
+	struct rlimit *old_rlim = current->rlim + resource;
+
+	/* Control the ability to change the hard limit (whether
+	   lowering or raising it), so that the hard limit can
+	   later be used as a safe reset point for the soft limit
+	   upon context transitions. See selinux_bprm_compute_creds. */
+	if (old_rlim->rlim_max != new_rlim->rlim_max)
+		return task_has_perm(current, current, PROCESS__SETRLIMIT);
+
 	return 0;
 }
 
diff -puN security/selinux/include/av_permissions.h~selinux-01-resource-limit-control security/selinux/include/av_permissions.h
--- 25/security/selinux/include/av_permissions.h~selinux-01-resource-limit-control	Fri Jan  9 12:49:27 2004
+++ 25-akpm/security/selinux/include/av_permissions.h	Fri Jan  9 12:49:27 2004
@@ -451,6 +451,8 @@
 #define PROCESS__SETFSCREATE                      0x00040000UL
 #define PROCESS__NOATSECURE                       0x00080000UL
 #define PROCESS__SIGINH                           0x00100000UL
+#define PROCESS__SETRLIMIT                        0x00200000UL
+#define PROCESS__RLIMITINH                        0x00400000UL
 
 #define IPC__SETATTR                              0x00000008UL
 #define IPC__READ                                 0x00000010UL
diff -puN security/selinux/include/av_perm_to_string.h~selinux-01-resource-limit-control security/selinux/include/av_perm_to_string.h
--- 25/security/selinux/include/av_perm_to_string.h~selinux-01-resource-limit-control	Fri Jan  9 12:49:27 2004
+++ 25-akpm/security/selinux/include/av_perm_to_string.h	Fri Jan  9 12:49:27 2004
@@ -67,6 +67,8 @@ static struct av_perm_to_string av_perm_
    { SECCLASS_PROCESS, PROCESS__SETFSCREATE, "setfscreate" },
    { SECCLASS_PROCESS, PROCESS__NOATSECURE, "noatsecure" },
    { SECCLASS_PROCESS, PROCESS__SIGINH, "siginh" },
+   { SECCLASS_PROCESS, PROCESS__SETRLIMIT, "setrlimit" },
+   { SECCLASS_PROCESS, PROCESS__RLIMITINH, "rlimitinh" },
    { SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue" },
    { SECCLASS_MSG, MSG__SEND, "send" },
    { SECCLASS_MSG, MSG__RECEIVE, "receive" },

_
