mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 22:05:36 +00:00
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: Adrian Reber <areber@redhat.com>
This commit is contained in:
committed by
Andrei Vagin
parent
d9c51a7034
commit
b701774f9d
70
criu/net.c
70
criu/net.c
@@ -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;
|
||||
|
Reference in New Issue
Block a user