diff options
author | Tiago Natel <t.nateldemoura@f5.com> | 2019-12-06 16:52:50 +0000 |
---|---|---|
committer | Tiago Natel <t.nateldemoura@f5.com> | 2019-12-06 16:52:50 +0000 |
commit | 411daeaa532c47328ab901a7ba9ea5dcd876be06 (patch) | |
tree | 90774780cf42278a5cb148992604e8fdb864f54b /src/nxt_credential.c | |
parent | ed2492a66afdf578d1e4f99dc098ab685607b3ba (diff) | |
download | unit-411daeaa532c47328ab901a7ba9ea5dcd876be06.tar.gz unit-411daeaa532c47328ab901a7ba9ea5dcd876be06.tar.bz2 |
Isolation: allowed the use of credentials with unpriv userns.
The setuid/setgid syscalls requires root capabilities but if the kernel
supports unprivileged user namespace then the child process has the full
set of capabilities in the new namespace, then we can allow setting "user"
and "group" in such cases (this is a common security use case).
Tests were added to ensure user gets meaningful error messages for
uid/gid mapping misconfigurations.
Diffstat (limited to '')
-rw-r--r-- | src/nxt_credential.c | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/src/nxt_credential.c b/src/nxt_credential.c index 9f275b7d..168db9cf 100644 --- a/src/nxt_credential.c +++ b/src/nxt_credential.c @@ -280,61 +280,69 @@ free: nxt_int_t -nxt_credential_set(nxt_task_t *task, nxt_credential_t *uc) +nxt_credential_setuid(nxt_task_t *task, nxt_credential_t *uc) { - nxt_debug(task, "user cred set: \"%s\" uid:%d base gid:%d", - uc->user, uc->uid, uc->base_gid); + nxt_debug(task, "user cred set: \"%s\" uid:%d", uc->user, uc->uid); - if (setgid(uc->base_gid) != 0) { + if (setuid(uc->uid) != 0) { #if (NXT_HAVE_CLONE) if (nxt_errno == EINVAL) { - nxt_log(task, NXT_LOG_ERR, "The gid %d isn't valid in the " - "application namespace.", uc->base_gid); + nxt_log(task, NXT_LOG_ERR, "The uid %d (user \"%s\") isn't " + "valid in the application namespace.", uc->uid, uc->user); return NXT_ERROR; } #endif - nxt_alert(task, "setgid(%d) failed %E", uc->base_gid, nxt_errno); + nxt_alert(task, "setuid(%d) failed %E", uc->uid, nxt_errno); return NXT_ERROR; } - if (uc->gids != NULL) { - if (setgroups(uc->ngroups, uc->gids) != 0) { + return NXT_OK; +} -#if (NXT_HAVE_CLONE) - if (nxt_errno == EINVAL) { - nxt_log(task, NXT_LOG_ERR, "The user \"%s\" (uid: %d) has " - "supplementary group ids not valid in the application " - "namespace.", uc->user, uc->uid); - return NXT_ERROR; - } -#endif - nxt_alert(task, "setgroups(%i) failed %E", uc->ngroups, nxt_errno); - return NXT_ERROR; - } +nxt_int_t +nxt_credential_setgids(nxt_task_t *task, nxt_credential_t *uc) +{ + nxt_runtime_t *rt; - } else { - /* MacOSX fallback. */ - if (initgroups(uc->user, uc->base_gid) != 0) { - nxt_alert(task, "initgroups(%s, %d) failed %E", - uc->user, uc->base_gid, nxt_errno); + nxt_debug(task, "user cred set gids: base gid:%d, ngroups: %d", + uc->base_gid, uc->ngroups); + + rt = task->thread->runtime; + + if (setgid(uc->base_gid) != 0) { + +#if (NXT_HAVE_CLONE) + if (nxt_errno == EINVAL) { + nxt_log(task, NXT_LOG_ERR, "The gid %d isn't valid in the " + "application namespace.", uc->base_gid); return NXT_ERROR; } +#endif + + nxt_alert(task, "setgid(%d) failed %E", uc->base_gid, nxt_errno); + return NXT_ERROR; } - if (setuid(uc->uid) != 0) { + if (!rt->capabilities.setid) { + return NXT_OK; + } + + if (nxt_slow_path(uc->ngroups > 0 + && setgroups(uc->ngroups, uc->gids) != 0)) { #if (NXT_HAVE_CLONE) if (nxt_errno == EINVAL) { - nxt_log(task, NXT_LOG_ERR, "The uid %d (user \"%s\") isn't " - "valid in the application namespace.", uc->uid, uc->user); + nxt_log(task, NXT_LOG_ERR, "The user \"%s\" (uid: %d) has " + "supplementary group ids not valid in the application " + "namespace.", uc->user, uc->uid); return NXT_ERROR; } #endif - nxt_alert(task, "setuid(%d) failed %E", uc->uid, nxt_errno); + nxt_alert(task, "setgroups(%i) failed %E", uc->ngroups, nxt_errno); return NXT_ERROR; } |