From 3462d773d2d98c213408b929e19b86a502f2fab6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 2 Oct 2020 11:59:45 +0200 Subject: [PATCH] nspawn: don't chown() stdin/stdout passed in when --console=pipe is used We should chown what we allocate ourselves, i.e. any pty we allocate ourselves. But for stuff we propagate, let's avoid that: we shouldn't make more changes than necessary. Fixes: #17229 --- src/nspawn/nspawn-setuid.c | 23 +++++++++++++---------- src/nspawn/nspawn-setuid.h | 4 ++-- src/nspawn/nspawn.c | 4 ++-- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/nspawn/nspawn-setuid.c b/src/nspawn/nspawn-setuid.c index fa2002d5785..62b949f58cd 100644 --- a/src/nspawn/nspawn-setuid.c +++ b/src/nspawn/nspawn-setuid.c @@ -63,16 +63,19 @@ int change_uid_gid_raw( uid_t uid, gid_t gid, const gid_t *supplementary_gids, - size_t n_supplementary_gids) { + size_t n_supplementary_gids, + bool chown_stdio) { 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 (chown_stdio) { + (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"); @@ -86,7 +89,7 @@ int change_uid_gid_raw( return 0; } -int change_uid_gid(const char *user, char **_home) { +int change_uid_gid(const char *user, bool chown_stdio, char **ret_home) { char *x, *u, *g, *h; _cleanup_free_ gid_t *gids = NULL; _cleanup_free_ char *home = NULL, *line = NULL; @@ -99,7 +102,7 @@ int change_uid_gid(const char *user, char **_home) { pid_t pid; int r; - assert(_home); + assert(ret_home); if (!user || STR_IN_SET(user, "root", "0")) { /* Reset everything fully to 0, just in case */ @@ -108,7 +111,7 @@ int change_uid_gid(const char *user, char **_home) { if (r < 0) return log_error_errno(r, "Failed to become root: %m"); - *_home = NULL; + *ret_home = NULL; return 0; } @@ -232,12 +235,12 @@ 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"); - r = change_uid_gid_raw(uid, gid, gids, n_gids); + r = change_uid_gid_raw(uid, gid, gids, n_gids, chown_stdio); if (r < 0) return r; - if (_home) - *_home = TAKE_PTR(home); + if (ret_home) + *ret_home = TAKE_PTR(home); return 0; } diff --git a/src/nspawn/nspawn-setuid.h b/src/nspawn/nspawn-setuid.h index 9a2b05ebbb1..c82d50bdf13 100644 --- a/src/nspawn/nspawn-setuid.h +++ b/src/nspawn/nspawn-setuid.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -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); +int change_uid_gid_raw(uid_t uid, gid_t gid, const gid_t *supplementary_gids, size_t n_supplementary_gids, bool chown_stdio); +int change_uid_gid(const char *user, bool chown_stdio, char **ret_home); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 36a26046641..12a04b0baed 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3321,9 +3321,9 @@ static int inner_child( return log_error_errno(errno, "Failed to set PR_SET_KEEPCAPS: %m"); if (uid_is_valid(arg_uid) || gid_is_valid(arg_gid)) - r = change_uid_gid_raw(arg_uid, arg_gid, arg_supplementary_gids, arg_n_supplementary_gids); + r = change_uid_gid_raw(arg_uid, arg_gid, arg_supplementary_gids, arg_n_supplementary_gids, arg_console_mode != CONSOLE_PIPE); else - r = change_uid_gid(arg_user, &home); + r = change_uid_gid(arg_user, arg_console_mode != CONSOLE_PIPE, &home); if (r < 0) return r;