selinux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v2 1/2] nspawn: add --selinux-namespace option to unshare SELinux namespace
@ 2025-10-06 13:25 Stephen Smalley
  2025-10-06 13:25 ` [RFC PATCH v2 2/2] systemd: perform SELinux initialization again in a " Stephen Smalley
  0 siblings, 1 reply; 3+ messages in thread
From: Stephen Smalley @ 2025-10-06 13:25 UTC (permalink / raw)
  To: selinux; +Cc: paul, 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>
---
v2 drops the setting of the SELINUXNS environment variable since systemd
can instead use the new is_selinux_unshared(3) API introduced by the
above libselinux patch.

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

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index ab8746c442..4c5f3eb812 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;
@@ -3502,6 +3510,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) {
 
-- 
2.51.0


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

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

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1993 bytes --]

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>
---
v2 fixes the error handling as per Christian Göttsche <cgzones@googlemail.com>
and switches from using a SELINUXNS environment variable set by nspawn
to using the new is_selinux_unshared(3) API introduced by 
https://lore.kernel.org/selinux/20251003191922.5326-2-stephen.smalley.work@gmail.com/

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

diff --git a/src/core/main.c b/src/core/main.c
index 4fc870d6c0..f33d5609bd 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 {
+                        int selinuxns = is_selinux_unshared();
+
+                        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] 3+ messages in thread

* Re: [RFC PATCH v2 2/2] systemd: perform SELinux initialization again in a SELinux namespace
  2025-10-06 13:25 ` [RFC PATCH v2 2/2] systemd: perform SELinux initialization again in a " Stephen Smalley
@ 2025-10-06 14:02   ` Stephen Smalley
  0 siblings, 0 replies; 3+ messages in thread
From: Stephen Smalley @ 2025-10-06 14:02 UTC (permalink / raw)
  To: selinux; +Cc: paul

On Mon, Oct 6, 2025 at 9:30 AM Stephen Smalley
<stephen.smalley.work@gmail.com> wrote:
>
> 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>
> ---
> v2 fixes the error handling as per Christian Göttsche <cgzones@googlemail.com>
> and switches from using a SELINUXNS environment variable set by nspawn
> to using the new is_selinux_unshared(3) API introduced by
> https://lore.kernel.org/selinux/20251003191922.5326-2-stephen.smalley.work@gmail.com/

Hmm..this doesn't appear to work, possibly due to seccomp filters set
by systemd-nspawn.
I guess that's one advantage of selinuxfs-based interfaces versus new
system calls, less likely to be blocked by existing seccomp
allow-lists. Will revert to using the SELINUXNS environment variable
for now.

>
>  src/core/main.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
>
> diff --git a/src/core/main.c b/src/core/main.c
> index 4fc870d6c0..f33d5609bd 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 {
> +                        int selinuxns = is_selinux_unshared();
> +
> +                        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	[flat|nested] 3+ messages in thread

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

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-06 13:25 [RFC PATCH v2 1/2] nspawn: add --selinux-namespace option to unshare SELinux namespace Stephen Smalley
2025-10-06 13:25 ` [RFC PATCH v2 2/2] systemd: perform SELinux initialization again in a " Stephen Smalley
2025-10-06 14:02   ` 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).