criu/685.patch
Adrian Reber 30ddb75045
Applied patch to correctly restore socket()s
Signed-off-by: Adrian Reber <adrian@lisas.de>
2019-04-29 18:24:31 +02:00

143 lines
4.3 KiB
Diff

From a3b9082572036b46bcdb4e8894a9266ec589bbf0 Mon Sep 17 00:00:00 2001
From: Adrian Reber <areber@redhat.com>
Date: Mon, 29 Apr 2019 15:19:23 +0200
Subject: [PATCH 1/2] cr-restore: do open_cores() earlier
open_cores() needs to happen before prepare_fds() as it is necessary to
read the LSM information to correctly label newly created sockets when
using SELinux.
Signed-off-by: Adrian Reber <areber@redhat.com>
---
criu/cr-restore.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 5fd22e9246..dadae5600f 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -845,6 +845,14 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
memzero(ta, args_len);
+ /*
+ * open_cores() needs to happen before prepare_fds() as
+ * it is necessary to read the LSM information to correctly
+ * label newly created sockets when using SELinux.
+ */
+ if (open_cores(pid, core))
+ return -1;
+
if (prepare_fds(current))
return -1;
@@ -860,9 +868,6 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
if (fixup_sysv_shmems())
return -1;
- if (open_cores(pid, core))
- return -1;
-
if (prepare_signals(pid, ta, core))
return -1;
From bd1f4c71882a0f8e07c63baf61004940a2b20a15 Mon Sep 17 00:00:00 2001
From: Adrian Reber <areber@redhat.com>
Date: Mon, 29 Apr 2019 15:21:59 +0200
Subject: [PATCH 2/2] sk-inet: tell SELinux to label all newly created sockets
When running in a SELinux environment processes and threads will
be labeled with the same process labels they had during checkpoint.
The process labels are set as late as possible during restore.
Sockets created during restore, however, will be labeled with
CRIU's context during restore. These sockets might not work
correctly once the process is restored and switched to another
context.
This tells SELinux to label sockets with the appropriate label.
Signed-off-by: Adrian Reber <areber@redhat.com>
---
criu/sk-inet.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/criu/sk-inet.c b/criu/sk-inet.c
index 60ee4c3155..b239d174d5 100644
--- a/criu/sk-inet.c
+++ b/criu/sk-inet.c
@@ -14,6 +14,10 @@
#include <linux/icmp.h>
#include <linux/icmpv6.h>
+#ifdef CONFIG_HAS_SELINUX
+#include <selinux/selinux.h>
+#endif
+
#include "../soccr/soccr.h"
#include "libnetlink.h"
@@ -23,6 +27,8 @@
#include "files.h"
#include "image.h"
#include "log.h"
+#include "kerndat.h"
+#include "pstree.h"
#include "rst-malloc.h"
#include "sockets.h"
#include "sk-inet.h"
@@ -30,6 +36,8 @@
#include "util.h"
#include "namespaces.h"
+#include "images/inventory.pb-c.h"
+
#undef LOG_PREFIX
#define LOG_PREFIX "inet: "
@@ -804,6 +812,44 @@ static int open_inet_sk(struct file_desc *d, int *new_fd)
if (set_netns(ie->ns_id))
return -1;
+#ifdef CONFIG_HAS_SELINUX
+ /*
+ * When running in a SELinux environment processes and threads will
+ * be labeled with the same process labels they had during checkpoint.
+ * The process labels are set as late as possible during restore.
+ * Sockets created during restore, however, will be labeled with
+ * CRIU's context during restore. These sockets might not work
+ * correctly once the process is restored and switched to another
+ * context.
+ *
+ * This tells SELinux to label sockets with the appropriate label.
+ *
+ * As with all SELinux related labeling, all processes and sockets
+ * are labeled with the same SELinux label.
+ */
+ if (kdat.lsm == LSMTYPE__SELINUX) {
+ /* Use the SELinux label from the first process/thread */
+ if (current->core[0]->thread_core &&
+ current->core[0]->thread_core->creds &&
+ current->core[0]->thread_core->creds->lsm_profile) {
+ /*
+ * thread_core, thread_core->creds and
+ * thread_core->creds->lsm_profile are all optional
+ * protobuf fields. This makes sure these exist
+ * before accessing them.
+ */
+ int ret = setsockcreatecon_raw(current->core[0]->
+ thread_core->creds->lsm_profile);
+
+ if (ret < 0) {
+ pr_perror("Setting SELinux socket context failed");
+ return -1;
+ }
+ pr_debug("Setting LSM label %s on socket\n", current->
+ core[0]->thread_core->creds->lsm_profile);
+ }
+ }
+#endif
sk = socket(ie->family, ie->type, ie->proto);
if (sk < 0) {
pr_perror("Can't create inet socket");