b11b5f
From 3f90090e70a5fa81bced17792fe08d9c46324da9 Mon Sep 17 00:00:00 2001
b11b5f
From: "Ted X. Toth" <txtoth@flycast.org>
b11b5f
Date: Thu, 13 Oct 2022 12:58:26 -0700
b11b5f
Subject: [PATCH] manager: use target process context to set socket context
b11b5f
b11b5f
Use target process context to set socket context when using SELinuxContextFromNet
b11b5f
not systemd's context. Currently when using the SELinuxContextFromNet option for
b11b5f
a socket activated services, systemd calls getcon_raw which returns init_t and
b11b5f
uses the resulting context to compute the context to be passed to the
b11b5f
setsockcreatecon call. A socket of type init_t is created and listened on and
b11b5f
this means that SELinux policy cannot be written to control which processes
b11b5f
(SELinux types) can connect to the socket since the ref policy allows all
b11b5f
'types' to connect to sockets of the type init_t. When security accessors see
b11b5f
that any process can connect to a socket this raises serious concerns. I have
b11b5f
spoken with SELinux contributors in person and on the mailing list and the
b11b5f
consensus is that the best solution is to use the target executables context
b11b5f
when computing the sockets context in all cases.
b11b5f
b11b5f
[zjs review/comment:
b11b5f
b11b5f
This removes the branch that was added in 16115b0a7b7cdf08fb38084d857d572d8a9088dc.
b11b5f
16115b0a7b7cdf08fb38084d857d572d8a9088dc did two things: it had the branch here
b11b5f
in 'socket_determine_selinux_label()' and a code in 'exec_child()' to call
b11b5f
'label_get_child_mls_label(socket_fd, command->path, &label)'.
b11b5f
b11b5f
Before this patch, the flow was:
b11b5f
'''
b11b5f
mac_selinux_get_child_mls_label:
b11b5f
  peercon = getpeercon_raw(socket_fd);
b11b5f
  if (!exec_label)
b11b5f
     exec_label = getfilecon_raw(exe);
b11b5f
b11b5f
socket_open_fds:
b11b5f
  if (params->selinux_context_net)                 #
b11b5f
     label = mac_selinux_get_our_label();          #  this part is removed
b11b5f
  else                                             #
b11b5f
     label = mac_selinux_get_create_label_from_exe(path);
b11b5f
  socket_address_listen_in_cgroup(s, &p->address, label);
b11b5f
b11b5f
exec_child():
b11b5f
   exec_context = mac_selinux_get_child_mls_label(fd, executable, context->selinux_context);
b11b5f
   setexeccon(exec_context);
b11b5f
'''
b11b5f
]
b11b5f
b11b5f
(cherry picked from commit 29dbc62d74f7b7881dc3136e68e03a03ea055b36)
b11b5f
b11b5f
Resolves: #2136738
b11b5f
---
b11b5f
 src/core/socket.c | 58 ++++++++++++++++++++---------------------------
b11b5f
 1 file changed, 24 insertions(+), 34 deletions(-)
b11b5f
b11b5f
diff --git a/src/core/socket.c b/src/core/socket.c
b11b5f
index d1ca0a07c5..8aa5463b25 100644
b11b5f
--- a/src/core/socket.c
b11b5f
+++ b/src/core/socket.c
b11b5f
@@ -1434,47 +1434,37 @@ static int socket_determine_selinux_label(Socket *s, char **ret) {
b11b5f
         assert(s);
b11b5f
         assert(ret);
b11b5f
 
b11b5f
-        if (s->selinux_context_from_net) {
b11b5f
-                /* If this is requested, get label from the network label */
b11b5f
-
b11b5f
-                r = mac_selinux_get_our_label(ret);
b11b5f
-                if (r == -EOPNOTSUPP)
b11b5f
-                        goto no_label;
b11b5f
-
b11b5f
-        } else {
b11b5f
-                /* Otherwise, get it from the executable we are about to start */
b11b5f
-                r = socket_instantiate_service(s);
b11b5f
-                if (r < 0)
b11b5f
-                        return r;
b11b5f
+        r = socket_instantiate_service(s);
b11b5f
+        if (r < 0)
b11b5f
+                return r;
b11b5f
 
b11b5f
-                if (!UNIT_ISSET(s->service))
b11b5f
-                        goto no_label;
b11b5f
-                service = SERVICE(UNIT_DEREF(s->service));
b11b5f
+        if (!UNIT_ISSET(s->service))
b11b5f
+                goto no_label;
b11b5f
+        service = SERVICE(UNIT_DEREF(s->service));
b11b5f
 
b11b5f
-                exec_context = service->exec_context.selinux_context;
b11b5f
-                if (exec_context) {
b11b5f
-                        char *con;
b11b5f
+        exec_context = service->exec_context.selinux_context;
b11b5f
+        if (exec_context) {
b11b5f
+                char *con;
b11b5f
 
b11b5f
-                        con = strdup(exec_context);
b11b5f
-                        if (!con)
b11b5f
-                                return -ENOMEM;
b11b5f
+                con = strdup(exec_context);
b11b5f
+                if (!con)
b11b5f
+                        return -ENOMEM;
b11b5f
 
b11b5f
-                        *ret = TAKE_PTR(con);
b11b5f
-                        return 0;
b11b5f
-                }
b11b5f
+                *ret = TAKE_PTR(con);
b11b5f
+                return 0;
b11b5f
+        }
b11b5f
 
b11b5f
-                c = service->exec_command[SERVICE_EXEC_START];
b11b5f
-                if (!c)
b11b5f
-                        goto no_label;
b11b5f
+        c = service->exec_command[SERVICE_EXEC_START];
b11b5f
+        if (!c)
b11b5f
+                goto no_label;
b11b5f
 
b11b5f
-                r = chase_symlinks(c->path, service->exec_context.root_directory, CHASE_PREFIX_ROOT, &path);
b11b5f
-                if (r < 0)
b11b5f
-                        goto no_label;
b11b5f
+        r = chase_symlinks(c->path, service->exec_context.root_directory, CHASE_PREFIX_ROOT, &path);
b11b5f
+        if (r < 0)
b11b5f
+                goto no_label;
b11b5f
 
b11b5f
-                r = mac_selinux_get_create_label_from_exe(path, ret);
b11b5f
-                if (IN_SET(r, -EPERM, -EOPNOTSUPP))
b11b5f
-                        goto no_label;
b11b5f
-        }
b11b5f
+        r = mac_selinux_get_create_label_from_exe(path, ret);
b11b5f
+        if (IN_SET(r, -EPERM, -EOPNOTSUPP))
b11b5f
+                goto no_label;
b11b5f
 
b11b5f
         return r;
b11b5f