mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 06:04:23 +08:00
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>
This commit is contained in:
parent
bbf5c97901
commit
111767c1d8
@ -418,7 +418,7 @@ EXPORT_SYMBOL(ns_capable_noaudit);
|
||||
/**
|
||||
* ns_capable_setid - Determine if the current task has a superior capability
|
||||
* in effect, while signalling that this check is being done from within a
|
||||
* setid syscall.
|
||||
* setid or setgroups syscall.
|
||||
* @ns: The usernamespace we want the capability in
|
||||
* @cap: The capability to be tested for
|
||||
*
|
||||
|
@ -178,7 +178,7 @@ bool may_setgroups(void)
|
||||
{
|
||||
struct user_namespace *user_ns = current_user_ns();
|
||||
|
||||
return ns_capable(user_ns, CAP_SETGID) &&
|
||||
return ns_capable_setid(user_ns, CAP_SETGID) &&
|
||||
userns_may_setgroups(user_ns);
|
||||
}
|
||||
|
||||
|
10
kernel/sys.c
10
kernel/sys.c
@ -373,7 +373,7 @@ long __sys_setregid(gid_t rgid, gid_t egid)
|
||||
if (rgid != (gid_t) -1) {
|
||||
if (gid_eq(old->gid, krgid) ||
|
||||
gid_eq(old->egid, krgid) ||
|
||||
ns_capable(old->user_ns, CAP_SETGID))
|
||||
ns_capable_setid(old->user_ns, CAP_SETGID))
|
||||
new->gid = krgid;
|
||||
else
|
||||
goto error;
|
||||
@ -382,7 +382,7 @@ long __sys_setregid(gid_t rgid, gid_t egid)
|
||||
if (gid_eq(old->gid, kegid) ||
|
||||
gid_eq(old->egid, kegid) ||
|
||||
gid_eq(old->sgid, kegid) ||
|
||||
ns_capable(old->user_ns, CAP_SETGID))
|
||||
ns_capable_setid(old->user_ns, CAP_SETGID))
|
||||
new->egid = kegid;
|
||||
else
|
||||
goto error;
|
||||
@ -432,7 +432,7 @@ long __sys_setgid(gid_t gid)
|
||||
old = current_cred();
|
||||
|
||||
retval = -EPERM;
|
||||
if (ns_capable(old->user_ns, CAP_SETGID))
|
||||
if (ns_capable_setid(old->user_ns, CAP_SETGID))
|
||||
new->gid = new->egid = new->sgid = new->fsgid = kgid;
|
||||
else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid))
|
||||
new->egid = new->fsgid = kgid;
|
||||
@ -744,7 +744,7 @@ long __sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
|
||||
old = current_cred();
|
||||
|
||||
retval = -EPERM;
|
||||
if (!ns_capable(old->user_ns, CAP_SETGID)) {
|
||||
if (!ns_capable_setid(old->user_ns, CAP_SETGID)) {
|
||||
if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
|
||||
!gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
|
||||
goto error;
|
||||
@ -871,7 +871,7 @@ long __sys_setfsgid(gid_t gid)
|
||||
|
||||
if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) ||
|
||||
gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) ||
|
||||
ns_capable(old->user_ns, CAP_SETGID)) {
|
||||
ns_capable_setid(old->user_ns, CAP_SETGID)) {
|
||||
if (!gid_eq(kgid, old->fsgid)) {
|
||||
new->fsgid = kgid;
|
||||
if (security_task_fix_setgid(new,old,LSM_SETID_FS) == 0)
|
||||
|
Loading…
Reference in New Issue
Block a user