From: Lennart Poettering Date: Wed, 6 Mar 2019 10:54:54 +0000 (+0100) Subject: nspawn: refactor setuid code a bit X-Git-Tag: v242-rc1~99^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=61b4443361ecd8f80c1eabc3d6675394a1835dde;p=thirdparty%2Fsystemd.git nspawn: refactor setuid code a bit Let's separate out the raw uid_t/gid_t handling from the username handling. This is useful later on. Also, let's use the right gid_t type for group types wherever appropriate. --- diff --git a/src/nspawn/nspawn-setuid.c b/src/nspawn/nspawn-setuid.c index 0026e4e3fc7..da419f4c71b 100644 --- a/src/nspawn/nspawn-setuid.c +++ b/src/nspawn/nspawn-setuid.c @@ -59,14 +59,41 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) { return pipe_fds[0]; } +int change_uid_gid_raw( + uid_t uid, + gid_t gid, + const gid_t *supplementary_gids, + size_t n_supplementary_gids) { + + if (!uid_is_valid(uid)) + uid = 0; + if (!gid_is_valid(gid)) + gid = 0; + + (void) fchown(STDIN_FILENO, uid, gid); + (void) fchown(STDOUT_FILENO, uid, gid); + (void) fchown(STDERR_FILENO, uid, gid); + + if (setgroups(n_supplementary_gids, supplementary_gids) < 0) + return log_error_errno(errno, "Failed to set auxiliary groups: %m"); + + if (setresgid(gid, gid, gid) < 0) + return log_error_errno(errno, "setresgid() failed: %m"); + + if (setresuid(uid, uid, uid) < 0) + return log_error_errno(errno, "setresuid() failed: %m"); + + return 0; +} + int change_uid_gid(const char *user, char **_home) { char *x, *u, *g, *h; const char *word, *state; - _cleanup_free_ uid_t *uids = NULL; + _cleanup_free_ gid_t *gids = NULL; _cleanup_free_ char *home = NULL, *line = NULL; _cleanup_fclose_ FILE *f = NULL; _cleanup_close_ int fd = -1; - unsigned n_uids = 0; + unsigned n_gids = 0; size_t sz = 0, l; uid_t uid; gid_t gid; @@ -189,10 +216,10 @@ int change_uid_gid(const char *user, char **_home) { memcpy(c, word, l); c[l] = 0; - if (!GREEDY_REALLOC(uids, sz, n_uids+1)) + if (!GREEDY_REALLOC(gids, sz, n_gids+1)) return log_oom(); - r = parse_uid(c, &uids[n_uids++]); + r = parse_gid(c, &gids[n_gids++]); if (r < 0) return log_error_errno(r, "Failed to parse group data from getent: %m"); } @@ -205,18 +232,9 @@ int change_uid_gid(const char *user, char **_home) { if (r < 0 && !IN_SET(r, -EEXIST, -ENOTDIR)) return log_error_errno(r, "Failed to make home directory: %m"); - (void) fchown(STDIN_FILENO, uid, gid); - (void) fchown(STDOUT_FILENO, uid, gid); - (void) fchown(STDERR_FILENO, uid, gid); - - if (setgroups(n_uids, uids) < 0) - return log_error_errno(errno, "Failed to set auxiliary groups: %m"); - - if (setresgid(gid, gid, gid) < 0) - return log_error_errno(errno, "setresgid() failed: %m"); - - if (setresuid(uid, uid, uid) < 0) - return log_error_errno(errno, "setresuid() failed: %m"); + r = change_uid_gid_raw(uid, gid, gids, n_gids); + if (r < 0) + return r; if (_home) *_home = TAKE_PTR(home); diff --git a/src/nspawn/nspawn-setuid.h b/src/nspawn/nspawn-setuid.h index 0ae47cb6b31..9a2b05ebbb1 100644 --- a/src/nspawn/nspawn-setuid.h +++ b/src/nspawn/nspawn-setuid.h @@ -1,4 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -int change_uid_gid(const char *user, char **ret); +int change_uid_gid_raw(uid_t uid, gid_t gid, const gid_t *supplementary_gids, size_t n_supplementary_gids); +int change_uid_gid(const char *user, char **ret_home);