]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: flush out environment block of the -a stub init process
authorLennart Poettering <lennart@poettering.net>
Tue, 6 Dec 2016 17:19:23 +0000 (18:19 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 14 Dec 2016 17:29:30 +0000 (18:29 +0100)
The container detection code in virt.c we ship checks for /proc/1/environ,
looking for "container=" in it. Let's make sure our "-a" init stub exposes that
correctly.

Without this "systemd-detect-virt" run in a "-a" container won't detect that it
is being run in a container.

src/nspawn/nspawn-stub-pid1.c
src/nspawn/nspawn-stub-pid1.h
src/nspawn/nspawn.c

index 2de87e3c63e88b17628483411f40dbbdbffcdcde..38ab37367ef7a9ddf868f75ea128995b9ffa4dd7 100644 (file)
@@ -20,6 +20,7 @@
 #include <sys/reboot.h>
 #include <sys/unistd.h>
 #include <sys/wait.h>
+#include <sys/prctl.h>
 
 #include "fd-util.h"
 #include "log.h"
 #include "time-util.h"
 #include "def.h"
 
-int stub_pid1(void) {
+static int reset_environ(const char *new_environment, size_t length) {
+        unsigned long start, end;
+
+        start = (unsigned long) new_environment;
+        end = start + length;
+
+        if (prctl(PR_SET_MM, PR_SET_MM_ENV_START, start, 0, 0) < 0)
+                return -errno;
+
+        if (prctl(PR_SET_MM, PR_SET_MM_ENV_END, end, 0, 0) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int stub_pid1(sd_id128_t uuid) {
         enum {
                 STATE_RUNNING,
                 STATE_REBOOT,
@@ -41,6 +57,11 @@ int stub_pid1(void) {
         pid_t pid;
         int r;
 
+        /* The new environment we set up, on the stack. */
+        char new_environment[] =
+                "container=systemd-nspawn\0"
+                "container_uuid=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+
         /* Implements a stub PID 1, that reaps all processes and processes a couple of standard signals. This is useful
          * for allowing arbitrary processes run in a container, and still have all zombies reaped. */
 
@@ -64,6 +85,12 @@ int stub_pid1(void) {
         close_all_fds(NULL, 0);
         log_open();
 
+        /* Flush out /proc/self/environ, so that we don't leak the environment from the host into the container. Also,
+         * set $container= and $container_uuid= so that clients in the container that query it from /proc/1/environ
+         * find them set set. */
+        sd_id128_to_string(uuid, new_environment + sizeof(new_environment) - SD_ID128_STRING_MAX);
+        reset_environ(new_environment, sizeof(new_environment));
+
         rename_process("STUBINIT");
 
         assert_se(sigemptyset(&waitmask) >= 0);
index 36c1aaf5dd9c4ef9abddb34de6575a3f489c04ff..7ca83078c06e6a5b7b5f8300606bc6d7b52d377c 100644 (file)
@@ -19,4 +19,6 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-int stub_pid1(void);
+#include "sd-id128.h"
+
+int stub_pid1(sd_id128_t uuid);
index 080bd7c31e60dfc1a7d763db10b9da14b53b206f..dcc639f15cd489dcbde307afcf34311368dd8588 100644 (file)
@@ -2278,7 +2278,7 @@ static int inner_child(
                         return log_error_errno(errno, "Failed to change to specified working directory %s: %m", arg_chdir);
 
         if (arg_start_mode == START_PID2) {
-                r = stub_pid1();
+                r = stub_pid1(arg_uuid);
                 if (r < 0)
                         return r;
         }