Skip to content
This repository has been archived by the owner on Aug 14, 2023. It is now read-only.

Commit

Permalink
groups: Consolidate the setgroups permission checks
Browse files Browse the repository at this point in the history
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.

Cc: [email protected]
Signed-off-by: "Eric W. Biederman" <[email protected]>
  • Loading branch information
ebiederm committed Dec 5, 2014
1 parent 4fed655 commit 7ff4d90
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 3 deletions.
2 changes: 1 addition & 1 deletion arch/s390/kernel/compat_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ COMPAT_SYSCALL_DEFINE2(s390_setgroups16, int, gidsetsize, u16 __user *, grouplis
struct group_info *group_info;
int retval;

if (!capable(CAP_SETGID))
if (!may_setgroups())
return -EPERM;
if ((unsigned)gidsetsize > NGROUPS_MAX)
return -EINVAL;
Expand Down
1 change: 1 addition & 0 deletions include/linux/cred.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ extern void groups_free(struct group_info *);
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) \
Expand Down
9 changes: 8 additions & 1 deletion kernel/groups.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,13 @@ SYSCALL_DEFINE2(getgroups, int, gidsetsize, gid_t __user *, grouplist)
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.
Expand All @@ -223,7 +230,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;
Expand Down
2 changes: 1 addition & 1 deletion kernel/uid16.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 7ff4d90

Please sign in to comment.