Commit b701774f authored by Adrian Reber's avatar Adrian Reber Committed by Andrei Vagin

net: add correct SELinux label to parasite socket

If running on a system with SELinux enabled the socket for the
communication between parasite daemon and the main CRIU process needs to
be correctly labeled.

Initially this was motivated by Podman's use case: The container is
usually running as something like '...:...:container_t:...:....' and
CRIU started from runc and Podman will run as
'...:...:container_runtime_t:...:...'. As the parasite will be running
with the same context as the container process: 'container_t'.

Allowing a container process to connect via socket to the outside
of the container ('container_runtime_t') is not desired and therefore
CRIU needs to label the socket with the context of the
container: 'container_t'.

So this first gets the context of the root container process and tells
SELinux to label the next created socket with the same label as the root
container process. For this to work it is necessary to have the correct
SELinux policies installed. For Fedora based systems this is part of the
container-selinux package.

This assumes that all processes CRIU wants to dump are labeled with the
same SELinux context. If some of the child processes have different
labels this will not work and needs additional SELinux policies. But the
whole SELinux socket labeling relies on the correct SELinux being
available.
Signed-off-by: 's avatarAdrian Reber <areber@redhat.com>
parent d9c51a70
......@@ -17,6 +17,10 @@
#include <libnl3/netlink/msg.h>
#include <libnl3/netlink/netlink.h>
#ifdef CONFIG_HAS_SELINUX
#include <selinux/selinux.h>
#endif
#include "../soccr/soccr.h"
#include "imgset.h"
......@@ -40,6 +44,7 @@
#include "protobuf.h"
#include "images/netdev.pb-c.h"
#include "images/inventory.pb-c.h"
#ifndef IFLA_LINK_NETNSID
#define IFLA_LINK_NETNSID 37
......@@ -2718,6 +2723,54 @@ static int prep_ns_sockets(struct ns_id *ns, bool for_dump)
} else
ns->net.nlsk = -1;
#ifdef CONFIG_HAS_SELINUX
/*
* If running on a system with SELinux enabled the socket for the
* communication between parasite daemon and the main
* CRIU process needs to be correctly labeled.
* Initially this was motivated by Podman's use case: The container
* is usually running as something like '...:...:container_t:...:....'
* and CRIU started from runc and Podman will run as
* '...:...:container_runtime_t:...:...'. As the parasite will be
* running with the same context as the container process: 'container_t'.
* Allowing a container process to connect via socket to the outside
* of the container ('container_runtime_t') is not desired and
* therefore CRIU needs to label the socket with the context of
* the container: 'container_t'.
* So this first gets the context of the root container process
* and tells SELinux to label the next created socket with
* the same label as the root container process.
* For this to work it is necessary to have the correct SELinux
* policies installed. For Fedora based systems this is part
* of the container-selinux package.
*/
security_context_t ctx;
/*
* This assumes that all processes CRIU wants to dump are labeled
* with the same SELinux context. If some of the child processes
* have different labels this will not work and needs additional
* SELinux policies. But the whole SELinux socket labeling relies
* on the correct SELinux being available.
*/
if (kdat.lsm == LSMTYPE__SELINUX) {
ret = getpidcon_raw(root_item->pid->real, &ctx);
if (ret < 0) {
pr_perror("Getting SELinux context for PID %d failed",
root_item->pid->real);
goto err_sq;
}
ret = setsockcreatecon(ctx);
freecon(ctx);
if (ret < 0) {
pr_perror("Setting SELinux socket context for PID %d failed",
root_item->pid->real);
goto err_sq;
}
}
#endif
ret = ns->net.seqsk = socket(PF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0);
if (ret < 0) {
pr_perror("Can't create seqsk for parasite");
......@@ -2725,6 +2778,23 @@ static int prep_ns_sockets(struct ns_id *ns, bool for_dump)
}
ret = 0;
#ifdef CONFIG_HAS_SELINUX
/*
* Once the socket has been created, reset the SELinux socket labelling
* back to the default value of this process.
*/
if (kdat.lsm == LSMTYPE__SELINUX) {
ret = setsockcreatecon_raw(NULL);
if (ret < 0) {
pr_perror("Resetting SELinux socket context to "
"default for PID %d failed",
root_item->pid->real);
goto err_ret;
}
}
#endif
out:
if (nsret >= 0 && restore_ns(nsret, &net_ns_desc) < 0) {
nsret = -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment