Zbigniew Jędrzejewski-Szmek 35bb94
From aad46f8f761dfe93954ebba2cd764c4530337083 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 35bb94
From: Michal Sekletar <msekletar@users.noreply.github.com>
Zbigniew Jędrzejewski-Szmek 35bb94
Date: Tue, 10 Oct 2017 09:46:13 +0200
Zbigniew Jędrzejewski-Szmek 35bb94
Subject: [PATCH] namespace: fall back gracefully when kernel doesn't support
Zbigniew Jędrzejewski-Szmek 35bb94
 network namespaces (#7024)
Zbigniew Jędrzejewski-Szmek 35bb94
Zbigniew Jędrzejewski-Szmek 35bb94
(cherry picked from commit 6e2d7c4f131edb19255842cdd4dc199cf8adb5ab)
Zbigniew Jędrzejewski-Szmek 35bb94
---
Zbigniew Jędrzejewski-Szmek 35bb94
 TODO                 |  3 ---
Zbigniew Jędrzejewski-Szmek 35bb94
 src/core/execute.c   | 13 ++++++++-----
Zbigniew Jędrzejewski-Szmek 35bb94
 src/core/namespace.c | 24 ++++++++++++++++++++++++
Zbigniew Jędrzejewski-Szmek 35bb94
 src/core/namespace.h | 17 +++++++++++++++++
Zbigniew Jędrzejewski-Szmek 35bb94
 4 files changed, 49 insertions(+), 8 deletions(-)
Zbigniew Jędrzejewski-Szmek 35bb94
Zbigniew Jędrzejewski-Szmek 35bb94
diff --git a/TODO b/TODO
Zbigniew Jędrzejewski-Szmek 35bb94
index 81f009918c..020bdae9c8 100644
Zbigniew Jędrzejewski-Szmek 35bb94
--- a/TODO
Zbigniew Jędrzejewski-Szmek 35bb94
+++ b/TODO
Zbigniew Jędrzejewski-Szmek 35bb94
@@ -115,9 +115,6 @@ Features:
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
 * maybe introduce gpt auto discovery for /var/tmp?
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
-* fix PrivateNetwork= so that we fall back gracefully on kernels lacking
Zbigniew Jędrzejewski-Szmek 35bb94
-  namespacing support (similar for the other namespacing options)
Zbigniew Jędrzejewski-Szmek 35bb94
-
Zbigniew Jędrzejewski-Szmek 35bb94
 * maybe add gpt-partition-based user management: each user gets his own
Zbigniew Jędrzejewski-Szmek 35bb94
   LUKS-encrypted GPT partition with a new GPT type. A small nss module
Zbigniew Jędrzejewski-Szmek 35bb94
   enumerates users via udev partition enumeration. UIDs are assigned in a fixed
Zbigniew Jędrzejewski-Szmek 35bb94
diff --git a/src/core/execute.c b/src/core/execute.c
Zbigniew Jędrzejewski-Szmek 35bb94
index 2453f84fbd..ef95a75e75 100644
Zbigniew Jędrzejewski-Szmek 35bb94
--- a/src/core/execute.c
Zbigniew Jędrzejewski-Szmek 35bb94
+++ b/src/core/execute.c
Zbigniew Jędrzejewski-Szmek 35bb94
@@ -3070,11 +3070,14 @@ static int exec_child(
Zbigniew Jędrzejewski-Szmek 35bb94
         }
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
         if (context->private_network && runtime && runtime->netns_storage_socket[0] >= 0) {
Zbigniew Jędrzejewski-Szmek 35bb94
-                r = setup_netns(runtime->netns_storage_socket);
Zbigniew Jędrzejewski-Szmek 35bb94
-                if (r < 0) {
Zbigniew Jędrzejewski-Szmek 35bb94
-                        *exit_status = EXIT_NETWORK;
Zbigniew Jędrzejewski-Szmek 35bb94
-                        return log_unit_error_errno(unit, r, "Failed to set up network namespacing: %m");
Zbigniew Jędrzejewski-Szmek 35bb94
-                }
Zbigniew Jędrzejewski-Szmek 35bb94
+                if (ns_type_supported(NAMESPACE_NET)) {
Zbigniew Jędrzejewski-Szmek 35bb94
+                        r = setup_netns(runtime->netns_storage_socket);
Zbigniew Jędrzejewski-Szmek 35bb94
+                        if (r < 0) {
Zbigniew Jędrzejewski-Szmek 35bb94
+                                *exit_status = EXIT_NETWORK;
Zbigniew Jędrzejewski-Szmek 35bb94
+                                return log_unit_error_errno(unit, r, "Failed to set up network namespacing: %m");
Zbigniew Jędrzejewski-Szmek 35bb94
+                        }
Zbigniew Jędrzejewski-Szmek 35bb94
+                } else
Zbigniew Jędrzejewski-Szmek 35bb94
+                        log_unit_warning(unit, "PrivateNetwork=yes is configured, but the kernel does not support network namespaces, ignoring.");
Zbigniew Jędrzejewski-Szmek 35bb94
         }
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
         needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime);
