diff options
author | Eric Paris <eparis@redhat.com> | 2013-07-03 18:08:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 19:08:03 -0400 |
commit | b57922b6c76c3ee401bb32fd3f298409dd6e6a53 (patch) | |
tree | f9c8509215a9e5333accfa80f4e97bb0cd068209 | |
parent | 30bc30df102b2d0c003d93477e04b97e6c528573 (diff) |
fork: reorder permissions when violating number of processes limits
When a task is attempting to violate the RLIMIT_NPROC limit we have a
check to see if the task is sufficiently priviledged. The check first
looks at CAP_SYS_ADMIN, then CAP_SYS_RESOURCE, then if the task is uid=0.
A result is that tasks which are allowed by the uid=0 check are first
checked against the security subsystem. This results in the security
subsystem auditting a denial for sys_admin and sys_resource and then the
task passing the uid=0 check.
This patch rearranges the code to first check uid=0, since if we pass that
we shouldn't hit the security system at all. We then check sys_resource,
since it is the smallest capability which will solve the problem. Lastly
we check the fallback everything cap_sysadmin. We don't want to give this
capability many places since it is so powerful.
This will eliminate many of the false positive/needless denial messages we
get when a root task tries to violate the nproc limit. (note that
kthreads count against root, so on a sufficiently large machine we can
actually get past the default limits before any userspace tasks are
launched.)
Signed-off-by: Eric Paris <eparis@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | kernel/fork.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 987b28a1f01b..09dbda38a54b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1199,8 +1199,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1199 | retval = -EAGAIN; | 1199 | retval = -EAGAIN; |
1200 | if (atomic_read(&p->real_cred->user->processes) >= | 1200 | if (atomic_read(&p->real_cred->user->processes) >= |
1201 | task_rlimit(p, RLIMIT_NPROC)) { | 1201 | task_rlimit(p, RLIMIT_NPROC)) { |
1202 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && | 1202 | if (p->real_cred->user != INIT_USER && |
1203 | p->real_cred->user != INIT_USER) | 1203 | !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) |
1204 | goto bad_fork_free; | 1204 | goto bad_fork_free; |
1205 | } | 1205 | } |
1206 | current->flags &= ~PF_NPROC_EXCEEDED; | 1206 | current->flags &= ~PF_NPROC_EXCEEDED; |