[5/6] net/lsm: Move default socket labeling helpers in lsm.c

Submitted by Dmitry Safonov on Nov. 23, 2019, 11:46 p.m.

Details

Message ID 20191123234627.483372-6-dima@arista.com
State New
Series "criu: dlopen() optional libraries"
Headers show

Commit Message

Dmitry Safonov Nov. 23, 2019, 11:46 p.m.
No functional changes - just keep lsm to lsm.c.

Signed-off-by: Dmitry Safonov <dima@arista.com>
---
 criu/include/lsm.h |  3 ++
 criu/lsm.c         | 77 ++++++++++++++++++++++++++++++++++++++++++++++
 criu/net.c         | 75 +++++---------------------------------------
 3 files changed, 87 insertions(+), 68 deletions(-)

Patch hide | download patch | download mbox

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