Compare commits
No commits in common. "c8-stream-1.0" and "c9-beta" have entirely different histories.
c8-stream-
...
c9-beta
@ -1 +1 @@
|
|||||||
b2ceaf9705aa8239915010136a59664d31044fe3 SOURCES/criu-3.12.tar.bz2
|
61ffc54bf7e345c9df2d20d599da47f0e91e70e2 SOURCES/criu-3.19.tar.gz
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
|||||||
SOURCES/criu-3.12.tar.bz2
|
SOURCES/criu-3.19.tar.gz
|
||||||
|
|||||||
57
SOURCES/0001-Fix-building-with-annobin.patch
Normal file
57
SOURCES/0001-Fix-building-with-annobin.patch
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
From 4878775c8e0f2ea6869aff139d219f6eb0c4006c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Reber <areber@redhat.com>
|
||||||
|
Date: Fri, 28 Jan 2022 15:10:31 +0000
|
||||||
|
Subject: [PATCH] Fix building with annobin
|
||||||
|
|
||||||
|
Annobin (used at least in Fedora and RHEL) injects annotation into the
|
||||||
|
compiled objects which break the parasite and restorer.
|
||||||
|
|
||||||
|
This removes the annobin flags as used in Fedora and RHEL and makes CRIU
|
||||||
|
work on Fedora and RHEL with annobin enabled.
|
||||||
|
|
||||||
|
Signed-off-by: Adrian Reber <areber@redhat.com>
|
||||||
|
---
|
||||||
|
compel/plugins/Makefile | 2 +-
|
||||||
|
criu/pie/Makefile | 2 +-
|
||||||
|
criu/pie/Makefile.library | 2 +-
|
||||||
|
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/compel/plugins/Makefile b/compel/plugins/Makefile
|
||||||
|
index e5fa781ac..37630d438 100644
|
||||||
|
--- a/compel/plugins/Makefile
|
||||||
|
+++ b/compel/plugins/Makefile
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-CFLAGS := $(filter-out -pg $(CFLAGS-GCOV) $(CFLAGS-ASAN),$(CFLAGS))
|
||||||
|
+CFLAGS := $(filter-out -pg $(CFLAGS-GCOV) $(CFLAGS-ASAN) -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1,$(CFLAGS))
|
||||||
|
CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0
|
||||||
|
CFLAGS += -Wp,-U_FORTIFY_SOURCE -Wp,-D_FORTIFY_SOURCE=0
|
||||||
|
|
||||||
|
diff --git a/criu/pie/Makefile b/criu/pie/Makefile
|
||||||
|
index 265dcf82b..386626334 100644
|
||||||
|
--- a/criu/pie/Makefile
|
||||||
|
+++ b/criu/pie/Makefile
|
||||||
|
@@ -4,7 +4,7 @@
|
||||||
|
|
||||||
|
target := parasite restorer
|
||||||
|
|
||||||
|
-CFLAGS := $(filter-out -pg $(CFLAGS-GCOV) $(CFLAGS-ASAN),$(CFLAGS))
|
||||||
|
+CFLAGS := $(filter-out -pg $(CFLAGS-GCOV) $(CFLAGS-ASAN) -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1,$(CFLAGS))
|
||||||
|
CFLAGS += $(CFLAGS_PIE)
|
||||||
|
ccflags-y += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0
|
||||||
|
ccflags-y += -Wp,-U_FORTIFY_SOURCE -Wp,-D_FORTIFY_SOURCE=0
|
||||||
|
diff --git a/criu/pie/Makefile.library b/criu/pie/Makefile.library
|
||||||
|
index da2a2fab3..6247afe7e 100644
|
||||||
|
--- a/criu/pie/Makefile.library
|
||||||
|
+++ b/criu/pie/Makefile.library
|
||||||
|
@@ -21,7 +21,7 @@ ifeq ($(ARCH),arm)
|
||||||
|
lib-y += ./$(ARCH_DIR)/pie-cacheflush.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
-CFLAGS := $(filter-out -pg $(CFLAGS-GCOV) $(CFLAGS-ASAN),$(CFLAGS))
|
||||||
|
+CFLAGS := $(filter-out -pg $(CFLAGS-GCOV) $(CFLAGS-ASAN) -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1,$(CFLAGS))
|
||||||
|
CFLAGS += $(CFLAGS_PIE)
|
||||||
|
|
||||||
|
ifeq ($(ARCH),mips)
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
||||||
87
SOURCES/089345f77a34d1bc7ef146d650636afcd3cdda21.patch
Normal file
87
SOURCES/089345f77a34d1bc7ef146d650636afcd3cdda21.patch
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
From 089345f77a34d1bc7ef146d650636afcd3cdda21 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Wed, 10 Jul 2024 18:34:50 +0200
|
||||||
|
Subject: [PATCH] Adjust to glibc __rseq_size semantic change
|
||||||
|
|
||||||
|
In commit 2e456ccf0c34a056e3ccafac4a0c7effef14d918 ("Linux: Make
|
||||||
|
__rseq_size useful for feature detection (bug 31965)") glibc 2.40
|
||||||
|
changed the meaning of __rseq_size slightly: it is now the size
|
||||||
|
of the active/feature area (20 bytes initially), and not the size
|
||||||
|
of the entire initially defined struct (32 bytes including padding).
|
||||||
|
The reason for the change is that the size including padding does not
|
||||||
|
allow detection of newly added features while previously unused
|
||||||
|
padding is consumed.
|
||||||
|
|
||||||
|
The prep_libc_rseq_info change in criu/cr-restore.c is not necessary
|
||||||
|
on kernels which have full ptrace support for obtaining rseq
|
||||||
|
information because the code is not used. On older kernels, it is
|
||||||
|
a correctness fix because with size 20 (the new value), rseq
|
||||||
|
registeration would fail.
|
||||||
|
|
||||||
|
The two other changes are required to make rseq unregistration work
|
||||||
|
in tests.
|
||||||
|
|
||||||
|
Signed-off-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
---
|
||||||
|
criu/cr-restore.c | 8 ++++++++
|
||||||
|
test/zdtm/static/rseq00.c | 5 ++++-
|
||||||
|
test/zdtm/transition/rseq01.c | 5 ++++-
|
||||||
|
3 files changed, 16 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
|
||||||
|
index 4db2f4ecfc..b95d4f134b 100644
|
||||||
|
--- a/criu/cr-restore.c
|
||||||
|
+++ b/criu/cr-restore.c
|
||||||
|
@@ -2618,7 +2618,15 @@ static void prep_libc_rseq_info(struct rst_rseq_param *rseq)
|
||||||
|
if (!kdat.has_ptrace_get_rseq_conf) {
|
||||||
|
#if defined(__GLIBC__) && defined(RSEQ_SIG)
|
||||||
|
rseq->rseq_abi_pointer = encode_pointer(__criu_thread_pointer() + __rseq_offset);
|
||||||
|
+ /*
|
||||||
|
+ * Current glibc reports the feature/active size in
|
||||||
|
+ * __rseq_size, not the size passed to the kernel.
|
||||||
|
+ * This could be 20, but older kernels expect 32 for
|
||||||
|
+ * the size argument even if only 20 bytes are used.
|
||||||
|
+ */
|
||||||
|
rseq->rseq_abi_size = __rseq_size;
|
||||||
|
+ if (rseq->rseq_abi_size < 32)
|
||||||
|
+ rseq->rseq_abi_size = 32;
|
||||||
|
rseq->signature = RSEQ_SIG;
|
||||||
|
#else
|
||||||
|
rseq->rseq_abi_pointer = 0;
|
||||||
|
diff --git a/test/zdtm/static/rseq00.c b/test/zdtm/static/rseq00.c
|
||||||
|
index 471ad6a43f..7add7801eb 100644
|
||||||
|
--- a/test/zdtm/static/rseq00.c
|
||||||
|
+++ b/test/zdtm/static/rseq00.c
|
||||||
|
@@ -46,12 +46,15 @@ static inline void *__criu_thread_pointer(void)
|
||||||
|
static inline void unregister_glibc_rseq(void)
|
||||||
|
{
|
||||||
|
struct rseq *rseq = (struct rseq *)((char *)__criu_thread_pointer() + __rseq_offset);
|
||||||
|
+ unsigned int size = __rseq_size;
|
||||||
|
|
||||||
|
/* hack: mark glibc rseq structure as failed to register */
|
||||||
|
rseq->cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED;
|
||||||
|
|
||||||
|
/* unregister rseq */
|
||||||
|
- syscall(__NR_rseq, (void *)rseq, __rseq_size, 1, RSEQ_SIG);
|
||||||
|
+ if (__rseq_size < 32)
|
||||||
|
+ size = 32;
|
||||||
|
+ syscall(__NR_rseq, (void *)rseq, size, 1, RSEQ_SIG);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void unregister_glibc_rseq(void)
|
||||||
|
diff --git a/test/zdtm/transition/rseq01.c b/test/zdtm/transition/rseq01.c
|
||||||
|
index 0fbcc2dca0..08a7a8e1a6 100644
|
||||||
|
--- a/test/zdtm/transition/rseq01.c
|
||||||
|
+++ b/test/zdtm/transition/rseq01.c
|
||||||
|
@@ -33,7 +33,10 @@ static inline void *thread_pointer(void)
|
||||||
|
static inline void unregister_old_rseq(void)
|
||||||
|
{
|
||||||
|
/* unregister rseq */
|
||||||
|
- syscall(__NR_rseq, (void *)((char *)thread_pointer() + __rseq_offset), __rseq_size, 1, RSEQ_SIG);
|
||||||
|
+ unsigned int size = __rseq_size;
|
||||||
|
+ if (__rseq_size < 32)
|
||||||
|
+ size = 32;
|
||||||
|
+ syscall(__NR_rseq, (void *)((char *)thread_pointer() + __rseq_offset), size, 1, RSEQ_SIG);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void unregister_old_rseq(void)
|
||||||
@ -1,67 +0,0 @@
|
|||||||
From 1e84cb90b63bce841376140a7a80107e5ec1e1a8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Adrian Reber <areber@redhat.com>
|
|
||||||
Date: Fri, 3 May 2019 06:27:51 +0000
|
|
||||||
Subject: [PATCH] lsm: fix compiler error 'unused-result'
|
|
||||||
|
|
||||||
Reading out the xattr 'security.selinux' of checkpointed sockets with
|
|
||||||
fscanf() works (at least in theory) without checking the result of
|
|
||||||
fscanf(). There are, however, multiple CI failures when ignoring the
|
|
||||||
return value of fscanf().
|
|
||||||
|
|
||||||
This adds ferror() to check if the stream has an actual error or if '-1'
|
|
||||||
just mean EOF.
|
|
||||||
|
|
||||||
Handle all errors of fscanf() // Andrei
|
|
||||||
|
|
||||||
Signed-off-by: Adrian Reber <areber@redhat.com>
|
|
||||||
Signed-off-by: Andrei Vagin <avagin@gmail.com>
|
|
||||||
---
|
|
||||||
criu/lsm.c | 22 +++++++++++++---------
|
|
||||||
1 file changed, 13 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/criu/lsm.c b/criu/lsm.c
|
|
||||||
index ef6ba112b3..9c9ac7f80e 100644
|
|
||||||
--- a/criu/lsm.c
|
|
||||||
+++ b/criu/lsm.c
|
|
||||||
@@ -33,8 +33,8 @@ static int apparmor_get_label(pid_t pid, char **profile_name)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (fscanf(f, "%ms", profile_name) != 1) {
|
|
||||||
- fclose(f);
|
|
||||||
pr_perror("err scanfing");
|
|
||||||
+ fclose(f);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -111,19 +111,23 @@ static int selinux_get_label(pid_t pid, char **output)
|
|
||||||
static int selinux_get_sockcreate_label(pid_t pid, char **output)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
+ int ret;
|
|
||||||
|
|
||||||
f = fopen_proc(pid, "attr/sockcreate");
|
|
||||||
if (!f)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
- fscanf(f, "%ms", output);
|
|
||||||
- /*
|
|
||||||
- * No need to check the result of fscanf(). If there is something
|
|
||||||
- * in /proc/PID/attr/sockcreate it will be copied to *output. If
|
|
||||||
- * there is nothing it will stay NULL. So whatever fscanf() does
|
|
||||||
- * it should be correct.
|
|
||||||
- */
|
|
||||||
-
|
|
||||||
+ ret = fscanf(f, "%ms", output);
|
|
||||||
+ if (ret == -1 && errno != 0) {
|
|
||||||
+ pr_perror("Unable to parse /proc/%d/attr/sockcreate", pid);
|
|
||||||
+ /*
|
|
||||||
+ * Only if the error indicator is set it is a real error.
|
|
||||||
+ * -1 could also be EOF, which would mean that sockcreate
|
|
||||||
+ * was just empty, which is the most common case.
|
|
||||||
+ */
|
|
||||||
+ fclose(f);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
fclose(f);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
30
SOURCES/2587.patch
Normal file
30
SOURCES/2587.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From 432e9f78b44d15c38fcc07b509ca329b3ad627b5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Adrian Reber <areber@redhat.com>
|
||||||
|
Date: Thu, 6 Feb 2025 11:07:17 +0100
|
||||||
|
Subject: [PATCH] lsm: use the user provided lsm label
|
||||||
|
|
||||||
|
Currently CRIU has the possibility to specify a LSM label during
|
||||||
|
restore. Unfortunately the information is completely ignored in the case
|
||||||
|
of SELinux.
|
||||||
|
|
||||||
|
This change selects the lsm label from the user if it is provided and
|
||||||
|
else the label from the checkpoint image is used.
|
||||||
|
|
||||||
|
Signed-off-by: Adrian Reber <areber@redhat.com>
|
||||||
|
---
|
||||||
|
criu/lsm.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/criu/lsm.c b/criu/lsm.c
|
||||||
|
index d1b73cc79e..70b66d42ee 100644
|
||||||
|
--- a/criu/lsm.c
|
||||||
|
+++ b/criu/lsm.c
|
||||||
|
@@ -370,7 +370,7 @@ int render_lsm_profile(char *profile, char **val)
|
||||||
|
case LSMTYPE__APPARMOR:
|
||||||
|
return render_aa_profile(val, profile);
|
||||||
|
case LSMTYPE__SELINUX:
|
||||||
|
- if (asprintf(val, "%s", profile) < 0) {
|
||||||
|
+ if (asprintf(val, "%s", opts.lsm_supplied ? opts.lsm_profile : profile) < 0) {
|
||||||
|
*val = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
@ -1,834 +0,0 @@
|
|||||||
From 3313343ba7803bff077af5d87df2260cdcd2d678 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Adrian Reber <areber@redhat.com>
|
|
||||||
Date: Thu, 2 May 2019 13:41:46 +0000
|
|
||||||
Subject: [PATCH 1/4] lsm: also dump and restore sockcreate
|
|
||||||
|
|
||||||
The file /proc/PID/attr/sockcreate is used by SELinux to label newly
|
|
||||||
created sockets with the label available at sockcreate.
|
|
||||||
|
|
||||||
If it is NULL, the default label of the process will be used.
|
|
||||||
|
|
||||||
This reads out that file during checkpoint and restores the value during
|
|
||||||
restore.
|
|
||||||
|
|
||||||
This value is irrelevant for existing sockets as they might have been
|
|
||||||
created with another context. This is only to make sure that newly
|
|
||||||
created sockets have the correct context.
|
|
||||||
|
|
||||||
Signed-off-by: Adrian Reber <areber@redhat.com>
|
|
||||||
---
|
|
||||||
criu/cr-restore.c | 36 ++++++++++++++++++++++++++++++++++++
|
|
||||||
criu/include/restorer.h | 2 ++
|
|
||||||
criu/lsm.c | 32 ++++++++++++++++++++++++++++++++
|
|
||||||
criu/pie/restorer.c | 15 ++++++++++-----
|
|
||||||
images/creds.proto | 1 +
|
|
||||||
5 files changed, 81 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
|
|
||||||
index 5fd22e9246..f254cbc0eb 100644
|
|
||||||
--- a/criu/cr-restore.c
|
|
||||||
+++ b/criu/cr-restore.c
|
|
||||||
@@ -2997,6 +2997,8 @@ static void rst_reloc_creds(struct thread_restore_args *thread_args,
|
|
||||||
|
|
||||||
if (args->lsm_profile)
|
|
||||||
args->lsm_profile = rst_mem_remap_ptr(args->mem_lsm_profile_pos, RM_PRIVATE);
|
|
||||||
+ if (args->lsm_sockcreate)
|
|
||||||
+ args->lsm_sockcreate = rst_mem_remap_ptr(args->mem_lsm_sockcreate_pos, RM_PRIVATE);
|
|
||||||
if (args->groups)
|
|
||||||
args->groups = rst_mem_remap_ptr(args->mem_groups_pos, RM_PRIVATE);
|
|
||||||
|
|
||||||
@@ -3062,6 +3064,40 @@ rst_prep_creds_args(CredsEntry *ce, unsigned long *prev_pos)
|
|
||||||
args->mem_lsm_profile_pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (ce->lsm_sockcreate) {
|
|
||||||
+ char *rendered = NULL;
|
|
||||||
+ char *profile;
|
|
||||||
+
|
|
||||||
+ profile = ce->lsm_sockcreate;
|
|
||||||
+
|
|
||||||
+ if (validate_lsm(profile) < 0)
|
|
||||||
+ return ERR_PTR(-EINVAL);
|
|
||||||
+
|
|
||||||
+ if (profile && render_lsm_profile(profile, &rendered)) {
|
|
||||||
+ return ERR_PTR(-EINVAL);
|
|
||||||
+ }
|
|
||||||
+ if (rendered) {
|
|
||||||
+ size_t lsm_sockcreate_len;
|
|
||||||
+ char *lsm_sockcreate;
|
|
||||||
+
|
|
||||||
+ args->mem_lsm_sockcreate_pos = rst_mem_align_cpos(RM_PRIVATE);
|
|
||||||
+ lsm_sockcreate_len = strlen(rendered);
|
|
||||||
+ lsm_sockcreate = rst_mem_alloc(lsm_sockcreate_len + 1, RM_PRIVATE);
|
|
||||||
+ if (!lsm_sockcreate) {
|
|
||||||
+ xfree(rendered);
|
|
||||||
+ return ERR_PTR(-ENOMEM);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ args = rst_mem_remap_ptr(this_pos, RM_PRIVATE);
|
|
||||||
+ args->lsm_sockcreate = lsm_sockcreate;
|
|
||||||
+ strncpy(args->lsm_sockcreate, rendered, lsm_sockcreate_len);
|
|
||||||
+ xfree(rendered);
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ args->lsm_sockcreate = NULL;
|
|
||||||
+ args->mem_lsm_sockcreate_pos = 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Zap fields which we can't use.
|
|
||||||
*/
|
|
||||||
diff --git a/criu/include/restorer.h b/criu/include/restorer.h
|
|
||||||
index 2884ce9e6d..b83e9130c5 100644
|
|
||||||
--- a/criu/include/restorer.h
|
|
||||||
+++ b/criu/include/restorer.h
|
|
||||||
@@ -69,8 +69,10 @@ struct thread_creds_args {
|
|
||||||
unsigned int secbits;
|
|
||||||
char *lsm_profile;
|
|
||||||
unsigned int *groups;
|
|
||||||
+ char *lsm_sockcreate;
|
|
||||||
|
|
||||||
unsigned long mem_lsm_profile_pos;
|
|
||||||
+ unsigned long mem_lsm_sockcreate_pos;
|
|
||||||
unsigned long mem_groups_pos;
|
|
||||||
|
|
||||||
unsigned long mem_pos_next;
|
|
||||||
diff --git a/criu/lsm.c b/criu/lsm.c
|
|
||||||
index 849ec37cde..b0ef0c396c 100644
|
|
||||||
--- a/criu/lsm.c
|
|
||||||
+++ b/criu/lsm.c
|
|
||||||
@@ -98,6 +98,32 @@ static int selinux_get_label(pid_t pid, char **output)
|
|
||||||
freecon(ctx);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * selinux_get_sockcreate_label reads /proc/PID/attr/sockcreate
|
|
||||||
+ * to see if the PID has a special label specified for sockets.
|
|
||||||
+ * Most of the time this will be empty and the process will use
|
|
||||||
+ * the process context also for sockets.
|
|
||||||
+ */
|
|
||||||
+static int selinux_get_sockcreate_label(pid_t pid, char **output)
|
|
||||||
+{
|
|
||||||
+ FILE *f;
|
|
||||||
+
|
|
||||||
+ f = fopen_proc(pid, "attr/sockcreate");
|
|
||||||
+ if (!f)
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ fscanf(f, "%ms", output);
|
|
||||||
+ /*
|
|
||||||
+ * No need to check the result of fscanf(). If there is something
|
|
||||||
+ * in /proc/PID/attr/sockcreate it will be copied to *output. If
|
|
||||||
+ * there is nothing it will stay NULL. So whatever fscanf() does
|
|
||||||
+ * it should be correct.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+ fclose(f);
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void kerndat_lsm(void)
|
|
||||||
@@ -132,6 +158,7 @@ int collect_lsm_profile(pid_t pid, CredsEntry *ce)
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ce->lsm_profile = NULL;
|
|
||||||
+ ce->lsm_sockcreate = NULL;
|
|
||||||
|
|
||||||
switch (kdat.lsm) {
|
|
||||||
case LSMTYPE__NO_LSM:
|
|
||||||
@@ -143,6 +170,9 @@ int collect_lsm_profile(pid_t pid, CredsEntry *ce)
|
|
||||||
#ifdef CONFIG_HAS_SELINUX
|
|
||||||
case LSMTYPE__SELINUX:
|
|
||||||
ret = selinux_get_label(pid, &ce->lsm_profile);
|
|
||||||
+ if (ret)
|
|
||||||
+ break;
|
|
||||||
+ ret = selinux_get_sockcreate_label(pid, &ce->lsm_sockcreate);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
@@ -153,6 +183,8 @@ int collect_lsm_profile(pid_t pid, CredsEntry *ce)
|
|
||||||
|
|
||||||
if (ce->lsm_profile)
|
|
||||||
pr_info("%d has lsm profile %s\n", pid, ce->lsm_profile);
|
|
||||||
+ if (ce->lsm_sockcreate)
|
|
||||||
+ pr_info("%d has lsm sockcreate label %s\n", pid, ce->lsm_sockcreate);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
|
|
||||||
index 6e18cc2606..4f42605a09 100644
|
|
||||||
--- a/criu/pie/restorer.c
|
|
||||||
+++ b/criu/pie/restorer.c
|
|
||||||
@@ -149,7 +149,7 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
|
|
||||||
sys_exit_group(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int lsm_set_label(char *label, int procfd)
|
|
||||||
+static int lsm_set_label(char *label, char *type, int procfd)
|
|
||||||
{
|
|
||||||
int ret = -1, len, lsmfd;
|
|
||||||
char path[STD_LOG_SIMPLE_CHUNK];
|
|
||||||
@@ -157,9 +157,9 @@ static int lsm_set_label(char *label, int procfd)
|
|
||||||
if (!label)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- pr_info("restoring lsm profile %s\n", label);
|
|
||||||
+ pr_info("restoring lsm profile (%s) %s\n", type, label);
|
|
||||||
|
|
||||||
- std_sprintf(path, "self/task/%ld/attr/current", sys_gettid());
|
|
||||||
+ std_sprintf(path, "self/task/%ld/attr/%s", sys_gettid(), type);
|
|
||||||
|
|
||||||
lsmfd = sys_openat(procfd, path, O_WRONLY, 0);
|
|
||||||
if (lsmfd < 0) {
|
|
||||||
@@ -305,9 +305,14 @@ static int restore_creds(struct thread_creds_args *args, int procfd,
|
|
||||||
* SELinux and instead the process context is set before the
|
|
||||||
* threads are created.
|
|
||||||
*/
|
|
||||||
- if (lsm_set_label(args->lsm_profile, procfd) < 0)
|
|
||||||
+ if (lsm_set_label(args->lsm_profile, "current", procfd) < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ /* Also set the sockcreate label for all threads */
|
|
||||||
+ if (lsm_set_label(args->lsm_sockcreate, "sockcreate", procfd) < 0)
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1571,7 +1576,7 @@ long __export_restore_task(struct task_restore_args *args)
|
|
||||||
if (args->lsm_type == LSMTYPE__SELINUX) {
|
|
||||||
/* Only for SELinux */
|
|
||||||
if (lsm_set_label(args->t->creds_args->lsm_profile,
|
|
||||||
- args->proc_fd) < 0)
|
|
||||||
+ "current", args->proc_fd) < 0)
|
|
||||||
goto core_restore_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/images/creds.proto b/images/creds.proto
|
|
||||||
index 29fb8652eb..23b84c7e50 100644
|
|
||||||
--- a/images/creds.proto
|
|
||||||
+++ b/images/creds.proto
|
|
||||||
@@ -20,4 +20,5 @@ message creds_entry {
|
|
||||||
repeated uint32 groups = 14;
|
|
||||||
|
|
||||||
optional string lsm_profile = 15;
|
|
||||||
+ optional string lsm_sockcreate = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
From 495e6aa7ac51fcb36e6bc5f6c97f44cab7649b9c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Adrian Reber <areber@redhat.com>
|
|
||||||
Date: Thu, 2 May 2019 13:47:29 +0000
|
|
||||||
Subject: [PATCH 2/4] test: Verify that sockcreate does not change during
|
|
||||||
restore
|
|
||||||
|
|
||||||
This makes sure that sockcreate stays empty for selinux00 before and
|
|
||||||
after checkpoint/restore.
|
|
||||||
|
|
||||||
Signed-off-by: Adrian Reber <areber@redhat.com>
|
|
||||||
---
|
|
||||||
test/zdtm/static/selinux00.c | 34 ++++++++++++++++++++++++++++++++++
|
|
||||||
1 file changed, 34 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/test/zdtm/static/selinux00.c b/test/zdtm/static/selinux00.c
|
|
||||||
index dd9096a6fc..db8420eacb 100644
|
|
||||||
--- a/test/zdtm/static/selinux00.c
|
|
||||||
+++ b/test/zdtm/static/selinux00.c
|
|
||||||
@@ -83,6 +83,31 @@ int checkprofile()
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+int check_sockcreate()
|
|
||||||
+{
|
|
||||||
+ char *output = NULL;
|
|
||||||
+ FILE *f = fopen("/proc/self/attr/sockcreate", "r");
|
|
||||||
+ int ret = fscanf(f, "%ms", &output);
|
|
||||||
+ fclose(f);
|
|
||||||
+
|
|
||||||
+ if (ret >= 1) {
|
|
||||||
+ free(output);
|
|
||||||
+ /* sockcreate should be empty, if fscanf found something
|
|
||||||
+ * it is wrong.*/
|
|
||||||
+ fail("sockcreate should be empty\n");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (output) {
|
|
||||||
+ free(output);
|
|
||||||
+ /* Same here, output should still be NULL. */
|
|
||||||
+ fail("sockcreate should be empty\n");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
test_init(argc, argv);
|
|
||||||
@@ -95,12 +120,21 @@ int main(int argc, char **argv)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (check_sockcreate())
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
if (setprofile())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
+ if (check_sockcreate())
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
test_daemon();
|
|
||||||
test_waitsig();
|
|
||||||
|
|
||||||
+ if (check_sockcreate())
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
if (checkprofile() == 0)
|
|
||||||
pass();
|
|
||||||
|
|
||||||
|
|
||||||
From fe52cf66b38a261846ff40fc425085724b2acc15 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Adrian Reber <areber@redhat.com>
|
|
||||||
Date: Mon, 29 Apr 2019 15:21:59 +0200
|
|
||||||
Subject: [PATCH 3/4] sockets: dump and restore xattr security labels
|
|
||||||
|
|
||||||
Restoring a SELinux process also requires to correctly label sockets.
|
|
||||||
|
|
||||||
During checkpointing fgetxattr() is used to retrieve the
|
|
||||||
"security.selinux" xattr and during restore setsockcreatecon() is used
|
|
||||||
before a socket is created.
|
|
||||||
|
|
||||||
Previous commits are already restoring the sockcreate SELinux setting if
|
|
||||||
set by the process.
|
|
||||||
|
|
||||||
Signed-off-by: Adrian Reber <areber@redhat.com>
|
|
||||||
---
|
|
||||||
criu/include/lsm.h | 18 +++++++++++++++
|
|
||||||
criu/lsm.c | 56 +++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
criu/sk-inet.c | 12 ++++++++++
|
|
||||||
criu/sockets.c | 4 ++++
|
|
||||||
images/fdinfo.proto | 1 +
|
|
||||||
5 files changed, 91 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/criu/include/lsm.h b/criu/include/lsm.h
|
|
||||||
index b4fce13039..3b82712829 100644
|
|
||||||
--- a/criu/include/lsm.h
|
|
||||||
+++ b/criu/include/lsm.h
|
|
||||||
@@ -3,6 +3,7 @@
|
|
||||||
|
|
||||||
#include "images/inventory.pb-c.h"
|
|
||||||
#include "images/creds.pb-c.h"
|
|
||||||
+#include "images/fdinfo.pb-c.h"
|
|
||||||
|
|
||||||
#define AA_SECURITYFS_PATH "/sys/kernel/security/apparmor"
|
|
||||||
|
|
||||||
@@ -34,4 +35,21 @@ int validate_lsm(char *profile);
|
|
||||||
int render_lsm_profile(char *profile, char **val);
|
|
||||||
|
|
||||||
extern int lsm_check_opts(void);
|
|
||||||
+
|
|
||||||
+#ifdef CONFIG_HAS_SELINUX
|
|
||||||
+int dump_xattr_security_selinux(int fd, FdinfoEntry *e);
|
|
||||||
+int run_setsockcreatecon(FdinfoEntry *e);
|
|
||||||
+int reset_setsockcreatecon();
|
|
||||||
+#else
|
|
||||||
+static inline int dump_xattr_security_selinux(int fd, FdinfoEntry *e) {
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+static inline int run_setsockcreatecon(FdinfoEntry *e) {
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+static inline int reset_setsockcreatecon() {
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
#endif /* __CR_LSM_H__ */
|
|
||||||
diff --git a/criu/lsm.c b/criu/lsm.c
|
|
||||||
index b0ef0c396c..ef6ba112b3 100644
|
|
||||||
--- a/criu/lsm.c
|
|
||||||
+++ b/criu/lsm.c
|
|
||||||
@@ -3,6 +3,7 @@
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
+#include <sys/xattr.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "common/config.h"
|
|
||||||
@@ -11,10 +12,12 @@
|
|
||||||
#include "util.h"
|
|
||||||
#include "cr_options.h"
|
|
||||||
#include "lsm.h"
|
|
||||||
+#include "fdstore.h"
|
|
||||||
|
|
||||||
#include "protobuf.h"
|
|
||||||
#include "images/inventory.pb-c.h"
|
|
||||||
#include "images/creds.pb-c.h"
|
|
||||||
+#include "images/fdinfo.pb-c.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_HAS_SELINUX
|
|
||||||
#include <selinux/selinux.h>
|
|
||||||
@@ -124,6 +127,59 @@ static int selinux_get_sockcreate_label(pid_t pid, char **output)
|
|
||||||
fclose(f);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+int reset_setsockcreatecon()
|
|
||||||
+{
|
|
||||||
+ return setsockcreatecon_raw(NULL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int run_setsockcreatecon(FdinfoEntry *e)
|
|
||||||
+{
|
|
||||||
+ char *ctx = NULL;
|
|
||||||
+
|
|
||||||
+ /* Currently this only works for SELinux. */
|
|
||||||
+ if (kdat.lsm != LSMTYPE__SELINUX)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ ctx = e->xattr_security_selinux;
|
|
||||||
+ /* Writing to the FD using fsetxattr() did not work for some reason. */
|
|
||||||
+ return setsockcreatecon_raw(ctx);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int dump_xattr_security_selinux(int fd, FdinfoEntry *e)
|
|
||||||
+{
|
|
||||||
+ char *ctx = NULL;
|
|
||||||
+ int len;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ /* Currently this only works for SELinux. */
|
|
||||||
+ if (kdat.lsm != LSMTYPE__SELINUX)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ /* Get the size of the xattr. */
|
|
||||||
+ len = fgetxattr(fd, "security.selinux", ctx, 0);
|
|
||||||
+ if (len == -1) {
|
|
||||||
+ pr_err("Reading xattr %s to FD %d failed\n", ctx, fd);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ctx = xmalloc(len);
|
|
||||||
+ if (!ctx) {
|
|
||||||
+ pr_err("xmalloc to read xattr for FD %d failed\n", fd);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = fgetxattr(fd, "security.selinux", ctx, len);
|
|
||||||
+ if (len != ret) {
|
|
||||||
+ pr_err("Reading xattr %s to FD %d failed\n", ctx, fd);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ e->xattr_security_selinux = ctx;
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void kerndat_lsm(void)
|
|
||||||
diff --git a/criu/sk-inet.c b/criu/sk-inet.c
|
|
||||||
index 60ee4c3155..ca5c9bf2cd 100644
|
|
||||||
--- a/criu/sk-inet.c
|
|
||||||
+++ b/criu/sk-inet.c
|
|
||||||
@@ -23,6 +23,9 @@
|
|
||||||
#include "files.h"
|
|
||||||
#include "image.h"
|
|
||||||
#include "log.h"
|
|
||||||
+#include "lsm.h"
|
|
||||||
+#include "kerndat.h"
|
|
||||||
+#include "pstree.h"
|
|
||||||
#include "rst-malloc.h"
|
|
||||||
#include "sockets.h"
|
|
||||||
#include "sk-inet.h"
|
|
||||||
@@ -30,6 +33,8 @@
|
|
||||||
#include "util.h"
|
|
||||||
#include "namespaces.h"
|
|
||||||
|
|
||||||
+#include "images/inventory.pb-c.h"
|
|
||||||
+
|
|
||||||
#undef LOG_PREFIX
|
|
||||||
#define LOG_PREFIX "inet: "
|
|
||||||
|
|
||||||
@@ -804,12 +809,18 @@ static int open_inet_sk(struct file_desc *d, int *new_fd)
|
|
||||||
if (set_netns(ie->ns_id))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
+ if (run_setsockcreatecon(fle->fe))
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
sk = socket(ie->family, ie->type, ie->proto);
|
|
||||||
if (sk < 0) {
|
|
||||||
pr_perror("Can't create inet socket");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (reset_setsockcreatecon())
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
if (ie->v6only) {
|
|
||||||
if (restore_opt(sk, SOL_IPV6, IPV6_V6ONLY, &yes) == -1)
|
|
||||||
goto err;
|
|
||||||
@@ -895,6 +906,7 @@ static int open_inet_sk(struct file_desc *d, int *new_fd)
|
|
||||||
}
|
|
||||||
|
|
||||||
*new_fd = sk;
|
|
||||||
+
|
|
||||||
return 1;
|
|
||||||
err:
|
|
||||||
close(sk);
|
|
||||||
diff --git a/criu/sockets.c b/criu/sockets.c
|
|
||||||
index 30072ac737..7f7453ca1d 100644
|
|
||||||
--- a/criu/sockets.c
|
|
||||||
+++ b/criu/sockets.c
|
|
||||||
@@ -22,6 +22,7 @@
|
|
||||||
#include "util-pie.h"
|
|
||||||
#include "sk-packet.h"
|
|
||||||
#include "namespaces.h"
|
|
||||||
+#include "lsm.h"
|
|
||||||
#include "net.h"
|
|
||||||
#include "xmalloc.h"
|
|
||||||
#include "fs-magic.h"
|
|
||||||
@@ -663,6 +664,9 @@ int dump_socket(struct fd_parms *p, int lfd, FdinfoEntry *e)
|
|
||||||
int family;
|
|
||||||
const struct fdtype_ops *ops;
|
|
||||||
|
|
||||||
+ if (dump_xattr_security_selinux(lfd, e))
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
if (dump_opt(lfd, SOL_SOCKET, SO_DOMAIN, &family))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
diff --git a/images/fdinfo.proto b/images/fdinfo.proto
|
|
||||||
index ed82ceffe7..77e375aa94 100644
|
|
||||||
--- a/images/fdinfo.proto
|
|
||||||
+++ b/images/fdinfo.proto
|
|
||||||
@@ -47,6 +47,7 @@ message fdinfo_entry {
|
|
||||||
required uint32 flags = 2;
|
|
||||||
required fd_types type = 3;
|
|
||||||
required uint32 fd = 4;
|
|
||||||
+ optional string xattr_security_selinux = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message file_entry {
|
|
||||||
|
|
||||||
From ba42d30fad82f17a66617a33f03d3da05cc73bfe Mon Sep 17 00:00:00 2001
|
|
||||||
From: Adrian Reber <areber@redhat.com>
|
|
||||||
Date: Tue, 30 Apr 2019 09:47:32 +0000
|
|
||||||
Subject: [PATCH 4/4] selinux: add socket label test
|
|
||||||
|
|
||||||
This adds two more SELinux test to verfy that checkpointing and
|
|
||||||
restoring SELinux socket labels works correctly, if the process uses
|
|
||||||
setsockcreatecon() or if the process leaves the default context for
|
|
||||||
newly created sockets.
|
|
||||||
|
|
||||||
Signed-off-by: Adrian Reber <areber@redhat.com>
|
|
||||||
---
|
|
||||||
test/zdtm/static/Makefile | 3 +
|
|
||||||
test/zdtm/static/selinux01.c | 200 +++++++++++++++++++++++++++
|
|
||||||
test/zdtm/static/selinux01.checkskip | 1 +
|
|
||||||
test/zdtm/static/selinux01.desc | 1 +
|
|
||||||
test/zdtm/static/selinux01.hook | 1 +
|
|
||||||
test/zdtm/static/selinux02.c | 1 +
|
|
||||||
test/zdtm/static/selinux02.checkskip | 1 +
|
|
||||||
test/zdtm/static/selinux02.desc | 1 +
|
|
||||||
test/zdtm/static/selinux02.hook | 1 +
|
|
||||||
9 files changed, 210 insertions(+)
|
|
||||||
create mode 100644 test/zdtm/static/selinux01.c
|
|
||||||
create mode 120000 test/zdtm/static/selinux01.checkskip
|
|
||||||
create mode 120000 test/zdtm/static/selinux01.desc
|
|
||||||
create mode 120000 test/zdtm/static/selinux01.hook
|
|
||||||
create mode 120000 test/zdtm/static/selinux02.c
|
|
||||||
create mode 120000 test/zdtm/static/selinux02.checkskip
|
|
||||||
create mode 120000 test/zdtm/static/selinux02.desc
|
|
||||||
create mode 120000 test/zdtm/static/selinux02.hook
|
|
||||||
|
|
||||||
diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile
|
|
||||||
index 8e3f39276a..1ffaa90394 100644
|
|
||||||
--- a/test/zdtm/static/Makefile
|
|
||||||
+++ b/test/zdtm/static/Makefile
|
|
||||||
@@ -211,6 +211,8 @@ TST_NOFILE := \
|
|
||||||
thp_disable \
|
|
||||||
pid_file \
|
|
||||||
selinux00 \
|
|
||||||
+ selinux01 \
|
|
||||||
+ selinux02 \
|
|
||||||
# jobctl00 \
|
|
||||||
|
|
||||||
ifneq ($(SRCARCH),arm)
|
|
||||||
@@ -513,6 +515,7 @@ unlink_fstat041: CFLAGS += -DUNLINK_FSTAT041 -DUNLINK_FSTAT04
|
|
||||||
ghost_holes01: CFLAGS += -DTAIL_HOLE
|
|
||||||
ghost_holes02: CFLAGS += -DHEAD_HOLE
|
|
||||||
sk-freebind-false: CFLAGS += -DZDTM_FREEBIND_FALSE
|
|
||||||
+selinux02: CFLAGS += -DUSING_SOCKCREATE
|
|
||||||
stopped01: CFLAGS += -DZDTM_STOPPED_KILL
|
|
||||||
stopped02: CFLAGS += -DZDTM_STOPPED_TKILL
|
|
||||||
stopped12: CFLAGS += -DZDTM_STOPPED_KILL -DZDTM_STOPPED_TKILL
|
|
||||||
diff --git a/test/zdtm/static/selinux01.c b/test/zdtm/static/selinux01.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000..9966455c47
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/test/zdtm/static/selinux01.c
|
|
||||||
@@ -0,0 +1,200 @@
|
|
||||||
+#include <unistd.h>
|
|
||||||
+#include <stdio.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+#include <string.h>
|
|
||||||
+#include <fcntl.h>
|
|
||||||
+#include <sys/stat.h>
|
|
||||||
+#include <sys/types.h>
|
|
||||||
+#include <sys/mount.h>
|
|
||||||
+#include <sys/socket.h>
|
|
||||||
+#include <sys/xattr.h>
|
|
||||||
+#include <linux/limits.h>
|
|
||||||
+#include <signal.h>
|
|
||||||
+#include "zdtmtst.h"
|
|
||||||
+
|
|
||||||
+/* Enabling the right policy happens in selinux00.hook and selinx00.checkskip */
|
|
||||||
+
|
|
||||||
+const char *test_doc = "Check that a SELinux socket context is restored";
|
|
||||||
+const char *test_author = "Adrian Reber <areber@redhat.com>";
|
|
||||||
+
|
|
||||||
+/* This is all based on Tycho's apparmor code */
|
|
||||||
+
|
|
||||||
+#define CONTEXT "unconfined_u:unconfined_r:unconfined_dbusd_t:s0"
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * This is used to store the state of SELinux. For this test
|
|
||||||
+ * SELinux is switched to permissive mode and later the previous
|
|
||||||
+ * SELinux state is restored.
|
|
||||||
+ */
|
|
||||||
+char state;
|
|
||||||
+
|
|
||||||
+int check_for_selinux()
|
|
||||||
+{
|
|
||||||
+ if (access("/sys/fs/selinux", F_OK) == 0)
|
|
||||||
+ return 0;
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int setprofile()
|
|
||||||
+{
|
|
||||||
+ int fd, len;
|
|
||||||
+
|
|
||||||
+ fd = open("/proc/self/attr/current", O_WRONLY);
|
|
||||||
+ if (fd < 0) {
|
|
||||||
+ fail("Could not open /proc/self/attr/current\n");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ len = write(fd, CONTEXT, strlen(CONTEXT));
|
|
||||||
+ close(fd);
|
|
||||||
+
|
|
||||||
+ if (len < 0) {
|
|
||||||
+ fail("Could not write context\n");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int set_sockcreate()
|
|
||||||
+{
|
|
||||||
+ int fd, len;
|
|
||||||
+
|
|
||||||
+ fd = open("/proc/self/attr/sockcreate", O_WRONLY);
|
|
||||||
+ if (fd < 0) {
|
|
||||||
+ fail("Could not open /proc/self/attr/sockcreate\n");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ len = write(fd, CONTEXT, strlen(CONTEXT));
|
|
||||||
+ close(fd);
|
|
||||||
+
|
|
||||||
+ if (len < 0) {
|
|
||||||
+ fail("Could not write context\n");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int check_sockcreate()
|
|
||||||
+{
|
|
||||||
+ int fd;
|
|
||||||
+ char context[1024];
|
|
||||||
+ int len;
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ fd = open("/proc/self/attr/sockcreate", O_RDONLY);
|
|
||||||
+ if (fd < 0) {
|
|
||||||
+ fail("Could not open /proc/self/attr/sockcreate\n");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ len = read(fd, context, strlen(CONTEXT));
|
|
||||||
+ close(fd);
|
|
||||||
+ if (len != strlen(CONTEXT)) {
|
|
||||||
+ fail("SELinux context has unexpected length %d, expected %zd\n",
|
|
||||||
+ len, strlen(CONTEXT));
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (strncmp(context, CONTEXT, strlen(CONTEXT)) != 0) {
|
|
||||||
+ fail("Wrong SELinux context %s expected %s\n", context, CONTEXT);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int check_sockcreate_empty()
|
|
||||||
+{
|
|
||||||
+ char *output = NULL;
|
|
||||||
+ FILE *f = fopen("/proc/self/attr/sockcreate", "r");
|
|
||||||
+ int ret = fscanf(f, "%ms", &output);
|
|
||||||
+ fclose(f);
|
|
||||||
+
|
|
||||||
+ if (ret >= 1) {
|
|
||||||
+ free(output);
|
|
||||||
+ /* sockcreate should be empty, if fscanf found something
|
|
||||||
+ * it is wrong.*/
|
|
||||||
+ fail("sockcreate should be empty\n");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (output) {
|
|
||||||
+ free(output);
|
|
||||||
+ /* Same here, output should still be NULL. */
|
|
||||||
+ fail("sockcreate should be empty\n");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int main(int argc, char **argv)
|
|
||||||
+{
|
|
||||||
+ char ctx[1024];
|
|
||||||
+ test_init(argc, argv);
|
|
||||||
+
|
|
||||||
+ if (check_for_selinux()) {
|
|
||||||
+ skip("SELinux not found on this system.");
|
|
||||||
+ test_daemon();
|
|
||||||
+ test_waitsig();
|
|
||||||
+ pass();
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+#ifdef USING_SOCKCREATE
|
|
||||||
+ if (set_sockcreate())
|
|
||||||
+ return -1;
|
|
||||||
+#else
|
|
||||||
+ if (check_sockcreate_empty())
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ if (setprofile())
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ if (check_sockcreate_empty())
|
|
||||||
+ return -1;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ /* Open our test socket */
|
|
||||||
+ int sk = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
+ memset(ctx, 0, 1024);
|
|
||||||
+ /* Read out the socket label */
|
|
||||||
+ if (fgetxattr(sk, "security.selinux", ctx, 1024) == -1) {
|
|
||||||
+ fail("Reading xattr 'security.selinux' failed.\n");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ if (strncmp(ctx, CONTEXT, strlen(CONTEXT)) != 0) {
|
|
||||||
+ fail("Wrong SELinux context %s expected %s\n", ctx, CONTEXT);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ memset(ctx, 0, 1024);
|
|
||||||
+
|
|
||||||
+ test_daemon();
|
|
||||||
+ test_waitsig();
|
|
||||||
+
|
|
||||||
+ /* Read out the socket label again */
|
|
||||||
+
|
|
||||||
+ if (fgetxattr(sk, "security.selinux", ctx, 1024) == -1) {
|
|
||||||
+ fail("Reading xattr 'security.selinux' failed.\n");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ if (strncmp(ctx, CONTEXT, strlen(CONTEXT)) != 0) {
|
|
||||||
+ fail("Wrong SELinux context %s expected %s\n", ctx, CONTEXT);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+#ifdef USING_SOCKCREATE
|
|
||||||
+ if (check_sockcreate())
|
|
||||||
+ return -1;
|
|
||||||
+#else
|
|
||||||
+ if (check_sockcreate_empty())
|
|
||||||
+ return -1;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ pass();
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
diff --git a/test/zdtm/static/selinux01.checkskip b/test/zdtm/static/selinux01.checkskip
|
|
||||||
new file mode 120000
|
|
||||||
index 0000000000..e8a172479e
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/test/zdtm/static/selinux01.checkskip
|
|
||||||
@@ -0,0 +1 @@
|
|
||||||
+selinux00.checkskip
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/test/zdtm/static/selinux01.desc b/test/zdtm/static/selinux01.desc
|
|
||||||
new file mode 120000
|
|
||||||
index 0000000000..2d2961a764
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/test/zdtm/static/selinux01.desc
|
|
||||||
@@ -0,0 +1 @@
|
|
||||||
+selinux00.desc
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/test/zdtm/static/selinux01.hook b/test/zdtm/static/selinux01.hook
|
|
||||||
new file mode 120000
|
|
||||||
index 0000000000..dd7ed6bb33
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/test/zdtm/static/selinux01.hook
|
|
||||||
@@ -0,0 +1 @@
|
|
||||||
+selinux00.hook
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/test/zdtm/static/selinux02.c b/test/zdtm/static/selinux02.c
|
|
||||||
new file mode 120000
|
|
||||||
index 0000000000..5702677858
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/test/zdtm/static/selinux02.c
|
|
||||||
@@ -0,0 +1 @@
|
|
||||||
+selinux01.c
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/test/zdtm/static/selinux02.checkskip b/test/zdtm/static/selinux02.checkskip
|
|
||||||
new file mode 120000
|
|
||||||
index 0000000000..2696e6e3de
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/test/zdtm/static/selinux02.checkskip
|
|
||||||
@@ -0,0 +1 @@
|
|
||||||
+selinux01.checkskip
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/test/zdtm/static/selinux02.desc b/test/zdtm/static/selinux02.desc
|
|
||||||
new file mode 120000
|
|
||||||
index 0000000000..9c6802c4da
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/test/zdtm/static/selinux02.desc
|
|
||||||
@@ -0,0 +1 @@
|
|
||||||
+selinux01.desc
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/test/zdtm/static/selinux02.hook b/test/zdtm/static/selinux02.hook
|
|
||||||
new file mode 120000
|
|
||||||
index 0000000000..e3ea0a6c80
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/test/zdtm/static/selinux02.hook
|
|
||||||
@@ -0,0 +1 @@
|
|
||||||
+selinux01.hook
|
|
||||||
\ No newline at end of file
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
From 80d90c5c59e9477d8a0c9eb727a0fc1bec2b01ea Mon Sep 17 00:00:00 2001
|
|
||||||
From: Andrei Vagin <avagin@gmail.com>
|
|
||||||
Date: Sat, 4 May 2019 20:01:52 -0700
|
|
||||||
Subject: [PATCH] lsm: don't reset socket contex if SELinux is disabled
|
|
||||||
|
|
||||||
Fixes #693
|
|
||||||
---
|
|
||||||
criu/lsm.c | 16 ++++++++++++++--
|
|
||||||
1 file changed, 14 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/criu/lsm.c b/criu/lsm.c
|
|
||||||
index 9c9ac7f80e..5921138392 100644
|
|
||||||
--- a/criu/lsm.c
|
|
||||||
+++ b/criu/lsm.c
|
|
||||||
@@ -134,7 +134,15 @@ static int selinux_get_sockcreate_label(pid_t pid, char **output)
|
|
||||||
|
|
||||||
int reset_setsockcreatecon()
|
|
||||||
{
|
|
||||||
- return setsockcreatecon_raw(NULL);
|
|
||||||
+ /* Currently this only works for SELinux. */
|
|
||||||
+ if (kdat.lsm != LSMTYPE__SELINUX)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ if (setsockcreatecon_raw(NULL)) {
|
|
||||||
+ pr_perror("Unable to reset socket SELinux context");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int run_setsockcreatecon(FdinfoEntry *e)
|
|
||||||
@@ -147,7 +155,11 @@ int run_setsockcreatecon(FdinfoEntry *e)
|
|
||||||
|
|
||||||
ctx = e->xattr_security_selinux;
|
|
||||||
/* Writing to the FD using fsetxattr() did not work for some reason. */
|
|
||||||
- return setsockcreatecon_raw(ctx);
|
|
||||||
+ if (setsockcreatecon_raw(ctx)) {
|
|
||||||
+ pr_perror("Unable to set the %s socket SELinux context", ctx);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dump_xattr_security_selinux(int fd, FdinfoEntry *e)
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
From b9e9e3903c78ba5d243b4176e82bf4b82342cb6a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Adrian Reber <areber@redhat.com>
|
|
||||||
Date: Sat, 4 May 2019 15:27:32 +0200
|
|
||||||
Subject: [PATCH] lsm: fix compiler error on Fedora 30
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
This fixes following compiler error:
|
|
||||||
|
|
||||||
criu/lsm.c: In function ‘dump_xattr_security_selinux’:
|
|
||||||
criu/include/log.h:51:2: error: ‘%s’ directive argument is null [-Werror=format-overflow=]
|
|
||||||
51 | print_on_level(LOG_ERROR, \
|
|
||||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
52 | "Error (%s:%d): " LOG_PREFIX fmt, \
|
|
||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
53 | __FILE__, __LINE__, ##__VA_ARGS__)
|
|
||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
criu/lsm.c:166:3: note: in expansion of macro ‘pr_err’
|
|
||||||
166 | pr_err("Reading xattr %s to FD %d failed\n", ctx, fd);
|
|
||||||
| ^~~~~~
|
|
||||||
|
|
||||||
Signed-off-by: Adrian Reber <areber@redhat.com>
|
|
||||||
---
|
|
||||||
criu/lsm.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/criu/lsm.c b/criu/lsm.c
|
|
||||||
index 5921138392..420585ba4f 100644
|
|
||||||
--- a/criu/lsm.c
|
|
||||||
+++ b/criu/lsm.c
|
|
||||||
@@ -175,7 +175,7 @@ int dump_xattr_security_selinux(int fd, FdinfoEntry *e)
|
|
||||||
/* Get the size of the xattr. */
|
|
||||||
len = fgetxattr(fd, "security.selinux", ctx, 0);
|
|
||||||
if (len == -1) {
|
|
||||||
- pr_err("Reading xattr %s to FD %d failed\n", ctx, fd);
|
|
||||||
+ pr_err("Reading xattr security.selinux from FD %d failed\n", fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
941
SOURCES/compel-handle-rseq-in-generic-compel-code.patch
Normal file
941
SOURCES/compel-handle-rseq-in-generic-compel-code.patch
Normal file
@ -0,0 +1,941 @@
|
|||||||
|
diff --git a/Documentation/compel.txt b/Documentation/compel.txt
|
||||||
|
index 506228f592..cdca1e6229 100644
|
||||||
|
--- a/Documentation/compel.txt
|
||||||
|
+++ b/Documentation/compel.txt
|
||||||
|
@@ -93,7 +93,7 @@ The parasitic code is compiled and converted to a header using *compel*, and inc
|
||||||
|
Following steps are performed to infect the victim process:
|
||||||
|
|
||||||
|
- stop the task: *int compel_stop_task(int pid);*
|
||||||
|
- - prepare infection handler: *struct parasite_ctl *compel_prepare(int pid);*
|
||||||
|
+ - prepare infection handler: *struct parasite_ctl *compel_prepare(int pid, bool handle_rseq);*
|
||||||
|
- execute system call: *int compel_syscall(ctl, int syscall_nr, long *ret, int arg ...);*
|
||||||
|
- infect victim: *int compel_infect(ctl, nr_thread, size_of_args_area);*
|
||||||
|
- cure the victim: *int compel_cure(ctl);* //ctl pointer is freed by this call
|
||||||
|
diff --git a/compel/include/uapi/infect.h b/compel/include/uapi/infect.h
|
||||||
|
index 4bbf57c4db..f88d91b1e0 100644
|
||||||
|
--- a/compel/include/uapi/infect.h
|
||||||
|
+++ b/compel/include/uapi/infect.h
|
||||||
|
@@ -47,12 +47,12 @@ extern int compel_resume_task_sig(pid_t pid, int orig_state, int state, int stop
|
||||||
|
struct parasite_ctl;
|
||||||
|
struct parasite_thread_ctl;
|
||||||
|
|
||||||
|
-extern struct parasite_ctl __must_check *compel_prepare(int pid);
|
||||||
|
-extern struct parasite_ctl __must_check *compel_prepare_noctx(int pid);
|
||||||
|
+extern struct parasite_ctl __must_check *compel_prepare(int pid, bool handle_rseq);
|
||||||
|
+extern struct parasite_ctl __must_check *compel_prepare_noctx(int pid, bool handle_rseq);
|
||||||
|
extern int __must_check compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size);
|
||||||
|
extern int __must_check compel_infect_no_daemon(struct parasite_ctl *ctl, unsigned long nr_threads,
|
||||||
|
unsigned long args_size);
|
||||||
|
-extern struct parasite_thread_ctl __must_check *compel_prepare_thread(struct parasite_ctl *ctl, int pid);
|
||||||
|
+extern struct parasite_thread_ctl __must_check *compel_prepare_thread(struct parasite_ctl *ctl, int pid, bool handle_rseq);
|
||||||
|
extern void compel_release_thread(struct parasite_thread_ctl *);
|
||||||
|
|
||||||
|
extern int __must_check compel_start_daemon(struct parasite_ctl *ctl);
|
||||||
|
diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c
|
||||||
|
index 8f44dbfc3e..b4764ce836 100644
|
||||||
|
--- a/compel/src/lib/infect.c
|
||||||
|
+++ b/compel/src/lib/infect.c
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#include "common/xmalloc.h"
|
||||||
|
#include "common/lock.h"
|
||||||
|
#include "common/page.h"
|
||||||
|
+#include "linux/rseq.h"
|
||||||
|
|
||||||
|
#include <compel/plugins/std/syscall-codes.h>
|
||||||
|
#include <compel/plugins/std/asm/syscall-types.h>
|
||||||
|
@@ -42,7 +43,7 @@
|
||||||
|
#define SECCOMP_MODE_DISABLED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-static int prepare_thread(int pid, struct thread_ctx *ctx);
|
||||||
|
+static int prepare_thread(int pid, struct thread_ctx *ctx, bool handle_rseq);
|
||||||
|
|
||||||
|
static inline void close_safe(int *pfd)
|
||||||
|
{
|
||||||
|
@@ -1111,13 +1112,13 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-struct parasite_thread_ctl *compel_prepare_thread(struct parasite_ctl *ctl, int pid)
|
||||||
|
+struct parasite_thread_ctl *compel_prepare_thread(struct parasite_ctl *ctl, int pid, bool handle_rseq)
|
||||||
|
{
|
||||||
|
struct parasite_thread_ctl *tctl;
|
||||||
|
|
||||||
|
tctl = xmalloc(sizeof(*tctl));
|
||||||
|
if (tctl) {
|
||||||
|
- if (prepare_thread(pid, &tctl->th)) {
|
||||||
|
+ if (prepare_thread(pid, &tctl->th, handle_rseq)) {
|
||||||
|
xfree(tctl);
|
||||||
|
tctl = NULL;
|
||||||
|
} else {
|
||||||
|
@@ -1129,7 +1130,117 @@ struct parasite_thread_ctl *compel_prepare_thread(struct parasite_ctl *ctl, int
|
||||||
|
return tctl;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int prepare_thread(int pid, struct thread_ctx *ctx)
|
||||||
|
+#define decode_pointer(x) ((void *)(unsigned long)(x))
|
||||||
|
+
|
||||||
|
+static bool task_in_rseq(struct criu_rseq_cs *rseq_cs, uint64_t addr)
|
||||||
|
+{
|
||||||
|
+ return addr - rseq_cs->start_ip < rseq_cs->post_commit_offset;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int read_rseq_cs(pid_t tid, struct __ptrace_rseq_configuration *rseqc, struct criu_rseq_cs *rseq_cs,
|
||||||
|
+ struct criu_rseq *rseq)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ if (!rseqc->rseq_abi_pointer)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ ret = ptrace_peek_area(tid, rseq,
|
||||||
|
+ decode_pointer(rseqc->rseq_abi_pointer),
|
||||||
|
+ sizeof(struct criu_rseq));
|
||||||
|
+ if (ret) {
|
||||||
|
+ pr_err("ptrace_peek_area(%d, %lx, %lx, %lx): fail to read rseq struct\n",
|
||||||
|
+ tid, (unsigned long)rseq, (unsigned long)rseqc->rseq_abi_pointer,
|
||||||
|
+ (unsigned long)sizeof(struct criu_rseq));
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!rseq->rseq_cs)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ ret = ptrace_peek_area(tid, rseq_cs,
|
||||||
|
+ decode_pointer(rseq->rseq_cs),
|
||||||
|
+ sizeof(struct criu_rseq_cs));
|
||||||
|
+ if (ret) {
|
||||||
|
+ pr_err("ptrace_peek_area(%d, %lx, %lx, %lx): fail to read rseq_cs struct\n",
|
||||||
|
+ tid, (unsigned long)rseq_cs, (unsigned long)rseq->rseq_cs,
|
||||||
|
+ (unsigned long)sizeof(struct criu_rseq_cs));
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * parasite_thread_rseq checks if the victim process is in an rseq critical
|
||||||
|
+ * section and, if so, aborts it.
|
||||||
|
+ */
|
||||||
|
+static int parasite_thread_rseq(int pid, struct thread_ctx *ctx)
|
||||||
|
+{
|
||||||
|
+ struct criu_rseq_cs _rseq_cs = {}, *rseq_cs = &_rseq_cs;
|
||||||
|
+ struct __ptrace_rseq_configuration rseqc;
|
||||||
|
+ int ret;
|
||||||
|
+ struct criu_rseq rseq = {};
|
||||||
|
+
|
||||||
|
+ ret = ptrace(PTRACE_GET_RSEQ_CONFIGURATION, pid, sizeof(rseqc), &rseqc);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ pr_perror("ptrace(PTRACE_GET_RSEQ_CONFIGURATION, %d) = %d", pid, ret);
|
||||||
|
+ return -1;
|
||||||
|
+ } else if (ret != sizeof(rseqc)) {
|
||||||
|
+ pr_err("ptrace(PTRACE_GET_RSEQ_CONFIGURATION, %d) returned unexpected size %d\n", pid, ret);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (rseqc.flags != 0) {
|
||||||
|
+ pr_err("something wrong with ptrace(PTRACE_GET_RSEQ_CONFIGURATION, %d) flags = 0x%x\n", pid,
|
||||||
|
+ rseqc.flags);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pr_debug("rseq of %d: ptr = 0x%lx sign = 0x%x\n", pid, (unsigned long)rseqc.rseq_abi_pointer,
|
||||||
|
+ rseqc.signature);
|
||||||
|
+
|
||||||
|
+ if (read_rseq_cs(pid, &rseqc, rseq_cs, &rseq))
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ if (rseq.rseq_cs) {
|
||||||
|
+ uint64_t zero_addr = 0;
|
||||||
|
+
|
||||||
|
+ pr_debug(
|
||||||
|
+ "fixup_thread_rseq for %d: rseq_cs start_ip = %llx abort_ip = %llx post_commit_offset = %llx flags = %x version = %x; IP = %lx\n",
|
||||||
|
+ pid, rseq_cs->start_ip, rseq_cs->abort_ip, rseq_cs->post_commit_offset, rseq_cs->flags,
|
||||||
|
+ rseq_cs->version, (unsigned long)REG_IP(ctx->regs));
|
||||||
|
+
|
||||||
|
+ if (rseq_cs->version != 0) {
|
||||||
|
+ pr_err("unsupported RSEQ ABI version = %d\n", rseq_cs->version);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (rseq.flags || rseq_cs->flags)
|
||||||
|
+ pr_warn("deprecated rseq flags are ignored for %d: rseq.flags = %#x rseq_cs.flags = %#x\n",
|
||||||
|
+ pid, rseq.flags, rseq_cs->flags);
|
||||||
|
+
|
||||||
|
+ if (task_in_rseq(rseq_cs, REG_IP(ctx->regs))) {
|
||||||
|
+ SET_REG_IP(ctx->regs, rseq_cs->abort_ip);
|
||||||
|
+ if (ptrace_set_regs(pid, &ctx->regs)) {
|
||||||
|
+ pr_perror("Can't apply rseq abort registers (pid: %d)", pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ptrace_poke_area(pid, &zero_addr,
|
||||||
|
+ decode_pointer(rseqc.rseq_abi_pointer) +
|
||||||
|
+ offsetof(struct criu_rseq, rseq_cs),
|
||||||
|
+ sizeof(zero_addr))) {
|
||||||
|
+ pr_err("ptrace_poke_area(%d) failed to zero out rseq_cs\n", pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int prepare_thread(int pid, struct thread_ctx *ctx, bool handle_rseq)
|
||||||
|
{
|
||||||
|
if (ptrace(PTRACE_GETSIGMASK, pid, sizeof(k_rtsigset_t), &ctx->sigmask)) {
|
||||||
|
pr_perror("can't get signal blocking mask for %d", pid);
|
||||||
|
@@ -1141,6 +1252,11 @@ static int prepare_thread(int pid, struct thread_ctx *ctx)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (handle_rseq && parasite_thread_rseq(pid, ctx)) {
|
||||||
|
+ pr_err("Can't handle rseq (pid: %d)\n", pid);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1153,7 +1269,7 @@ void compel_release_thread(struct parasite_thread_ctl *tctl)
|
||||||
|
xfree(tctl);
|
||||||
|
}
|
||||||
|
|
||||||
|
-struct parasite_ctl *compel_prepare_noctx(int pid)
|
||||||
|
+struct parasite_ctl *compel_prepare_noctx(int pid, bool handle_rseq)
|
||||||
|
{
|
||||||
|
struct parasite_ctl *ctl = NULL;
|
||||||
|
|
||||||
|
@@ -1170,7 +1286,7 @@ struct parasite_ctl *compel_prepare_noctx(int pid)
|
||||||
|
ctl->tsock = -1;
|
||||||
|
ctl->ictx.log_fd = -1;
|
||||||
|
|
||||||
|
- if (prepare_thread(pid, &ctl->orig))
|
||||||
|
+ if (prepare_thread(pid, &ctl->orig, handle_rseq))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
ctl->rpid = pid;
|
||||||
|
@@ -1346,12 +1462,12 @@ static int make_sigframe_plain(void *from, struct rt_sigframe *f, struct rt_sigf
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-struct parasite_ctl *compel_prepare(int pid)
|
||||||
|
+struct parasite_ctl *compel_prepare(int pid, bool handle_rseq)
|
||||||
|
{
|
||||||
|
struct parasite_ctl *ctl;
|
||||||
|
struct infect_ctx *ictx;
|
||||||
|
|
||||||
|
- ctl = compel_prepare_noctx(pid);
|
||||||
|
+ ctl = compel_prepare_noctx(pid, handle_rseq);
|
||||||
|
if (ctl == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
diff --git a/compel/test/fdspy/spy.c b/compel/test/fdspy/spy.c
|
||||||
|
index 41de99e200..35a6805715 100644
|
||||||
|
--- a/compel/test/fdspy/spy.c
|
||||||
|
+++ b/compel/test/fdspy/spy.c
|
||||||
|
@@ -39,7 +39,7 @@ static int do_infection(int pid, int *stolen_fd)
|
||||||
|
err_and_ret("Can't stop task");
|
||||||
|
|
||||||
|
printf("Preparing parasite ctl\n");
|
||||||
|
- ctl = compel_prepare(pid);
|
||||||
|
+ ctl = compel_prepare(pid, false);
|
||||||
|
if (!ctl)
|
||||||
|
err_and_ret("Can't prepare for infection");
|
||||||
|
|
||||||
|
diff --git a/compel/test/infect/spy.c b/compel/test/infect/spy.c
|
||||||
|
index 143946941e..da9b2d729a 100644
|
||||||
|
--- a/compel/test/infect/spy.c
|
||||||
|
+++ b/compel/test/infect/spy.c
|
||||||
|
@@ -38,7 +38,7 @@ static int do_infection(int pid)
|
||||||
|
err_and_ret("Can't stop task");
|
||||||
|
|
||||||
|
printf("Preparing parasite ctl\n");
|
||||||
|
- ctl = compel_prepare(pid);
|
||||||
|
+ ctl = compel_prepare(pid, false);
|
||||||
|
if (!ctl)
|
||||||
|
err_and_ret("Can't prepare for infection");
|
||||||
|
|
||||||
|
diff --git a/compel/test/rsys/spy.c b/compel/test/rsys/spy.c
|
||||||
|
index 4a6fcef29c..ca5630332f 100644
|
||||||
|
--- a/compel/test/rsys/spy.c
|
||||||
|
+++ b/compel/test/rsys/spy.c
|
||||||
|
@@ -33,7 +33,7 @@ static int do_rsetsid(int pid)
|
||||||
|
err_and_ret("Can't stop task");
|
||||||
|
|
||||||
|
printf("Preparing parasite ctl\n");
|
||||||
|
- ctl = compel_prepare(pid);
|
||||||
|
+ ctl = compel_prepare(pid, false);
|
||||||
|
if (!ctl)
|
||||||
|
err_and_ret("Can't prepare for infection");
|
||||||
|
|
||||||
|
diff --git a/compel/test/stack/spy.c b/compel/test/stack/spy.c
|
||||||
|
index 184c8ab318..d0ac16e718 100644
|
||||||
|
--- a/compel/test/stack/spy.c
|
||||||
|
+++ b/compel/test/stack/spy.c
|
||||||
|
@@ -123,7 +123,7 @@ static int do_infection(int pid)
|
||||||
|
err_and_ret("Can't stop task\n");
|
||||||
|
|
||||||
|
printf("Preparing parasite ctl\n");
|
||||||
|
- ctl = compel_prepare(pid);
|
||||||
|
+ ctl = compel_prepare(pid, false);
|
||||||
|
if (!ctl)
|
||||||
|
err_and_ret("Can't prepare for infection\n");
|
||||||
|
|
||||||
|
diff --git a/criu/cr-dump.c b/criu/cr-dump.c
|
||||||
|
index 6fe7c42e4e..fe3a3edd38 100644
|
||||||
|
--- a/criu/cr-dump.c
|
||||||
|
+++ b/criu/cr-dump.c
|
||||||
|
@@ -30,6 +30,7 @@
|
||||||
|
#include "images/siginfo.pb-c.h"
|
||||||
|
|
||||||
|
#include "common/list.h"
|
||||||
|
+#include "linux/rseq.h"
|
||||||
|
#include "imgset.h"
|
||||||
|
#include "file-ids.h"
|
||||||
|
#include "kcmp-ids.h"
|
||||||
|
@@ -908,72 +909,6 @@ static int collect_file_locks(void)
|
||||||
|
return parse_file_locks();
|
||||||
|
}
|
||||||
|
|
||||||
|
-static bool task_in_rseq(struct criu_rseq_cs *rseq_cs, uint64_t addr)
|
||||||
|
-{
|
||||||
|
- return addr >= rseq_cs->start_ip && addr < rseq_cs->start_ip + rseq_cs->post_commit_offset;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int fixup_thread_rseq(const struct pstree_item *item, int i)
|
||||||
|
-{
|
||||||
|
- CoreEntry *core = item->core[i];
|
||||||
|
- struct criu_rseq_cs *rseq_cs = &dmpi(item)->thread_rseq_cs[i];
|
||||||
|
- pid_t tid = item->threads[i].real;
|
||||||
|
-
|
||||||
|
- if (!kdat.has_ptrace_get_rseq_conf)
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
- /* equivalent to (struct rseq)->rseq_cs is NULL */
|
||||||
|
- if (!rseq_cs->start_ip)
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
- pr_debug(
|
||||||
|
- "fixup_thread_rseq for %d: rseq_cs start_ip = %llx abort_ip = %llx post_commit_offset = %llx flags = %x version = %x; IP = %lx\n",
|
||||||
|
- tid, rseq_cs->start_ip, rseq_cs->abort_ip, rseq_cs->post_commit_offset, rseq_cs->flags,
|
||||||
|
- rseq_cs->version, (unsigned long)TI_IP(core));
|
||||||
|
-
|
||||||
|
- if (rseq_cs->version != 0) {
|
||||||
|
- pr_err("unsupported RSEQ ABI version = %d\n", rseq_cs->version);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (task_in_rseq(rseq_cs, TI_IP(core))) {
|
||||||
|
- struct pid *tid = &item->threads[i];
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * We need to fixup task instruction pointer from
|
||||||
|
- * the original one (which lays inside rseq critical section)
|
||||||
|
- * to rseq abort handler address. But we need to look on rseq_cs->flags
|
||||||
|
- * (please refer to struct rseq -> flags field description).
|
||||||
|
- * Naive idea of flags support may be like... let's change instruction pointer (IP)
|
||||||
|
- * to rseq_cs->abort_ip if !(rseq_cs->flags & RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL).
|
||||||
|
- * But unfortunately, it doesn't work properly, because the kernel does
|
||||||
|
- * clean up of rseq_cs field in the struct rseq (modifies userspace memory).
|
||||||
|
- * So, we need to preserve original value of (struct rseq)->rseq_cs field in the
|
||||||
|
- * image and restore it's value before releasing threads (see restore_rseq_cs()).
|
||||||
|
- *
|
||||||
|
- * It's worth to mention that we need to fixup IP in CoreEntry
|
||||||
|
- * (used when full dump/restore is performed) and also in
|
||||||
|
- * the parasite regs storage (used if --leave-running option is used,
|
||||||
|
- * or if dump error occurred and process execution is resumed).
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- if (!(rseq_cs->flags & RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL)) {
|
||||||
|
- pr_warn("The %d task is in rseq critical section. IP will be set to rseq abort handler addr\n",
|
||||||
|
- tid->real);
|
||||||
|
-
|
||||||
|
- TI_IP(core) = rseq_cs->abort_ip;
|
||||||
|
-
|
||||||
|
- if (item->pid->real == tid->real) {
|
||||||
|
- compel_set_leader_ip(dmpi(item)->parasite_ctl, rseq_cs->abort_ip);
|
||||||
|
- } else {
|
||||||
|
- compel_set_thread_ip(dmpi(item)->thread_ctls[i], rseq_cs->abort_ip);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int dump_task_thread(struct parasite_ctl *parasite_ctl, const struct pstree_item *item, int id)
|
||||||
|
{
|
||||||
|
struct parasite_thread_ctl *tctl = dmpi(item)->thread_ctls[id];
|
||||||
|
@@ -997,12 +932,6 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl, const struct pstr
|
||||||
|
core->thread_core->creds->lsm_profile = dmpi(item)->thread_lsms[id]->profile;
|
||||||
|
core->thread_core->creds->lsm_sockcreate = dmpi(item)->thread_lsms[0]->sockcreate;
|
||||||
|
|
||||||
|
- ret = fixup_thread_rseq(item, id);
|
||||||
|
- if (ret) {
|
||||||
|
- pr_err("Can't fixup rseq for pid %d\n", pid);
|
||||||
|
- goto err;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
img = open_image(CR_FD_CORE, O_DUMP, tid->ns[0].virt);
|
||||||
|
if (!img)
|
||||||
|
goto err;
|
||||||
|
@@ -1148,48 +1077,6 @@ static int dump_task_signals(pid_t pid, struct pstree_item *item)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int read_rseq_cs(pid_t tid, struct __ptrace_rseq_configuration *rseqc, struct criu_rseq_cs *rseq_cs,
|
||||||
|
- struct criu_rseq *rseq)
|
||||||
|
-{
|
||||||
|
- int ret;
|
||||||
|
-
|
||||||
|
- /* rseq is not registered */
|
||||||
|
- if (!rseqc->rseq_abi_pointer)
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * We need to cover the case when victim process was inside rseq critical section
|
||||||
|
- * at the moment when CRIU comes and seized it. We need to determine the borders
|
||||||
|
- * of rseq critical section at first. To achieve that we need to access thread
|
||||||
|
- * memory and read pointer to struct rseq_cs.
|
||||||
|
- *
|
||||||
|
- * We have two ways to access thread memory: from the parasite and using ptrace().
|
||||||
|
- * But it this case we can't use parasite, because if victim process returns to the
|
||||||
|
- * execution, on the kernel side __rseq_handle_notify_resume hook will be called,
|
||||||
|
- * then rseq_ip_fixup() -> clear_rseq_cs() and user space memory with struct rseq
|
||||||
|
- * will be cleared. So, let's use ptrace(PTRACE_PEEKDATA).
|
||||||
|
- */
|
||||||
|
- ret = ptrace_peek_area(tid, rseq, decode_pointer(rseqc->rseq_abi_pointer), sizeof(struct criu_rseq));
|
||||||
|
- if (ret) {
|
||||||
|
- pr_err("ptrace_peek_area(%d, %lx, %lx, %lx): fail to read rseq struct\n", tid, (unsigned long)rseq,
|
||||||
|
- (unsigned long)(rseqc->rseq_abi_pointer), (unsigned long)sizeof(uint64_t));
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!rseq->rseq_cs)
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
- ret = ptrace_peek_area(tid, rseq_cs, decode_pointer(rseq->rseq_cs), sizeof(struct criu_rseq_cs));
|
||||||
|
- if (ret) {
|
||||||
|
- pr_err("ptrace_peek_area(%d, %lx, %lx, %lx): fail to read rseq_cs struct\n", tid,
|
||||||
|
- (unsigned long)rseq_cs, (unsigned long)rseq->rseq_cs,
|
||||||
|
- (unsigned long)sizeof(struct criu_rseq_cs));
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int dump_thread_rseq(struct pstree_item *item, int i)
|
||||||
|
{
|
||||||
|
struct __ptrace_rseq_configuration rseqc;
|
||||||
|
@@ -1197,8 +1084,6 @@ static int dump_thread_rseq(struct pstree_item *item, int i)
|
||||||
|
int ret;
|
||||||
|
CoreEntry *core = item->core[i];
|
||||||
|
RseqEntry **rseqep = &core->thread_core->rseq_entry;
|
||||||
|
- struct criu_rseq rseq = {};
|
||||||
|
- struct criu_rseq_cs *rseq_cs = &dmpi(item)->thread_rseq_cs[i];
|
||||||
|
pid_t tid = item->threads[i].real;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -1237,56 +1122,26 @@ static int dump_thread_rseq(struct pstree_item *item, int i)
|
||||||
|
rseqe->rseq_abi_size = rseqc.rseq_abi_size;
|
||||||
|
rseqe->signature = rseqc.signature;
|
||||||
|
|
||||||
|
- if (read_rseq_cs(tid, &rseqc, rseq_cs, &rseq))
|
||||||
|
- goto err;
|
||||||
|
-
|
||||||
|
- /* we won't save rseq_cs to the image (only pointer),
|
||||||
|
- * so let's combine flags from both struct rseq and struct rseq_cs
|
||||||
|
- * (kernel does the same when interpreting RSEQ_CS_FLAG_*)
|
||||||
|
- */
|
||||||
|
- rseq_cs->flags |= rseq.flags;
|
||||||
|
-
|
||||||
|
- if (rseq_cs->flags & RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL) {
|
||||||
|
- rseqe->has_rseq_cs_pointer = true;
|
||||||
|
- rseqe->rseq_cs_pointer = rseq.rseq_cs;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/* save rseq entry to the image */
|
||||||
|
*rseqep = rseqe;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
-
|
||||||
|
-err:
|
||||||
|
- xfree(rseqe);
|
||||||
|
- return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dump_task_rseq(pid_t pid, struct pstree_item *item)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
- struct criu_rseq_cs *thread_rseq_cs;
|
||||||
|
|
||||||
|
/* if rseq() syscall isn't supported then nothing to dump */
|
||||||
|
if (!kdat.has_rseq)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- thread_rseq_cs = xzalloc(sizeof(*thread_rseq_cs) * item->nr_threads);
|
||||||
|
- if (!thread_rseq_cs)
|
||||||
|
- return -1;
|
||||||
|
-
|
||||||
|
- dmpi(item)->thread_rseq_cs = thread_rseq_cs;
|
||||||
|
-
|
||||||
|
for (i = 0; i < item->nr_threads; i++) {
|
||||||
|
if (dump_thread_rseq(item, i))
|
||||||
|
- goto free_rseq;
|
||||||
|
+ return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
-
|
||||||
|
-free_rseq:
|
||||||
|
- xfree(thread_rseq_cs);
|
||||||
|
- dmpi(item)->thread_rseq_cs = NULL;
|
||||||
|
- return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct proc_pid_stat pps_buf;
|
||||||
|
@@ -1306,8 +1161,6 @@ static int dump_task_threads(struct parasite_ctl *parasite_ctl, const struct pst
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- xfree(dmpi(item)->thread_rseq_cs);
|
||||||
|
- dmpi(item)->thread_rseq_cs = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1632,12 +1485,6 @@ static int dump_one_task(struct pstree_item *item, InventoryEntry *parent_ie)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = fixup_thread_rseq(item, 0);
|
||||||
|
- if (ret) {
|
||||||
|
- pr_err("Fixup rseq for %d failed %d\n", pid, ret);
|
||||||
|
- goto err;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (fault_injected(FI_DUMP_EARLY)) {
|
||||||
|
pr_info("fault: CRIU sudden detach\n");
|
||||||
|
kill(getpid(), SIGKILL);
|
||||||
|
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
|
||||||
|
index 7579639a20..d8164366a0 100644
|
||||||
|
--- a/criu/cr-restore.c
|
||||||
|
+++ b/criu/cr-restore.c
|
||||||
|
@@ -25,6 +25,13 @@
|
||||||
|
|
||||||
|
#include "linux/rseq.h"
|
||||||
|
|
||||||
|
+#ifdef __has_include
|
||||||
|
+#if __has_include("sys/rseq.h")
|
||||||
|
+#include <sys/rseq.h>
|
||||||
|
+#include "asm/thread_pointer.h"
|
||||||
|
+#endif
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#include "clone-noasan.h"
|
||||||
|
#include "cr_options.h"
|
||||||
|
#include "servicefd.h"
|
||||||
|
@@ -1922,7 +1929,7 @@ static void finalize_restore(void)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Unmap the restorer blob */
|
||||||
|
- ctl = compel_prepare_noctx(pid);
|
||||||
|
+ ctl = compel_prepare_noctx(pid, false);
|
||||||
|
if (ctl == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
diff --git a/criu/include/pstree.h b/criu/include/pstree.h
|
||||||
|
index b750a919e6..b501ded721 100644
|
||||||
|
--- a/criu/include/pstree.h
|
||||||
|
+++ b/criu/include/pstree.h
|
||||||
|
@@ -63,7 +63,6 @@ struct dmp_info {
|
||||||
|
struct parasite_ctl *parasite_ctl;
|
||||||
|
struct parasite_thread_ctl **thread_ctls;
|
||||||
|
uint64_t *thread_sp;
|
||||||
|
- struct criu_rseq_cs *thread_rseq_cs;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Although we don't support dumping different struct creds in general,
|
||||||
|
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
|
||||||
|
index c2d9ad976b..1d8a388c85 100644
|
||||||
|
--- a/criu/parasite-syscall.c
|
||||||
|
+++ b/criu/parasite-syscall.c
|
||||||
|
@@ -339,6 +339,7 @@ static int make_sigframe(void *arg, struct rt_sigframe *sf, struct rt_sigframe *
|
||||||
|
|
||||||
|
static int parasite_prepare_threads(struct parasite_ctl *ctl, struct pstree_item *item)
|
||||||
|
{
|
||||||
|
+ bool handle_rseq = kdat.has_ptrace_get_rseq_conf;
|
||||||
|
struct parasite_thread_ctl **thread_ctls;
|
||||||
|
uint64_t *thread_sp;
|
||||||
|
int i;
|
||||||
|
@@ -359,7 +360,7 @@ static int parasite_prepare_threads(struct parasite_ctl *ctl, struct pstree_item
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- thread_ctls[i] = compel_prepare_thread(ctl, tid->real);
|
||||||
|
+ thread_ctls[i] = compel_prepare_thread(ctl, tid->real, handle_rseq);
|
||||||
|
if (!thread_ctls[i])
|
||||||
|
goto free_sp;
|
||||||
|
|
||||||
|
@@ -380,6 +381,7 @@ static int parasite_prepare_threads(struct parasite_ctl *ctl, struct pstree_item
|
||||||
|
|
||||||
|
struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, struct vm_area_list *vma_area_list)
|
||||||
|
{
|
||||||
|
+ bool handle_rseq = kdat.has_ptrace_get_rseq_conf;
|
||||||
|
struct parasite_ctl *ctl;
|
||||||
|
struct infect_ctx *ictx;
|
||||||
|
unsigned long p;
|
||||||
|
@@ -393,7 +395,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ctl = compel_prepare_noctx(pid);
|
||||||
|
+ ctl = compel_prepare_noctx(pid, handle_rseq);
|
||||||
|
if (!ctl)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
diff --git a/criu/include/linux/rseq.h b/include/linux/rseq.h
|
||||||
|
similarity index 98%
|
||||||
|
rename from criu/include/linux/rseq.h
|
||||||
|
rename to include/linux/rseq.h
|
||||||
|
index 5ceefbf8e1..4ffc1a4f37 100644
|
||||||
|
--- a/criu/include/linux/rseq.h
|
||||||
|
+++ b/include/linux/rseq.h
|
||||||
|
@@ -2,13 +2,6 @@
|
||||||
|
#ifndef _UAPI_LINUX_RSEQ_H
|
||||||
|
#define _UAPI_LINUX_RSEQ_H
|
||||||
|
|
||||||
|
-#ifdef __has_include
|
||||||
|
-#if __has_include("sys/rseq.h")
|
||||||
|
-#include <sys/rseq.h>
|
||||||
|
-#include "asm/thread_pointer.h"
|
||||||
|
-#endif
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
|
@@ -43,6 +36,8 @@ enum rseq_cs_flags {
|
||||||
|
RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL = (1U << RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL_BIT),
|
||||||
|
RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE = (1U << RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE_BIT),
|
||||||
|
};
|
||||||
|
+#else
|
||||||
|
+#include <sys/rseq.h>
|
||||||
|
#endif /* CONFIG_HAS_NO_LIBC_RSEQ_DEFS */
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/test/zdtm/transition/Makefile b/test/zdtm/transition/Makefile
|
||||||
|
index ddf2faaad1..8ed9248c7e 100644
|
||||||
|
--- a/test/zdtm/transition/Makefile
|
||||||
|
+++ b/test/zdtm/transition/Makefile
|
||||||
|
@@ -25,6 +25,7 @@ TST_NOFILE = \
|
||||||
|
pidfd_store_sk \
|
||||||
|
rseq01 \
|
||||||
|
rseq02 \
|
||||||
|
+ rseq03 \
|
||||||
|
stack \
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/test/zdtm/transition/rseq03.c b/test/zdtm/transition/rseq03.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..5f3633b71b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/zdtm/transition/rseq03.c
|
||||||
|
@@ -0,0 +1,287 @@
|
||||||
|
+/*
|
||||||
|
+ * test for rseq() syscall
|
||||||
|
+ * See also https://www.efficios.com/blog/2019/02/08/linux-restartable-sequences/
|
||||||
|
+ * https://github.com/torvalds/linux/commit/d7822b1e24f2df5df98c76f0e94a5416349ff759
|
||||||
|
+ */
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <signal.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <sys/wait.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+#include <sys/mman.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <pthread.h>
|
||||||
|
+#include <syscall.h>
|
||||||
|
+
|
||||||
|
+#include "zdtmtst.h"
|
||||||
|
+#include "lock.h"
|
||||||
|
+
|
||||||
|
+#ifdef __has_include
|
||||||
|
+#if __has_include("sys/rseq.h")
|
||||||
|
+#include <sys/rseq.h>
|
||||||
|
+#endif
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if defined(__x86_64__)
|
||||||
|
+
|
||||||
|
+#if defined(RSEQ_SIG)
|
||||||
|
+static inline void *__criu_thread_pointer(void)
|
||||||
|
+{
|
||||||
|
+#if __GNUC_PREREQ(11, 1)
|
||||||
|
+ return __builtin_thread_pointer();
|
||||||
|
+#else
|
||||||
|
+ void *__result;
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ __asm__("mov %%fs:0, %0" : "=r"(__result));
|
||||||
|
+#else
|
||||||
|
+ __asm__("mov %%gs:0, %0" : "=r"(__result));
|
||||||
|
+#endif /* __x86_64__ */
|
||||||
|
+ return __result;
|
||||||
|
+#endif /* !GCC 11 */
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void unregister_glibc_rseq(void)
|
||||||
|
+{
|
||||||
|
+ struct rseq *rseq = (struct rseq *)((char *)__criu_thread_pointer() + __rseq_offset);
|
||||||
|
+ unsigned int size = __rseq_size;
|
||||||
|
+
|
||||||
|
+ /* hack: mark glibc rseq structure as failed to register */
|
||||||
|
+ rseq->cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED;
|
||||||
|
+
|
||||||
|
+ /* unregister rseq */
|
||||||
|
+ if (__rseq_size < 32)
|
||||||
|
+ size = 32;
|
||||||
|
+ syscall(__NR_rseq, (void *)rseq, size, 1, RSEQ_SIG);
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+static inline void unregister_glibc_rseq(void)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+#endif /* defined(RSEQ_SIG) */
|
||||||
|
+
|
||||||
|
+const char *test_doc = "Check rseq() critical section abort during C/R";
|
||||||
|
+const char *test_author = "Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>";
|
||||||
|
+
|
||||||
|
+#ifndef RSEQ_SIG
|
||||||
|
+
|
||||||
|
+enum rseq_flags {
|
||||||
|
+ RSEQ_FLAG_UNREGISTER = (1 << 0),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct rseq {
|
||||||
|
+ uint32_t cpu_id_start;
|
||||||
|
+ uint32_t cpu_id;
|
||||||
|
+ uint64_t rseq_cs;
|
||||||
|
+ uint32_t flags;
|
||||||
|
+} __attribute__((aligned(4 * sizeof(uint64_t))));
|
||||||
|
+
|
||||||
|
+struct rseq_cs {
|
||||||
|
+ /* Version of this structure. */
|
||||||
|
+ uint32_t version;
|
||||||
|
+ /* enum rseq_cs_flags */
|
||||||
|
+ uint32_t flags;
|
||||||
|
+ uint64_t start_ip;
|
||||||
|
+ /* Offset from start_ip. */
|
||||||
|
+ uint64_t post_commit_offset;
|
||||||
|
+ uint64_t abort_ip;
|
||||||
|
+} __attribute__((aligned(4 * sizeof(__u64))));
|
||||||
|
+
|
||||||
|
+#define RSEQ_SIG 0x53053053
|
||||||
|
+
|
||||||
|
+#endif /* RSEQ_SIG */
|
||||||
|
+
|
||||||
|
+#ifndef __NR_rseq
|
||||||
|
+#define __NR_rseq 334
|
||||||
|
+#endif
|
||||||
|
+/* EOF */
|
||||||
|
+
|
||||||
|
+extern futex_t sig_received;
|
||||||
|
+
|
||||||
|
+static __thread volatile struct rseq __rseq_abi __attribute__((aligned(64)));
|
||||||
|
+static __thread volatile struct rseq_cs __rseq_cs __attribute__((aligned(64)));
|
||||||
|
+
|
||||||
|
+static __thread volatile int rseq_state = 0;
|
||||||
|
+
|
||||||
|
+static int sys_rseq(volatile struct rseq *rseq_abi, uint32_t rseq_len, int flags, uint32_t sig)
|
||||||
|
+{
|
||||||
|
+ return syscall(__NR_rseq, rseq_abi, rseq_len, flags, sig);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Return the rseq registration size. Starting with Linux 7.0,
|
||||||
|
+ * AT_RSEQ_ALIGN is 64 but the feature size is 33, so sizeof(struct rseq)
|
||||||
|
+ * (padded to alignment) no longer matches the registration size the kernel
|
||||||
|
+ * expects. Use __rseq_size when available, clamped to a minimum of 32
|
||||||
|
+ * for older kernels.
|
||||||
|
+ */
|
||||||
|
+static uint32_t rseq_reg_size(void)
|
||||||
|
+{
|
||||||
|
+#if defined(RSEQ_SIG) && defined(__rseq_size)
|
||||||
|
+ if (__rseq_size)
|
||||||
|
+ return (__rseq_size < 32) ? 32 : __rseq_size;
|
||||||
|
+#endif
|
||||||
|
+ return sizeof(struct rseq);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static unsigned long mmap_min_addr = 0x10000UL;
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Machine code for x86_64 that emulates:
|
||||||
|
+ * __rseq_abi.rseq_cs = &__rseq_cs;
|
||||||
|
+ * rseq_state = 1;
|
||||||
|
+ * while (futex_get(f) == 0) {
|
||||||
|
+ * if (__rseq_abi.rseq_cs != &__rseq_cs)
|
||||||
|
+ * return;
|
||||||
|
+ * }
|
||||||
|
+ * __rseq_abi.rseq_cs = 0;
|
||||||
|
+ * rseq_state = 0;
|
||||||
|
+ *
|
||||||
|
+ * Disassembly:
|
||||||
|
+ * 0x0: 48 89 37 mov %rsi,(%rdi) // set __rseq_abi.rseq_cs = &__rseq_cs
|
||||||
|
+ * 0x3: c7 01 01 00 00 00 movl $1,(%rcx) // set rseq_state = 1
|
||||||
|
+ * 0x9: 48 39 37 cmp %rsi,(%rdi) // check if __rseq_abi.rseq_cs == &__rseq_cs
|
||||||
|
+ * 0xc: 75 13 jne 0x21 // if not equal, break out (jump to ret)
|
||||||
|
+ * 0xe: 8b 02 mov (%rdx),%eax // load *f
|
||||||
|
+ * 0x10: 85 c0 test %eax,%eax // check if 0
|
||||||
|
+ * 0x12: 74 f5 je 0x9 // spin while *f == 0
|
||||||
|
+ * 0x14: 48 c7 07 00 00 00 00 movq $0,(%rdi) // clear __rseq_abi.rseq_cs on exit
|
||||||
|
+ * 0x1b: c7 01 00 00 00 00 movl $0,(%rcx) // set rseq_state = 0
|
||||||
|
+ * 0x21: c3 ret // return
|
||||||
|
+ */
|
||||||
|
+static const uint8_t test_go_rseq_code[] = {
|
||||||
|
+ 0x48, 0x89, 0x37,
|
||||||
|
+ 0xc7, 0x01, 0x01, 0x00, 0x00, 0x00,
|
||||||
|
+ 0x48, 0x39, 0x37,
|
||||||
|
+ 0x75, 0x13,
|
||||||
|
+ 0x8b, 0x02,
|
||||||
|
+ 0x85, 0xc0,
|
||||||
|
+ 0x74, 0xf5,
|
||||||
|
+ 0x48, 0xc7, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0xc3,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Machine code for the rseq abort section:
|
||||||
|
+ * rseq_state = 0;
|
||||||
|
+ * return;
|
||||||
|
+ *
|
||||||
|
+ * Disassembly:
|
||||||
|
+ * 0: c7 01 00 00 00 00 movl $0,(%rcx) // set rseq_state = 0
|
||||||
|
+ * 6: c3 ret // return
|
||||||
|
+ */
|
||||||
|
+static const uint8_t test_go_rseq_abort_code[] = {
|
||||||
|
+ 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
+ 0xc3,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void register_thread(void)
|
||||||
|
+{
|
||||||
|
+ int rc;
|
||||||
|
+ void *addr;
|
||||||
|
+
|
||||||
|
+ addr = mmap((void *)mmap_min_addr, 4096, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||||
|
+ MAP_FIXED_NOREPLACE | MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||||
|
+ if (addr == MAP_FAILED)
|
||||||
|
+ addr = mmap(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||||
|
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||||
|
+ if (addr == MAP_FAILED) {
|
||||||
|
+ fail("Failed to mmap rseq critical section area");
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ memcpy(addr, test_go_rseq_code, sizeof(test_go_rseq_code));
|
||||||
|
+
|
||||||
|
+ __rseq_cs.start_ip = (uint64_t)addr;
|
||||||
|
+ __rseq_cs.post_commit_offset = 2048;
|
||||||
|
+ __rseq_cs.abort_ip = __rseq_cs.start_ip + 2048;
|
||||||
|
+ *((uint32_t *)__rseq_cs.abort_ip - 1) = RSEQ_SIG;
|
||||||
|
+ memcpy((void *)__rseq_cs.abort_ip, test_go_rseq_abort_code,
|
||||||
|
+ sizeof(test_go_rseq_abort_code));
|
||||||
|
+
|
||||||
|
+ unregister_glibc_rseq();
|
||||||
|
+ rc = sys_rseq(&__rseq_abi, rseq_reg_size(), 0, RSEQ_SIG);
|
||||||
|
+ if (rc) {
|
||||||
|
+ fail("Failed to register rseq");
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void check_thread(void)
|
||||||
|
+{
|
||||||
|
+ int rc;
|
||||||
|
+ rc = sys_rseq(&__rseq_abi, rseq_reg_size(), 0, RSEQ_SIG);
|
||||||
|
+ if (!(rc && errno == EBUSY)) {
|
||||||
|
+ fail("Failed to check rseq %d", rc);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void test_go_rseq(futex_t *f)
|
||||||
|
+{
|
||||||
|
+ void (*fn)(void *, volatile struct rseq_cs *, futex_t *, volatile int *) =
|
||||||
|
+ (void (*)(void *, volatile struct rseq_cs *, futex_t *, volatile int *))__rseq_cs.start_ip;
|
||||||
|
+
|
||||||
|
+ while (futex_get(f) == 0) {
|
||||||
|
+ fn((void *)&__rseq_abi.rseq_cs, &__rseq_cs, f, &rseq_state);
|
||||||
|
+ if (rseq_state != 0) {
|
||||||
|
+ fail("rseq_state is %d (expected 0)", rseq_state);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *tfunc(void *args)
|
||||||
|
+{
|
||||||
|
+ register_thread();
|
||||||
|
+ test_go_rseq(&sig_received);
|
||||||
|
+ check_thread();
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int main(int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ pthread_t th;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ test_init(argc, argv);
|
||||||
|
+
|
||||||
|
+ ret = pthread_create(&th, NULL, tfunc, NULL);
|
||||||
|
+ if (ret) {
|
||||||
|
+ pr_err("pthread_create -> %d\n", ret);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ register_thread();
|
||||||
|
+
|
||||||
|
+ test_daemon();
|
||||||
|
+ test_go_rseq(&sig_received);
|
||||||
|
+
|
||||||
|
+ ret = pthread_join(th, NULL);
|
||||||
|
+ if (ret) {
|
||||||
|
+ pr_err("pthread_join -> %d\n", ret);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ check_thread();
|
||||||
|
+
|
||||||
|
+ pass();
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#else /* #if defined(__x86_64__) */
|
||||||
|
+
|
||||||
|
+int main(int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ test_init(argc, argv);
|
||||||
|
+ skip("Unsupported arch");
|
||||||
|
+ test_daemon();
|
||||||
|
+ test_waitsig();
|
||||||
|
+ pass();
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* #if defined(__x86_64__) */
|
||||||
|
diff --git a/test/zdtm/transition/rseq03.desc b/test/zdtm/transition/rseq03.desc
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..113feaee18
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/zdtm/transition/rseq03.desc
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+{'arch': 'x86_64', 'feature': 'get_rseq_conf'}
|
||||||
27
SOURCES/criu.pc.patch
Normal file
27
SOURCES/criu.pc.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 341ef149ee259d9432ea4c01507eefab2ef8b83c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Radostin Stoyanov <radostin@redhat.com>
|
||||||
|
Date: Thu, 14 Oct 2021 12:58:56 +0100
|
||||||
|
Subject: [PATCH] criu.pc: Add libprotobuf-c as a dependency
|
||||||
|
|
||||||
|
CRIU has a dependency on protobuf-c-devel. We express this dependency
|
||||||
|
in pkgconfig to be auto-detected when building a package.
|
||||||
|
|
||||||
|
Signed-off-by: Radostin Stoyanov <radostin@redhat.com>
|
||||||
|
---
|
||||||
|
lib/c/criu.pc.in | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/lib/c/criu.pc.in b/lib/c/criu.pc.in
|
||||||
|
index 33986d10d..bcced5033 100644
|
||||||
|
--- a/lib/c/criu.pc.in
|
||||||
|
+++ b/lib/c/criu.pc.in
|
||||||
|
@@ -4,5 +4,6 @@ includedir=@includedir@
|
||||||
|
Name: CRIU
|
||||||
|
Description: RPC library for userspace checkpoint and restore
|
||||||
|
Version: @version@
|
||||||
|
+Requires.private: libprotobuf-c
|
||||||
|
Libs: -L${libdir} -lcriu
|
||||||
|
Cflags: -I${includedir}
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
303
SPECS/criu.spec
303
SPECS/criu.spec
@ -1,57 +1,45 @@
|
|||||||
%if 0%{?fedora} >= 27 || 0%{?rhel} > 7
|
|
||||||
%global py_prefix python3
|
%global py_prefix python3
|
||||||
%global py_binary %{py_prefix}
|
%global py_binary %{py_prefix}
|
||||||
%else
|
|
||||||
%global py_prefix python
|
|
||||||
%global py_binary python2
|
|
||||||
%endif
|
|
||||||
|
|
||||||
# With annobin enabled, CRIU does not work anymore. It seems CRIU's
|
# This package calls LD directly without specifying the LTO plugins. Until
|
||||||
# parasite code breaks if annobin is enabled.
|
# that is fixed, disable LTO.
|
||||||
%undefine _annotated_build
|
%global _lto_cflags %%{nil}
|
||||||
|
|
||||||
Name: criu
|
Name: criu
|
||||||
Version: 3.12
|
Version: 3.19
|
||||||
Release: 9%{?dist}
|
Release: 6%{?dist}
|
||||||
Provides: crtools = %{version}-%{release}
|
Provides: crtools = %{version}-%{release}
|
||||||
Obsoletes: crtools <= 1.0-2
|
Obsoletes: crtools <= 1.0-2
|
||||||
Summary: Tool for Checkpoint/Restore in User-space
|
Summary: Tool for Checkpoint/Restore in User-space
|
||||||
License: GPLv2
|
License: GPLv2
|
||||||
URL: http://criu.org/
|
URL: http://criu.org/
|
||||||
Source0: http://download.openvz.org/criu/criu-%{version}.tar.bz2
|
Source0: https://github.com/checkpoint-restore/criu/archive/v%{version}/criu-%{version}.tar.gz
|
||||||
|
Source1: criu-tmpfiles.conf
|
||||||
Patch0: https://patch-diff.githubusercontent.com/raw/checkpoint-restore/criu/pull/685.patch
|
|
||||||
Patch1: https://github.com/checkpoint-restore/criu/commit/1e84cb90b63bce841376140a7a80107e5ec1e1a8.patch
|
|
||||||
Patch2: https://github.com/checkpoint-restore/criu/commit/80d90c5c59e9477d8a0c9eb727a0fc1bec2b01ea.patch
|
|
||||||
Patch3: https://github.com/checkpoint-restore/criu/commit/b9e9e3903c78ba5d243b4176e82bf4b82342cb6a.patch
|
|
||||||
|
|
||||||
%if 0%{?rhel} && 0%{?rhel} <= 7
|
|
||||||
BuildRequires: perl
|
|
||||||
# RHEL has no asciidoc; take man-page from Fedora 26
|
|
||||||
# zcat /usr/share/man/man8/criu.8.gz > criu.8
|
|
||||||
Source1: criu.8
|
|
||||||
Source2: crit.1
|
|
||||||
# The patch aio-fix.patch is needed as RHEL7
|
|
||||||
# doesn't do "nr_events *= 2" in ioctx_alloc().
|
|
||||||
Patch100: aio-fix.patch
|
|
||||||
%endif
|
|
||||||
|
|
||||||
Source3: criu-tmpfiles.conf
|
|
||||||
|
|
||||||
BuildRequires: gcc
|
BuildRequires: gcc
|
||||||
BuildRequires: systemd
|
BuildRequires: systemd
|
||||||
BuildRequires: libnet-devel
|
BuildRequires: libnet-devel
|
||||||
BuildRequires: protobuf-devel protobuf-c-devel %{py_prefix}-devel libnl3-devel libcap-devel
|
BuildRequires: protobuf-devel protobuf-c-devel %{py_prefix}-devel libnl3-devel libcap-devel
|
||||||
%if 0%{?fedora} || 0%{?rhel} > 7
|
|
||||||
BuildRequires: asciidoc xmlto
|
BuildRequires: asciidoc xmlto
|
||||||
|
BuildRequires: %{py_prefix}-pip
|
||||||
|
BuildRequires: %{py_prefix}-protobuf
|
||||||
|
BuildRequires: %{py_prefix}-setuptools
|
||||||
|
BuildRequires: %{py_prefix}-wheel
|
||||||
BuildRequires: perl-interpreter
|
BuildRequires: perl-interpreter
|
||||||
BuildRequires: libselinux-devel
|
BuildRequires: libselinux-devel
|
||||||
|
BuildRequires: gnutls-devel
|
||||||
|
BuildRequires: make
|
||||||
# Checkpointing containers with a tmpfs requires tar
|
# Checkpointing containers with a tmpfs requires tar
|
||||||
Recommends: tar
|
Recommends: tar
|
||||||
%if 0%{?fedora}
|
Recommends: iptables
|
||||||
BuildRequires: libbsd-devel
|
|
||||||
%endif
|
Patch0: 0001-Fix-building-with-annobin.patch
|
||||||
%endif
|
Patch1: criu.pc.patch
|
||||||
|
Patch2: https://github.com/checkpoint-restore/criu/pull/2587.patch
|
||||||
|
# Update restartable sequences to latest upstream code
|
||||||
|
Patch3: https://github.com/checkpoint-restore/criu/commit/089345f77a34d1bc7ef146d650636afcd3cdda21.patch
|
||||||
|
|
||||||
|
# Based on https://github.com/checkpoint-restore/criu/pull/3097
|
||||||
|
Patch4: compel-handle-rseq-in-generic-compel-code.patch
|
||||||
|
|
||||||
# user-space and kernel changes are only available for x86_64, arm,
|
# user-space and kernel changes are only available for x86_64, arm,
|
||||||
# ppc64le, aarch64 and s390x
|
# ppc64le, aarch64 and s390x
|
||||||
@ -63,10 +51,10 @@ criu is the user-space part of Checkpoint/Restore in User-space
|
|||||||
(CRIU), a project to implement checkpoint/restore functionality for
|
(CRIU), a project to implement checkpoint/restore functionality for
|
||||||
Linux in user-space.
|
Linux in user-space.
|
||||||
|
|
||||||
%if 0%{?fedora}
|
|
||||||
%package devel
|
%package devel
|
||||||
Summary: Header files and libraries for %{name}
|
Summary: Header files and libraries for %{name}
|
||||||
Requires: %{name} = %{version}-%{release}
|
Requires: %{name} = %{version}-%{release}
|
||||||
|
Requires: %{name}-libs = %{version}-%{release}
|
||||||
|
|
||||||
%description devel
|
%description devel
|
||||||
This package contains header files and libraries for %{name}.
|
This package contains header files and libraries for %{name}.
|
||||||
@ -77,18 +65,12 @@ Requires: %{name} = %{version}-%{release}
|
|||||||
|
|
||||||
%description libs
|
%description libs
|
||||||
This package contains the libraries for %{name}
|
This package contains the libraries for %{name}
|
||||||
%endif
|
|
||||||
|
|
||||||
%package -n %{py_prefix}-%{name}
|
%package -n %{py_prefix}-%{name}
|
||||||
%{?python_provide:%python_provide %{py_prefix}-%{name}}
|
%{?python_provide:%python_provide %{py_prefix}-%{name}}
|
||||||
Summary: Python bindings for %{name}
|
Summary: Python bindings for %{name}
|
||||||
%if 0%{?rhel} && 0%{?rhel} <= 7
|
|
||||||
Requires: protobuf-python
|
|
||||||
Requires: %{name} = %{version}-%{release} %{py_prefix}-ipaddr
|
|
||||||
%else
|
|
||||||
Requires: %{py_prefix}-protobuf
|
Requires: %{py_prefix}-protobuf
|
||||||
Obsoletes: python2-criu < 3.10-1
|
Obsoletes: python2-criu < 3.10-1
|
||||||
%endif
|
|
||||||
|
|
||||||
%description -n %{py_prefix}-%{name}
|
%description -n %{py_prefix}-%{name}
|
||||||
%{py_prefix}-%{name} contains Python bindings for %{name}.
|
%{py_prefix}-%{name} contains Python bindings for %{name}.
|
||||||
@ -101,62 +83,69 @@ Requires: %{py_prefix}-%{name} = %{version}-%{release}
|
|||||||
crit is a tool designed to decode CRIU binary dump files and show
|
crit is a tool designed to decode CRIU binary dump files and show
|
||||||
their content in human-readable form.
|
their content in human-readable form.
|
||||||
|
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q
|
%setup -q
|
||||||
%patch0 -p1
|
%patch -P 0 -p1
|
||||||
%patch1 -p1
|
%patch -P 1 -p1
|
||||||
%patch2 -p1
|
%patch -P 2 -p1
|
||||||
%patch3 -p1
|
%patch -P 3 -p1
|
||||||
|
%patch -P 4 -p1
|
||||||
%if 0%{?rhel} && 0%{?rhel} <= 7
|
|
||||||
%patch100 -p1
|
|
||||||
%endif
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
# %{?_smp_mflags} does not work
|
# CRIU's parasite/restorer code (criu/pie/) is compiled with its own CFLAGS
|
||||||
# -fstack-protector breaks build
|
# that already disable hardening (-fno-stack-protector, -U_FORTIFY_SOURCE,
|
||||||
CFLAGS+=`echo %{optflags} | sed -e 's,-fstack-protector\S*,,g'` make V=1 WERROR=0 PREFIX=%{_prefix} RUNDIR=/run/criu PYTHON=%{py_binary}
|
# -D_FORTIFY_SOURCE=0, -nostdlib). Standard RHEL hardening flags (PIE, RELRO,
|
||||||
%if 0%{?fedora} || 0%{?rhel} > 7
|
# FORTIFY_SOURCE, stack protector) only affect the main criu binary and libs.
|
||||||
make docs V=1
|
#
|
||||||
%endif
|
# CRIU's nmk build system calls ld directly for intermediate partial linking
|
||||||
|
# (ld -r). RHEL LDFLAGS contain -specs= options that only gcc understands;
|
||||||
|
# raw ld rejects them. Create a wrapper that strips -specs= for direct ld
|
||||||
|
# calls. The final criu binary link uses gcc (CC), not ld, so it still gets
|
||||||
|
# full hardening (-pie, -z relro, -z now) from the spec files.
|
||||||
|
mkdir -p %{_builddir}/bin
|
||||||
|
cat > %{_builddir}/bin/ld << 'LDWRAPPER'
|
||||||
|
#!/bin/sh
|
||||||
|
for arg do
|
||||||
|
shift
|
||||||
|
case "$arg" in -specs=*) continue ;; esac
|
||||||
|
set -- "$@" "$arg"
|
||||||
|
done
|
||||||
|
exec /usr/bin/ld "$@"
|
||||||
|
LDWRAPPER
|
||||||
|
chmod +x %{_builddir}/bin/ld
|
||||||
|
|
||||||
|
# %{?_smp_mflags} does not work
|
||||||
|
CFLAGS+="%{optflags}" make V=1 WERROR=0 LD=%{_builddir}/bin/ld PREFIX=%{_prefix} RUNDIR=/run/criu PYTHON=%{py_binary}
|
||||||
|
make docs V=1
|
||||||
|
|
||||||
%install
|
%install
|
||||||
make install-criu DESTDIR=$RPM_BUILD_ROOT PREFIX=%{_prefix} LIBDIR=%{_libdir}
|
sed -e "s,--upgrade --ignore-installed,--no-index --no-deps -v --no-build-isolation,g" -i lib/Makefile -i crit/Makefile
|
||||||
make install-lib DESTDIR=$RPM_BUILD_ROOT PREFIX=%{_prefix} LIBDIR=%{_libdir} PYTHON=%{py_binary}
|
make install-criu LD=%{_builddir}/bin/ld DESTDIR=$RPM_BUILD_ROOT PREFIX=%{_prefix} LIBDIR=%{_libdir}
|
||||||
%if 0%{?fedora} || 0%{?rhel} > 7
|
make install-lib LD=%{_builddir}/bin/ld DESTDIR=$RPM_BUILD_ROOT PREFIX=%{_prefix} LIBDIR=%{_libdir} PYTHON=%{py_binary}
|
||||||
# only install documentation on Fedora as it requires asciidoc,
|
make install-crit LD=%{_builddir}/bin/ld DESTDIR=$RPM_BUILD_ROOT PREFIX=%{_prefix} LIBDIR=%{_libdir} PYTHON=%{py_binary}
|
||||||
# which is not available on RHEL7
|
make install-man LD=%{_builddir}/bin/ld DESTDIR=$RPM_BUILD_ROOT PREFIX=%{_prefix} LIBDIR=%{_libdir}
|
||||||
make install-man DESTDIR=$RPM_BUILD_ROOT PREFIX=%{_prefix} LIBDIR=%{_libdir}
|
|
||||||
%else
|
|
||||||
install -p -m 644 -D %{SOURCE1} $RPM_BUILD_ROOT%{_mandir}/man8/%{name}.8
|
|
||||||
install -p -m 644 -D %{SOURCE2} $RPM_BUILD_ROOT%{_mandir}/man1/crit.1
|
|
||||||
%endif
|
|
||||||
|
|
||||||
mkdir -p %{buildroot}%{_tmpfilesdir}
|
mkdir -p %{buildroot}%{_tmpfilesdir}
|
||||||
install -m 0644 %{SOURCE3} %{buildroot}%{_tmpfilesdir}/%{name}.conf
|
install -m 0644 %{SOURCE1} %{buildroot}%{_tmpfilesdir}/%{name}.conf
|
||||||
install -d -m 0755 %{buildroot}/run/%{name}/
|
install -d -m 0755 %{buildroot}/run/%{name}/
|
||||||
|
|
||||||
%if 0%{?rhel}
|
# remove static libs
|
||||||
# remove devel and libs packages
|
rm $RPM_BUILD_ROOT%{_libdir}/*.a
|
||||||
rm -rf $RPM_BUILD_ROOT%{_includedir}/criu
|
|
||||||
rm $RPM_BUILD_ROOT%{_libdir}/*.so*
|
|
||||||
rm -rf $RPM_BUILD_ROOT%{_libdir}/pkgconfig
|
|
||||||
rm -rf $RPM_BUILD_ROOT%{_libexecdir}/%{name}
|
rm -rf $RPM_BUILD_ROOT%{_libexecdir}/%{name}
|
||||||
%endif
|
# remove compel man-page
|
||||||
|
rm $RPM_BUILD_ROOT%{_mandir}/man1/compel.1*
|
||||||
|
# remove amdgpu plugin man-page
|
||||||
|
rm $RPM_BUILD_ROOT%{_mandir}/man1/criu-amdgpu-plugin.1*
|
||||||
|
# remove criu-ns
|
||||||
|
rm $RPM_BUILD_ROOT%{_sbindir}/criu-ns
|
||||||
|
rm $RPM_BUILD_ROOT%{_mandir}/man1/criu-ns.1*
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%{_sbindir}/%{name}
|
%{_sbindir}/%{name}
|
||||||
%doc %{_mandir}/man8/criu.8*
|
%{_mandir}/man8/criu.8*
|
||||||
%if 0%{?fedora}
|
|
||||||
%{_libexecdir}/%{name}
|
|
||||||
%endif
|
|
||||||
%dir /run/%{name}
|
%dir /run/%{name}
|
||||||
%{_tmpfilesdir}/%{name}.conf
|
%{_tmpfilesdir}/%{name}.conf
|
||||||
%doc README.md COPYING
|
%doc README.md COPYING
|
||||||
|
|
||||||
%if 0%{?fedora}
|
|
||||||
%files devel
|
%files devel
|
||||||
%{_includedir}/criu
|
%{_includedir}/criu
|
||||||
%{_libdir}/*.so
|
%{_libdir}/*.so
|
||||||
@ -164,24 +153,143 @@ rm -rf $RPM_BUILD_ROOT%{_libexecdir}/%{name}
|
|||||||
|
|
||||||
%files libs
|
%files libs
|
||||||
%{_libdir}/*.so.*
|
%{_libdir}/*.so.*
|
||||||
%endif
|
|
||||||
|
|
||||||
%files -n %{py_prefix}-%{name}
|
%files -n %{py_prefix}-%{name}
|
||||||
%if 0%{?rhel} && 0%{?rhel} <= 7
|
%{python3_sitelib}/pycriu*
|
||||||
%{python2_sitelib}/pycriu/*
|
|
||||||
%{python2_sitelib}/*egg-info
|
|
||||||
%else
|
|
||||||
%{python3_sitelib}/pycriu/*
|
|
||||||
%{python3_sitelib}/*egg-info
|
|
||||||
%endif
|
|
||||||
|
|
||||||
%files -n crit
|
%files -n crit
|
||||||
%{_bindir}/crit
|
%{_bindir}/crit
|
||||||
|
%{python3_sitelib}/crit-%{version}.dist-info
|
||||||
|
%{python3_sitelib}/crit
|
||||||
%doc %{_mandir}/man1/crit.1*
|
%doc %{_mandir}/man1/crit.1*
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Mon May 13 2019 Adrian Reber <adrian@lisas.de> - 3.12-9
|
* Mon Jul 20 2026 Adrian Reber <areber@redhat.com> - 3.19-6
|
||||||
|
- Handle rseq in generic compel code (checkpoint-restore/criu#3097)
|
||||||
|
|
||||||
|
* Thu Mar 05 2026 Adrian Reber <areber@redhat.com> - 3.19-5
|
||||||
|
- Recommends: iptables
|
||||||
|
|
||||||
|
* Mon Mar 02 2026 Christopher Lusk <clusk@redhat.com> - 3.19-4
|
||||||
|
- Re-enable binary hardening flags for main binary
|
||||||
|
|
||||||
|
* Thu May 08 2025 Adrian Reber <areber@redhat.com> - 3.19-3
|
||||||
|
- Added patch to correctly handle SELinux labels in Kubernetes
|
||||||
|
- Added latest upstream rseq patch
|
||||||
|
|
||||||
|
* Fri Dec 08 2023 Radostin Stoyanov <radostin@redhat.com> - 3.19-1
|
||||||
|
- Update to 3.19
|
||||||
|
- Drop upstreamed patches
|
||||||
|
|
||||||
|
* Tue Apr 25 2023 Adrian Reber <adrian@lisas.de> - 3.18-1
|
||||||
|
- Update to 3.18
|
||||||
|
- Apply patch from upstream to support newer CPUs
|
||||||
|
|
||||||
|
* Fri Mar 31 2023 Jindrich Novy <jnovy@redhat.com> - 3.17.1-1
|
||||||
|
- update to https://github.com/checkpoint-restore/criu/releases/tag/v3.17.1
|
||||||
|
- Related: #2176063
|
||||||
|
|
||||||
|
* Mon Jul 11 2022 Radostin Stoyanov <radostin@redhat.com> - 3.17-4
|
||||||
|
- Rebuilt to pick up glibc rseq() changes
|
||||||
|
|
||||||
|
* Mon Jul 04 2022 Radostin Stoyanov <radostin@redhat.com> - 3.17-3
|
||||||
|
- Add libprotobuf-c dependency requirement
|
||||||
|
|
||||||
|
* Mon May 09 2022 Adrian Reber <areber@redhat.com> - 3.17-2
|
||||||
|
- Update to 3.17
|
||||||
|
- Drop upstreamed patch
|
||||||
|
- Remove compel man-page
|
||||||
|
|
||||||
|
* Mon Jan 31 2022 Adrian Reber <areber@redhat.com> - 3.15-13
|
||||||
|
- Apply patch to build with annobin enabled
|
||||||
|
- Apply patch to fix unsafe IPv6 handling
|
||||||
|
|
||||||
|
* Mon Sep 6 2021 Radostin Stoyanov <radostin@redhat.com> - 3.15-12
|
||||||
|
- Increase release number from 11 to 12
|
||||||
|
- Disable podman test when crun doesn't support checkpoint/restore
|
||||||
|
|
||||||
|
* Tue Aug 31 2021 Adrian Reber <areber@redhat.com> - 3.15-11
|
||||||
|
- Remove unnecessary Requires: criu-libs
|
||||||
|
- Remove wrong BR nftables-devel
|
||||||
|
- Bump release for rebuild
|
||||||
|
|
||||||
|
* Mon Aug 16 2021 Jindrich Novy <jnovy@redhat.com> - 3.15-10
|
||||||
|
- disable LTO on RHEL9 again
|
||||||
|
- Related: #1970747
|
||||||
|
|
||||||
|
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 3.15-9
|
||||||
|
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
|
||||||
|
Related: rhbz#1991688
|
||||||
|
|
||||||
|
* Fri Aug 06 2021 Jindrich Novy <jnovy@redhat.com> - 3.15-8
|
||||||
|
- add Requires: criu-libs = %%{version}-%%{release} in criu-devel
|
||||||
|
- Related: #1970747
|
||||||
|
|
||||||
|
* Wed Aug 04 2021 Jindrich Novy <jnovy@redhat.com> - 3.15-7
|
||||||
|
- remove pre-RHEL9 hacks
|
||||||
|
|
||||||
|
* Wed May 05 2021 Adrian Reber <areber@redhat.com> - 3.15-6
|
||||||
|
- Enable criu-devel and criu-libs for RHEL 9
|
||||||
|
- Remove nftables-devel dependency for now
|
||||||
|
|
||||||
|
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 3.15-4
|
||||||
|
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
|
||||||
|
|
||||||
|
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.15-3
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
|
||||||
|
|
||||||
|
* Wed Jan 13 09:45:16 CET 2021 Adrian Reber <adrian@lisas.de> - 3.15-2
|
||||||
|
- Rebuilt for protobuf 3.14
|
||||||
|
|
||||||
|
* Wed Nov 04 2020 Adrian Reber <adrian@lisas.de> - 3.15-1
|
||||||
|
- Update to 3.15
|
||||||
|
|
||||||
|
* Wed Sep 23 2020 Adrian Reber <adrian@lisas.de> - 3.14-8
|
||||||
|
- Rebuilt for protobuf 3.13
|
||||||
|
|
||||||
|
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.14-7
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||||
|
|
||||||
|
* Tue Jul 14 2020 Jeff Law <law@redhat.com> - 3.14-6
|
||||||
|
- Disable LTO
|
||||||
|
|
||||||
|
* Sun Jun 14 2020 Adrian Reber <adrian@lisas.de> - 3.14-5
|
||||||
|
- Rebuilt for protobuf 3.12
|
||||||
|
|
||||||
|
* Tue May 26 2020 Miro Hrončok <mhroncok@redhat.com> - 3.14-4
|
||||||
|
- Rebuilt for Python 3.9
|
||||||
|
|
||||||
|
* Thu Apr 30 2020 Adrian Reber <adrian@lisas.de> - 3.14-3
|
||||||
|
- BuildRequire nftables-devel for working CI
|
||||||
|
|
||||||
|
* Thu Apr 30 2020 Adrian Reber <adrian@lisas.de> - 3.14-2
|
||||||
|
- Rebuild for CI fixes
|
||||||
|
|
||||||
|
* Wed Apr 29 2020 Adrian Reber <adrian@lisas.de> - 3.14-1
|
||||||
|
- Update to 3.14 (#1829399)
|
||||||
|
|
||||||
|
* Sun Mar 29 2020 Andrei Vagin <avagin@gmail.com> - 3.13-7
|
||||||
|
- Added patch for gcc-10
|
||||||
|
|
||||||
|
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.13-6
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
|
||||||
|
|
||||||
|
* Mon Sep 16 2019 Adrian Reber <adrian@lisas.de> - 3.13-5
|
||||||
|
- Update to 3.13 (#1751146)
|
||||||
|
- Drop upstreamed patches
|
||||||
|
- Drop static library
|
||||||
|
- Add compel man-page
|
||||||
|
|
||||||
|
* Mon Aug 19 2019 Miro Hrončok <mhroncok@redhat.com> - 3.12-14
|
||||||
|
- Rebuilt for Python 3.8
|
||||||
|
|
||||||
|
* Wed Jul 24 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.12-13
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
||||||
|
|
||||||
|
* Tue May 14 2019 Adrian Reber <adrian@lisas.de> - 3.12-11
|
||||||
|
- Test different decision_context in gating.yaml
|
||||||
|
|
||||||
|
* Mon May 13 2019 Adrian Reber <adrian@lisas.de> - 3.12-10
|
||||||
- Added additional fixup patches for the socket labelling
|
- Added additional fixup patches for the socket labelling
|
||||||
|
|
||||||
* Sat May 04 2019 Adrian Reber <adrian@lisas.de> - 3.12-8
|
* Sat May 04 2019 Adrian Reber <adrian@lisas.de> - 3.12-8
|
||||||
@ -202,16 +310,15 @@ rm -rf $RPM_BUILD_ROOT%{_libexecdir}/%{name}
|
|||||||
- Build against SELinux (Fedora and RHEL8)
|
- Build against SELinux (Fedora and RHEL8)
|
||||||
- Build against libbsd (Fedora)
|
- Build against libbsd (Fedora)
|
||||||
|
|
||||||
* Thu Feb 14 2019 Adrian Reber <areber@redhat.com> - 3.11-2
|
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.11-3
|
||||||
- Updated to 3.11
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
||||||
- Removed upstreamed patches
|
|
||||||
|
* Sat Jan 19 2019 Adrian Reber <adrian@lisas.de> - 3.11-2
|
||||||
- Added patch for gcc-9
|
- Added patch for gcc-9
|
||||||
|
|
||||||
* Tue Dec 11 2018 Adrian Reber <adrian@lisas.de> - 3.10-7
|
* Tue Nov 06 2018 Adrian Reber <adrian@lisas.de> - 3.11-1
|
||||||
- Fix 'criu check --feature link_nsid' with more than 10 interfaces (#1652442)
|
- Updated to 3.11
|
||||||
|
- Removed upstreamed patches
|
||||||
* Tue Dec 11 2018 Adrian Reber <adrian@lisas.de> - 3.10-6
|
|
||||||
- Make sure no iptables rules are left after restore (#1652471)
|
|
||||||
|
|
||||||
* Tue Oct 30 2018 Adrian Reber <adrian@lisas.de> - 3.10-5
|
* Tue Oct 30 2018 Adrian Reber <adrian@lisas.de> - 3.10-5
|
||||||
- Added Recommends: tar
|
- Added Recommends: tar
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user