[CRIU] [PATCH 5/6] net/lsm: Move default socket labeling helpers in lsm.c
Dmitry Safonov
dima at arista.com
Sun Nov 24 02:46:26 MSK 2019
No functional changes - just keep lsm to lsm.c.
Signed-off-by: Dmitry Safonov <dima at arista.com>
---
criu/include/lsm.h | 3 ++
criu/lsm.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++
criu/net.c | 75 +++++---------------------------------------
3 files changed, 87 insertions(+), 68 deletions(-)
diff --git a/criu/include/lsm.h b/criu/include/lsm.h
index 3b82712829e8..a410e7fd4047 100644
--- a/criu/include/lsm.h
+++ b/criu/include/lsm.h
@@ -36,6 +36,9 @@ int render_lsm_profile(char *profile, char **val);
extern int lsm_check_opts(void);
+extern int lsm_start_socket_labeling(void);
+extern int lsm_stop_socket_labeling(void);
+
#ifdef CONFIG_HAS_SELINUX
int dump_xattr_security_selinux(int fd, FdinfoEntry *e);
int run_setsockcreatecon(FdinfoEntry *e);
diff --git a/criu/lsm.c b/criu/lsm.c
index 9d7e55c11b7e..85bc29ad789f 100644
--- a/criu/lsm.c
+++ b/criu/lsm.c
@@ -262,6 +262,83 @@ int collect_lsm_profile(pid_t pid, CredsEntry *ce)
return ret;
}
+/*
+ * 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.
+ */
+int lsm_start_socket_labeling(void)
+{
+#ifdef CONFIG_HAS_SELINUX
+ security_context_t ctx;
+ int ret;
+
+ /*
+ * 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)
+ return 0;
+
+ ret = getpidcon_raw(root_item->pid->real, &ctx);
+ if (ret < 0) {
+ pr_perror("Getting SELinux context for PID %d failed",
+ root_item->pid->real);
+ return ret;
+ }
+
+ ret = setsockcreatecon(ctx);
+ freecon(ctx);
+ if (ret < 0) {
+ pr_perror("Setting SELinux socket context for PID %d failed",
+ root_item->pid->real);
+ return ret;
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Once the socket has been created, reset the SELinux socket labelling
+ * back to the default value of this process.
+ */
+int lsm_stop_socket_labeling(void)
+{
+#ifdef CONFIG_HAS_SELINUX
+ int ret;
+
+ if (kdat.lsm != LSMTYPE__SELINUX)
+ return 0;
+
+ ret = setsockcreatecon_raw(NULL);
+ if (ret < 0) {
+ pr_perror("Resetting SELinux socket context to "
+ "default for PID %d failed",
+ root_item->pid->real);
+ return ret;
+ }
+#endif
+ return 0;
+}
+
// in inventory.c
extern Lsmtype image_lsm;
diff --git a/criu/net.c b/criu/net.c
index 758bac9d9119..0c89a251fed1 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -17,10 +17,6 @@
#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"
@@ -36,6 +32,7 @@
#include "sockets.h"
#include "pstree.h"
#include "lib-bsd.h"
+#include "lsm.h"
#include "sysctl.h"
#include "kerndat.h"
#include "util.h"
@@ -2755,53 +2752,9 @@ 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 = lsm_start_socket_labeling();
+ if (ret)
+ goto err_sq;
ret = ns->net.seqsk = socket(PF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0);
if (ret < 0) {
@@ -2809,23 +2762,9 @@ static int prep_ns_sockets(struct ns_id *ns, bool for_dump)
goto err_sq;
}
- 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
+ ret = lsm_stop_socket_labeling();
+ if (ret)
+ goto err_ret;
out:
if (nsret >= 0 && restore_ns(nsret, &net_ns_desc) < 0) {
--
2.24.0
More information about the CRIU
mailing list