]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: don't chown() stdin/stdout passed in when --console=pipe is used 17233/head
authorLennart Poettering <lennart@poettering.net>
Fri, 2 Oct 2020 09:59:45 +0000 (11:59 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 2 Oct 2020 10:05:08 +0000 (12:05 +0200)
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
src/nspawn/nspawn-setuid.h
src/nspawn/nspawn.c

index fa2002d5785adfd949930f6dd71d75c528c1bfa5..62b949f58cd2250ae16c4a4fe002fe94a3ad93e6 100644 (file)
@@ -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;
 }
index 9a2b05ebbb15457e430427faf6e85251f7aec109..c82d50bdf131ebe805a8a2ad699a0781c7597b30 100644 (file)
@@ -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);
index 36a26046641195fb8574f964e2eccb5ca626110d..12a04b0baeda12cc83d8e0188f727d8bd00cc25b 100644 (file)
@@ -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;