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
This commit is contained in:
Lennart Poettering 2020-10-02 11:59:45 +02:00
parent 781fa474d8
commit 3462d773d2
3 changed files with 17 additions and 14 deletions

View file

@ -63,16 +63,19 @@ int change_uid_gid_raw(
uid_t uid, uid_t uid,
gid_t gid, gid_t gid,
const gid_t *supplementary_gids, const gid_t *supplementary_gids,
size_t n_supplementary_gids) { size_t n_supplementary_gids,
bool chown_stdio) {
if (!uid_is_valid(uid)) if (!uid_is_valid(uid))
uid = 0; uid = 0;
if (!gid_is_valid(gid)) if (!gid_is_valid(gid))
gid = 0; gid = 0;
(void) fchown(STDIN_FILENO, uid, gid); if (chown_stdio) {
(void) fchown(STDOUT_FILENO, uid, gid); (void) fchown(STDIN_FILENO, uid, gid);
(void) fchown(STDERR_FILENO, uid, gid); (void) fchown(STDOUT_FILENO, uid, gid);
(void) fchown(STDERR_FILENO, uid, gid);
}
if (setgroups(n_supplementary_gids, supplementary_gids) < 0) if (setgroups(n_supplementary_gids, supplementary_gids) < 0)
return log_error_errno(errno, "Failed to set auxiliary groups: %m"); return log_error_errno(errno, "Failed to set auxiliary groups: %m");
@ -86,7 +89,7 @@ int change_uid_gid_raw(
return 0; 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; char *x, *u, *g, *h;
_cleanup_free_ gid_t *gids = NULL; _cleanup_free_ gid_t *gids = NULL;
_cleanup_free_ char *home = NULL, *line = NULL; _cleanup_free_ char *home = NULL, *line = NULL;
@ -99,7 +102,7 @@ int change_uid_gid(const char *user, char **_home) {
pid_t pid; pid_t pid;
int r; int r;
assert(_home); assert(ret_home);
if (!user || STR_IN_SET(user, "root", "0")) { if (!user || STR_IN_SET(user, "root", "0")) {
/* Reset everything fully to 0, just in case */ /* Reset everything fully to 0, just in case */
@ -108,7 +111,7 @@ int change_uid_gid(const char *user, char **_home) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to become root: %m"); return log_error_errno(r, "Failed to become root: %m");
*_home = NULL; *ret_home = NULL;
return 0; return 0;
} }
@ -232,12 +235,12 @@ int change_uid_gid(const char *user, char **_home) {
if (r < 0 && !IN_SET(r, -EEXIST, -ENOTDIR)) if (r < 0 && !IN_SET(r, -EEXIST, -ENOTDIR))
return log_error_errno(r, "Failed to make home directory: %m"); 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) if (r < 0)
return r; return r;
if (_home) if (ret_home)
*_home = TAKE_PTR(home); *ret_home = TAKE_PTR(home);
return 0; return 0;
} }

View file

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once #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_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, char **ret_home); int change_uid_gid(const char *user, bool chown_stdio, char **ret_home);

View file

@ -3321,9 +3321,9 @@ static int inner_child(
return log_error_errno(errno, "Failed to set PR_SET_KEEPCAPS: %m"); return log_error_errno(errno, "Failed to set PR_SET_KEEPCAPS: %m");
if (uid_is_valid(arg_uid) || gid_is_valid(arg_gid)) 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 else
r = change_uid_gid(arg_user, &home); r = change_uid_gid(arg_user, arg_console_mode != CONSOLE_PIPE, &home);
if (r < 0) if (r < 0)
return r; return r;