Commit d99684fd authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] selinux: Add resource limit control

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>.
parent 13a2158c
...@@ -1516,6 +1516,7 @@ static void selinux_bprm_compute_creds(struct linux_binprm *bprm) ...@@ -1516,6 +1516,7 @@ static void selinux_bprm_compute_creds(struct linux_binprm *bprm)
u32 sid; u32 sid;
struct av_decision avd; struct av_decision avd;
struct itimerval itimer; struct itimerval itimer;
struct rlimit *rlim, *initrlim;
int rc, i; int rc, i;
secondary_ops->bprm_compute_creds(bprm); secondary_ops->bprm_compute_creds(bprm);
...@@ -1586,6 +1587,26 @@ static void selinux_bprm_compute_creds(struct linux_binprm *bprm) ...@@ -1586,6 +1587,26 @@ static void selinux_bprm_compute_creds(struct linux_binprm *bprm)
spin_unlock_irq(&current->sighand->siglock); 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 /* Wake up the parent if it is waiting so that it can
recheck wait permission to the new task SID. */ recheck wait permission to the new task SID. */
wake_up_interruptible(&current->parent->wait_chldexit); wake_up_interruptible(&current->parent->wait_chldexit);
...@@ -2222,10 +2243,15 @@ static int selinux_task_setnice(struct task_struct *p, int nice) ...@@ -2222,10 +2243,15 @@ static int selinux_task_setnice(struct task_struct *p, int nice)
static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
{ {
/* SELinux does not currently provide a process struct rlimit *old_rlim = current->rlim + resource;
resource limit policy based on security contexts.
It does control the use of the CAP_SYS_RESOURCE capability /* Control the ability to change the hard limit (whether
using the capable hook. */ 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; return 0;
} }
......
...@@ -67,6 +67,8 @@ static struct av_perm_to_string av_perm_to_string[] = { ...@@ -67,6 +67,8 @@ static struct av_perm_to_string av_perm_to_string[] = {
{ SECCLASS_PROCESS, PROCESS__SETFSCREATE, "setfscreate" }, { SECCLASS_PROCESS, PROCESS__SETFSCREATE, "setfscreate" },
{ SECCLASS_PROCESS, PROCESS__NOATSECURE, "noatsecure" }, { SECCLASS_PROCESS, PROCESS__NOATSECURE, "noatsecure" },
{ SECCLASS_PROCESS, PROCESS__SIGINH, "siginh" }, { SECCLASS_PROCESS, PROCESS__SIGINH, "siginh" },
{ SECCLASS_PROCESS, PROCESS__SETRLIMIT, "setrlimit" },
{ SECCLASS_PROCESS, PROCESS__RLIMITINH, "rlimitinh" },
{ SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue" }, { SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue" },
{ SECCLASS_MSG, MSG__SEND, "send" }, { SECCLASS_MSG, MSG__SEND, "send" },
{ SECCLASS_MSG, MSG__RECEIVE, "receive" }, { SECCLASS_MSG, MSG__RECEIVE, "receive" },
......
...@@ -451,6 +451,8 @@ ...@@ -451,6 +451,8 @@
#define PROCESS__SETFSCREATE 0x00040000UL #define PROCESS__SETFSCREATE 0x00040000UL
#define PROCESS__NOATSECURE 0x00080000UL #define PROCESS__NOATSECURE 0x00080000UL
#define PROCESS__SIGINH 0x00100000UL #define PROCESS__SIGINH 0x00100000UL
#define PROCESS__SETRLIMIT 0x00200000UL
#define PROCESS__RLIMITINH 0x00400000UL
#define IPC__SETATTR 0x00000008UL #define IPC__SETATTR 0x00000008UL
#define IPC__READ 0x00000010UL #define IPC__READ 0x00000010UL
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment