]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
fork: reorder permissions when violating number of processes limits
authorEric Paris <eparis@redhat.com>
Thu, 27 Jun 2013 23:53:55 +0000 (09:53 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Fri, 28 Jun 2013 06:38:57 +0000 (16:38 +1000)
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>
kernel/fork.c

index 6fcc2e24561ea8e5a828bd49a8aaad16b1d1a9ca..7fe4203cfe683f9e9fdb831caf9afaed2f956423 100644 (file)
@@ -1195,8 +1195,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        retval = -EAGAIN;
        if (atomic_read(&p->real_cred->user->processes) >=
                        task_rlimit(p, RLIMIT_NPROC)) {
-               if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
-                   p->real_cred->user != INIT_USER)
+               if (p->real_cred->user != INIT_USER &&
+                   !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN))
                        goto bad_fork_free;
        }
        current->flags &= ~PF_NPROC_EXCEEDED;