|
|
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 |
|