Zbigniew Jędrzejewski-Szmek 35bb94
diff --git a/src/core/namespace.c b/src/core/namespace.c
Zbigniew Jędrzejewski-Szmek 35bb94
index 6d74b8da67..df32d666bf 100644
Zbigniew Jędrzejewski-Szmek 35bb94
--- a/src/core/namespace.c
Zbigniew Jędrzejewski-Szmek 35bb94
+++ b/src/core/namespace.c
Zbigniew Jędrzejewski-Szmek 35bb94
@@ -1428,6 +1428,18 @@ fail:
Zbigniew Jędrzejewski-Szmek 35bb94
         return r;
Zbigniew Jędrzejewski-Szmek 35bb94
 }
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
+bool ns_type_supported(NamespaceType type) {
Zbigniew Jędrzejewski-Szmek 35bb94
+        const char *t, *ns_proc;
Zbigniew Jędrzejewski-Szmek 35bb94
+
Zbigniew Jędrzejewski-Szmek 35bb94
+        if (type <= _NAMESPACE_TYPE_INVALID || type >= _NAMESPACE_TYPE_MAX)
Zbigniew Jędrzejewski-Szmek 35bb94
+                return false;
Zbigniew Jędrzejewski-Szmek 35bb94
+
Zbigniew Jędrzejewski-Szmek 35bb94
+        t = namespace_type_to_string(type);
Zbigniew Jędrzejewski-Szmek 35bb94
+        ns_proc = strjoina("/proc/self/ns/", t);
Zbigniew Jędrzejewski-Szmek 35bb94
+
Zbigniew Jędrzejewski-Szmek 35bb94
+        return access(ns_proc, F_OK) == 0;
Zbigniew Jędrzejewski-Szmek 35bb94
+}
Zbigniew Jędrzejewski-Szmek 35bb94
+
Zbigniew Jędrzejewski-Szmek 35bb94
 static const char *const protect_home_table[_PROTECT_HOME_MAX] = {
Zbigniew Jędrzejewski-Szmek 35bb94
         [PROTECT_HOME_NO] = "no",
Zbigniew Jędrzejewski-Szmek 35bb94
         [PROTECT_HOME_YES] = "yes",
Zbigniew Jędrzejewski-Szmek 35bb94
@@ -1444,3 +1456,15 @@ static const char *const protect_system_table[_PROTECT_SYSTEM_MAX] = {
Zbigniew Jędrzejewski-Szmek 35bb94
 };
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
 DEFINE_STRING_TABLE_LOOKUP(protect_system, ProtectSystem);
Zbigniew Jędrzejewski-Szmek 35bb94
+
Zbigniew Jędrzejewski-Szmek 35bb94
+static const char* const namespace_type_table[] = {
Zbigniew Jędrzejewski-Szmek 35bb94
+        [NAMESPACE_MOUNT] = "mnt",
Zbigniew Jędrzejewski-Szmek 35bb94
+        [NAMESPACE_CGROUP] = "cgroup",
Zbigniew Jędrzejewski-Szmek 35bb94
+        [NAMESPACE_UTS] = "uts",
Zbigniew Jędrzejewski-Szmek 35bb94
+        [NAMESPACE_IPC] = "ipc",
Zbigniew Jędrzejewski-Szmek 35bb94
+        [NAMESPACE_USER] = "user",
Zbigniew Jędrzejewski-Szmek 35bb94
+        [NAMESPACE_PID] = "pid",
Zbigniew Jędrzejewski-Szmek 35bb94
+        [NAMESPACE_NET] = "net",
Zbigniew Jędrzejewski-Szmek 35bb94
+};
Zbigniew Jędrzejewski-Szmek 35bb94
+
Zbigniew Jędrzejewski-Szmek 35bb94
+DEFINE_STRING_TABLE_LOOKUP(namespace_type, NamespaceType);
Zbigniew Jędrzejewski-Szmek 35bb94
diff --git a/src/core/namespace.h b/src/core/namespace.h
Zbigniew Jędrzejewski-Szmek 35bb94
index da8d85dbc5..b244c8f337 100644
Zbigniew Jędrzejewski-Szmek 35bb94
--- a/src/core/namespace.h
Zbigniew Jędrzejewski-Szmek 35bb94
+++ b/src/core/namespace.h
Zbigniew Jędrzejewski-Szmek 35bb94
@@ -36,6 +36,18 @@ typedef enum ProtectHome {
Zbigniew Jędrzejewski-Szmek 35bb94
         _PROTECT_HOME_INVALID = -1
Zbigniew Jędrzejewski-Szmek 35bb94
 } ProtectHome;
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
+typedef enum NamespaceType {
Zbigniew Jędrzejewski-Szmek 35bb94
+        NAMESPACE_MOUNT,
Zbigniew Jędrzejewski-Szmek 35bb94
+        NAMESPACE_CGROUP,
Zbigniew Jędrzejewski-Szmek 35bb94
+        NAMESPACE_UTS,
Zbigniew Jędrzejewski-Szmek 35bb94
+        NAMESPACE_IPC,
Zbigniew Jędrzejewski-Szmek 35bb94
+        NAMESPACE_USER,
Zbigniew Jędrzejewski-Szmek 35bb94
+        NAMESPACE_PID,
Zbigniew Jędrzejewski-Szmek 35bb94
+        NAMESPACE_NET,
Zbigniew Jędrzejewski-Szmek 35bb94
+        _NAMESPACE_TYPE_MAX,
Zbigniew Jędrzejewski-Szmek 35bb94
+        _NAMESPACE_TYPE_INVALID = -1,
Zbigniew Jędrzejewski-Szmek 35bb94
+} NamespaceType;
Zbigniew Jędrzejewski-Szmek 35bb94
+
Zbigniew Jędrzejewski-Szmek 35bb94
 typedef enum ProtectSystem {
Zbigniew Jędrzejewski-Szmek 35bb94
         PROTECT_SYSTEM_NO,
Zbigniew Jędrzejewski-Szmek 35bb94
         PROTECT_SYSTEM_YES,
Zbigniew Jędrzejewski-Szmek 35bb94
@@ -94,3 +106,8 @@ ProtectSystem protect_system_from_string(const char *s) _pure_;
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
 void bind_mount_free_many(BindMount *b, unsigned n);
Zbigniew Jędrzejewski-Szmek 35bb94
 int bind_mount_add(BindMount **b, unsigned *n, const BindMount *item);
Zbigniew Jędrzejewski-Szmek 35bb94
+
Zbigniew Jędrzejewski-Szmek 35bb94
+const char* namespace_type_to_string(NamespaceType t) _const_;
Zbigniew Jędrzejewski-Szmek 35bb94
+NamespaceType namespace_type_from_string(const char *s) _pure_;
Zbigniew Jędrzejewski-Szmek 35bb94
+
Zbigniew Jędrzejewski-Szmek 35bb94
+bool ns_type_supported(NamespaceType type);