selinux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v3 1/2] nspawn: add --selinux-namespace option to unshare SELinux namespace
@ 2025-10-06 14:30 Stephen Smalley
  2025-10-06 14:30 ` [RFC PATCH v3 2/2] systemd: perform SELinux initialization again in a " Stephen Smalley
  0 siblings, 1 reply; 2+ messages in thread
From: Stephen Smalley @ 2025-10-06 14:30 UTC (permalink / raw)
  To: selinux; +Cc: paul, cgzones, Stephen Smalley

RFC only, this demonstrates how to use the selinux_unshare(3) API
added to libselinux by
https://lore.kernel.org/selinux/20251003191922.5326-2-stephen.smalley.work@gmail.com/
and integrates it into systemd-nspawn to support launching containers
with their own SELinux namespace.

Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
---
v3 reverts to setting and checking the SELINUXNS environment variable
for detection of whether the SELinux namespace was unshared since
systemd-nspawn sets seccomp filters that do not allow-list the
lsm_get_self_attr(2) system call.

 src/nspawn/nspawn.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index ab8746c442..22a5070cc6 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -148,6 +148,7 @@ static char *arg_machine = NULL;     /* The name used by the host to refer to th
 static char *arg_hostname = NULL;    /* The name the payload sees by default */
 static const char *arg_selinux_context = NULL;
 static const char *arg_selinux_apifs_context = NULL;
+static bool arg_selinux_namespace = false;
 static char *arg_slice = NULL;
 static bool arg_private_network; /* initialized depending on arg_privileged in run() */
 static bool arg_read_only = false;
@@ -437,6 +438,7 @@ static int help(void) {
                "  -L --selinux-apifs-context=SECLABEL\n"
                "                            Set the SELinux security context to be used by\n"
                "                            API/tmpfs file systems in the container\n"
+               "     --selinux-namespace    Unshare SELinux namespace\n"
                "\n%3$sResources:%4$s\n"
                "     --rlimit=NAME=LIMIT    Set a resource limit for the payload\n"
                "     --oom-score-adjust=VALUE\n"
@@ -654,6 +656,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_OVERLAY,
                 ARG_OVERLAY_RO,
                 ARG_INACCESSIBLE,
+                ARG_SELINUX_NAMESPACE,
                 ARG_SHARE_SYSTEM,
                 ARG_REGISTER,
                 ARG_KEEP_UNIT,
@@ -731,6 +734,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "setenv",                 required_argument, NULL, 'E'                        },
                 { "selinux-context",        required_argument, NULL, 'Z'                        },
                 { "selinux-apifs-context",  required_argument, NULL, 'L'                        },
+                { "selinux-namespace",      no_argument,       NULL, ARG_SELINUX_NAMESPACE      },
                 { "quiet",                  no_argument,       NULL, 'q'                        },
                 { "share-system",           no_argument,       NULL, ARG_SHARE_SYSTEM           }, /* not documented */
                 { "register",               required_argument, NULL, ARG_REGISTER               },
@@ -1005,6 +1009,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_selinux_apifs_context = optarg;
                         break;
 
+                case ARG_SELINUX_NAMESPACE:
+                        arg_selinux_namespace = true;
+                        break;
+
                 case ARG_READ_ONLY:
                         arg_read_only = true;
                         arg_settings_mask |= SETTING_READ_ONLY;
@@ -3323,6 +3331,7 @@ static int inner_child(
                 NULL, /* NOTIFY_SOCKET */
                 NULL, /* CREDENTIALS_DIRECTORY */
                 NULL, /* LANG */
+                NULL, /* SELINUXNS */
                 NULL
         };
         const char *exec_target;
@@ -3502,6 +3511,12 @@ static int inner_child(
         if (r < 0)
                 return log_error_errno(r, "Failed to apply resource limit RLIMIT_%s: %m", rlimit_to_string(which_failed));
 
+#if HAVE_SELINUX
+        if (arg_selinux_namespace)
+                if (selinux_unshare() < 0)
+                        return log_error_errno(errno, "selinux_unshare() failed: %m");
+#endif
+
 #if HAVE_SECCOMP
         if (arg_seccomp) {
 
@@ -3611,6 +3626,15 @@ static int inner_child(
                 n_env++;
         }
 
+#if HAVE_SELINUX
+        if (arg_selinux_namespace) {
+                envp[n_env] = strdup("SELINUXNS=1");
+                if (!envp[n_env])
+                        return log_oom();
+                n_env++;
+        }
+#endif
+
         env_use = strv_env_merge(envp, os_release_pairs, arg_setenv);
         if (!env_use)
                 return log_oom();
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [RFC PATCH v3 2/2] systemd: perform SELinux initialization again in a SELinux namespace
  2025-10-06 14:30 [RFC PATCH v3 1/2] nspawn: add --selinux-namespace option to unshare SELinux namespace Stephen Smalley
@ 2025-10-06 14:30 ` Stephen Smalley
  0 siblings, 0 replies; 2+ messages in thread
From: Stephen Smalley @ 2025-10-06 14:30 UTC (permalink / raw)
  To: selinux; +Cc: paul, cgzones, Stephen Smalley

RFC only, this demonstrates the changes required to systemd to
perform SELinux setup and initialization when run in its own
SELinux namespace. Otherwise, by default, systemd currently skips
SELinux processing when run within a container to avoid conflicting
with the host.

Modify systemd to perform SELinux setup and initialization when
run in its own SELinux namespace.

Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
---
v3 reverts to setting and checking the SELINUXNS environment variable
for detection of whether the SELinux namespace was unshared since
systemd-nspawn sets seccomp filters that do not allow-list the
lsm_get_self_attr(2) system call.

 src/core/main.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/core/main.c b/src/core/main.c
index 4fc870d6c0..eb8075fb79 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -3124,6 +3124,22 @@ int main(int argc, char *argv[]) {
                         log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
 
                 } else {
+                        const char *selinuxns = getenv("SELINUXNS");
+
+                        if (selinuxns) {
+                                r = mac_selinux_setup(&loaded_policy);
+                                if (r < 0) {
+                                        error_message = "Failed to setup SELinux namespace support";
+                                        goto finish;
+                                }
+
+                                r = mac_selinux_init();
+                                if (r < 0) {
+                                        error_message = "Failed to initialize SELinux namespace support";
+                                        goto finish;
+                                }
+                        }
+
                         /* Running inside a container, as PID 1 */
                         log_set_target_and_open(LOG_TARGET_CONSOLE);
 
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-10-06 14:35 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-06 14:30 [RFC PATCH v3 1/2] nspawn: add --selinux-namespace option to unshare SELinux namespace Stephen Smalley
2025-10-06 14:30 ` [RFC PATCH v3 2/2] systemd: perform SELinux initialization again in a " Stephen Smalley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).