Skip to content

Commit 111767c

Browse files
thomas-cedenomicah-morton
authored andcommitted
LSM: Signal to SafeSetID when setting group IDs
For SafeSetID to properly gate set*gid() calls, it needs to know whether ns_capable() is being called from within a sys_set*gid() function or is being called from elsewhere in the kernel. This allows SafeSetID to deny CAP_SETGID to restricted groups when they are attempting to use the capability for code paths other than updating GIDs (e.g. setting up userns GID mappings). This is the identical approach to what is currently done for CAP_SETUID. NOTE: We also add signaling to SafeSetID from the setgroups() syscall, as we have future plans to restrict a process' ability to set supplementary groups in addition to what is added in this series for restricting setting of the primary group. Signed-off-by: Thomas Cedeno <thomascedeno@google.com> Signed-off-by: Micah Morton <mortonm@chromium.org>
1 parent bbf5c97 commit 111767c

3 files changed

Lines changed: 7 additions & 7 deletions

File tree

kernel/capability.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ EXPORT_SYMBOL(ns_capable_noaudit);
418418
/**
419419
* ns_capable_setid - Determine if the current task has a superior capability
420420
* in effect, while signalling that this check is being done from within a
421-
* setid syscall.
421+
* setid or setgroups syscall.
422422
* @ns: The usernamespace we want the capability in
423423
* @cap: The capability to be tested for
424424
*

kernel/groups.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ bool may_setgroups(void)
178178
{
179179
struct user_namespace *user_ns = current_user_ns();
180180

181-
return ns_capable(user_ns, CAP_SETGID) &&
181+
return ns_capable_setid(user_ns, CAP_SETGID) &&
182182
userns_may_setgroups(user_ns);
183183
}
184184

kernel/sys.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ long __sys_setregid(gid_t rgid, gid_t egid)
373373
if (rgid != (gid_t) -1) {
374374
if (gid_eq(old->gid, krgid) ||
375375
gid_eq(old->egid, krgid) ||
376-
ns_capable(old->user_ns, CAP_SETGID))
376+
ns_capable_setid(old->user_ns, CAP_SETGID))
377377
new->gid = krgid;
378378
else
379379
goto error;
@@ -382,7 +382,7 @@ long __sys_setregid(gid_t rgid, gid_t egid)
382382
if (gid_eq(old->gid, kegid) ||
383383
gid_eq(old->egid, kegid) ||
384384
gid_eq(old->sgid, kegid) ||
385-
ns_capable(old->user_ns, CAP_SETGID))
385+
ns_capable_setid(old->user_ns, CAP_SETGID))
386386
new->egid = kegid;
387387
else
388388
goto error;
@@ -432,7 +432,7 @@ long __sys_setgid(gid_t gid)
432432
old = current_cred();
433433

434434
retval = -EPERM;
435-
if (ns_capable(old->user_ns, CAP_SETGID))
435+
if (ns_capable_setid(old->user_ns, CAP_SETGID))
436436
new->gid = new->egid = new->sgid = new->fsgid = kgid;
437437
else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid))
438438
new->egid = new->fsgid = kgid;
@@ -744,7 +744,7 @@ long __sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
744744
old = current_cred();
745745

746746
retval = -EPERM;
747-
if (!ns_capable(old->user_ns, CAP_SETGID)) {
747+
if (!ns_capable_setid(old->user_ns, CAP_SETGID)) {
748748
if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
749749
!gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
750750
goto error;
@@ -871,7 +871,7 @@ long __sys_setfsgid(gid_t gid)
871871

872872
if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) ||
873873
gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) ||
874-
ns_capable(old->user_ns, CAP_SETGID)) {
874+
ns_capable_setid(old->user_ns, CAP_SETGID)) {
875875
if (!gid_eq(kgid, old->fsgid)) {
876876
new->fsgid = kgid;
877877
if (security_task_fix_setgid(new,old,LSM_SETID_FS) == 0)

0 commit comments

Comments
 (0)