]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
groups: Consolidate the setgroups permission checks
authorEric W. Biederman <ebiederm@xmission.com>
Fri, 5 Dec 2014 23:19:27 +0000 (17:19 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 8 Jan 2015 18:00:49 +0000 (10:00 -0800)
commit 7ff4d90b4c24a03666f296c3d4878cd39001e81e upstream.

Today there are 3 instances of setgroups and due to an oversight their
permission checking has diverged.  Add a common function so that
they may all share the same permission checking code.

This corrects the current oversight in the current permission checks
and adds a helper to avoid this in the future.

A user namespace security fix will update this new helper, shortly.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/s390/kernel/compat_linux.c
include/linux/cred.h
kernel/groups.c
kernel/uid16.c

index db02052bd137254c1c6d46314005ed4fce1a6204..5426c9eb5114cca3912bbb3d16fb11ea9fa59532 100644 (file)
@@ -245,7 +245,7 @@ asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist)
        struct group_info *group_info;
        int retval;
 
-       if (!capable(CAP_SETGID))
+       if (!may_setgroups())
                return -EPERM;
        if ((unsigned)gidsetsize > NGROUPS_MAX)
                return -EINVAL;
index 04421e82536596c5aeb7a28b35e142556c821598..6c58dd7cb9ace20c8a30a429490cac03df022fcf 100644 (file)
@@ -68,6 +68,7 @@ extern void groups_free(struct group_info *);
 extern int set_current_groups(struct group_info *);
 extern int set_groups(struct cred *, struct group_info *);
 extern int groups_search(const struct group_info *, kgid_t);
+extern bool may_setgroups(void);
 
 /* access the groups "array" with this macro */
 #define GROUP_AT(gi, i) \
index 90cf1c38c8ea8cd425f09a078e2e334db6d675cc..984bb629c68cfc1687bc2f84295016c170e7aeb0 100644 (file)
@@ -223,6 +223,13 @@ out:
        return i;
 }
 
+bool may_setgroups(void)
+{
+       struct user_namespace *user_ns = current_user_ns();
+
+       return ns_capable(user_ns, CAP_SETGID);
+}
+
 /*
  *     SMP: Our groups are copy-on-write. We can set them safely
  *     without another task interfering.
@@ -233,7 +240,7 @@ SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist)
        struct group_info *group_info;
        int retval;
 
-       if (!ns_capable(current_user_ns(), CAP_SETGID))
+       if (!may_setgroups())
                return -EPERM;
        if ((unsigned)gidsetsize > NGROUPS_MAX)
                return -EINVAL;
index 602e5bbbceff51ef47d4a22d2e3a51e34a88cfd5..d58cc4d8f0d1fa95c7ec0120cb408a9b4ad859e5 100644 (file)
@@ -176,7 +176,7 @@ SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
        struct group_info *group_info;
        int retval;
 
-       if (!ns_capable(current_user_ns(), CAP_SETGID))
+       if (!may_setgroups())
                return -EPERM;
        if ((unsigned)gidsetsize > NGROUPS_MAX)
                return -EINVAL;