lkml.org 
[lkml]   [2015]   [Jan]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.18 57/84] groups: Consolidate the setgroups permission checks
    Date
    3.18-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: "Eric W. Biederman" <ebiederm@xmission.com>

    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 | 2 +-
    include/linux/cred.h | 1 +
    kernel/groups.c | 9 ++++++++-
    kernel/uid16.c | 2 +-
    4 files changed, 11 insertions(+), 3 deletions(-)

    --- a/arch/s390/kernel/compat_linux.c
    +++ b/arch/s390/kernel/compat_linux.c
    @@ -249,7 +249,7 @@ COMPAT_SYSCALL_DEFINE2(s390_setgroups16,
    struct group_info *group_info;
    int retval;

    - if (!capable(CAP_SETGID))
    + if (!may_setgroups())
    return -EPERM;
    if ((unsigned)gidsetsize > NGROUPS_MAX)
    return -EINVAL;
    --- a/include/linux/cred.h
    +++ b/include/linux/cred.h
    @@ -68,6 +68,7 @@ extern void groups_free(struct group_inf
    extern int set_current_groups(struct group_info *);
    extern void 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) \
    --- a/kernel/groups.c
    +++ b/kernel/groups.c
    @@ -213,6 +213,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.
    @@ -223,7 +230,7 @@ SYSCALL_DEFINE2(setgroups, int, gidsetsi
    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;
    --- a/kernel/uid16.c
    +++ b/kernel/uid16.c
    @@ -176,7 +176,7 @@ SYSCALL_DEFINE2(setgroups16, int, gidset
    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;



    \
     
     \ /
      Last update: 2015-01-07 04:01    [W:4.161 / U:0.820 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site