From 6953579e74f74a4c493e9e696b99a04d9f47791d Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 05 2019 19:37:48 +0000 Subject: import criu-3.12-9.el8 --- diff --git a/.criu.metadata b/.criu.metadata index 81d32f2..f33f9a7 100644 --- a/.criu.metadata +++ b/.criu.metadata @@ -1 +1 @@ -a3598bc51ee354d7300b9862be92dc9f41e8b372 SOURCES/criu-3.10.tar.bz2 +b2ceaf9705aa8239915010136a59664d31044fe3 SOURCES/criu-3.12.tar.bz2 diff --git a/.gitignore b/.gitignore index a736559..d9f1e8d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/criu-3.10.tar.bz2 +SOURCES/criu-3.12.tar.bz2 diff --git a/SOURCES/1-2-Fix-building-with-4.18.patch b/SOURCES/1-2-Fix-building-with-4.18.patch deleted file mode 100644 index 93bbe65..0000000 --- a/SOURCES/1-2-Fix-building-with-4.18.patch +++ /dev/null @@ -1,241 +0,0 @@ -From patchwork Mon Jul 9 06:28:26 2018 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [1/2] Fix building with 4.18 -From: Adrian Reber -X-Patchwork-Id: 8849 -Message-Id: <1531117707-8173-2-git-send-email-adrian@lisas.de> -To: , Andrei Vagin -Cc: Adrian Reber -Date: Mon, 9 Jul 2018 06:28:26 +0000 - -From: Adrian Reber - -Building CRIU against 4.18 fails with multiple re-definition errors. -This has been reported upstream - https://lore.kernel.org/lkml/20180704142116.GM17048@lisas.de/ -but there has not been any answer yet. This tries to workaround those -compile errors by pulling the required aio defines directly into CRIU. - -Signed-off-by: Adrian Reber ---- - criu/cr-check.c | 2 +- - criu/include/aio.h | 73 ++++++++++++++++++++++++++++++++++++++++++++++- - criu/pie/restorer.c | 1 - - test/zdtm/static/aio01.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++-- - 4 files changed, 145 insertions(+), 5 deletions(-) - -diff --git a/criu/cr-check.c b/criu/cr-check.c -index d3393c4..fc53afb 100644 ---- a/criu/cr-check.c -+++ b/criu/cr-check.c -@@ -22,7 +22,6 @@ - #include - #include - #include --#include - - #include "../soccr/soccr.h" - -@@ -51,6 +50,7 @@ - #include "net.h" - #include "restorer.h" - #include "uffd.h" -+#include "aio.h" - - static char *feature_name(int (*func)()); - -diff --git a/criu/include/aio.h b/criu/include/aio.h -index 9a58089..a749c47 100644 ---- a/criu/include/aio.h -+++ b/criu/include/aio.h -@@ -1,7 +1,6 @@ - #ifndef __CR_AIO_H__ - #define __CR_AIO_H__ - --#include - #include "images/mm.pb-c.h" - unsigned int aio_estimate_nr_reqs(unsigned int size); - int dump_aio_ring(MmEntry *mme, struct vma_area *vma); -@@ -12,6 +11,78 @@ unsigned long aio_rings_args_size(struct vm_area_list *); - struct task_restore_args; - int prepare_aios(struct pstree_item *t, struct task_restore_args *ta); - -+/* copied from linux/fs.h */ -+typedef int __bitwise __kernel_rwf_t; -+ -+/* copied from linux/aio_abi.h */ -+#ifndef COMPEL_SYSCALL_TYPES_H__ -+/* The ifndef is needed to avoid a clang compiler error */ -+typedef __kernel_ulong_t aio_context_t; -+#endif -+ -+enum { -+ IOCB_CMD_PREAD = 0, -+ IOCB_CMD_PWRITE = 1, -+ IOCB_CMD_FSYNC = 2, -+ IOCB_CMD_FDSYNC = 3, -+ /* These two are experimental. -+ * IOCB_CMD_PREADX = 4, -+ * IOCB_CMD_POLL = 5, -+ */ -+ IOCB_CMD_NOOP = 6, -+ IOCB_CMD_PREADV = 7, -+ IOCB_CMD_PWRITEV = 8, -+}; -+/* read() from /dev/aio returns these structures. */ -+struct io_event { -+ __u64 data; /* the data field from the iocb */ -+ __u64 obj; /* what iocb this event came from */ -+ __s64 res; /* result code for this event */ -+ __s64 res2; /* secondary result */ -+}; -+ -+/* -+ * we always use a 64bit off_t when communicating -+ * with userland. its up to libraries to do the -+ * proper padding and aio_error abstraction -+ */ -+ -+struct iocb { -+ /* these are internal to the kernel/libc. */ -+ __u64 aio_data; /* data to be returned in event's data */ -+ -+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN) -+ __u32 aio_key; /* the kernel sets aio_key to the req # */ -+ __kernel_rwf_t aio_rw_flags; /* RWF_* flags */ -+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN) -+ __kernel_rwf_t aio_rw_flags; /* RWF_* flags */ -+ __u32 aio_key; /* the kernel sets aio_key to the req # */ -+#else -+#error edit for your odd byteorder. -+#endif -+ -+ /* common fields */ -+ __u16 aio_lio_opcode; /* see IOCB_CMD_ above */ -+ __s16 aio_reqprio; -+ __u32 aio_fildes; -+ -+ __u64 aio_buf; -+ __u64 aio_nbytes; -+ __s64 aio_offset; -+ -+ /* extra parameters */ -+ __u64 aio_reserved2; /* TODO: use this for a (struct sigevent *) */ -+ -+ /* flags for the "struct iocb" */ -+ __u32 aio_flags; -+ -+ /* -+ * if the IOCB_FLAG_RESFD flag of "aio_flags" is set, this is an -+ * eventfd to signal AIO readiness to -+ */ -+ __u32 aio_resfd; -+}; /* 64 bytes */ -+ - struct aio_ring { - unsigned id; /* kernel internal index number */ - unsigned nr; /* number of io_events */ -diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c -index 9b7f6dd..f100213 100644 ---- a/criu/pie/restorer.c -+++ b/criu/pie/restorer.c -@@ -3,7 +3,6 @@ - - #include - #include --#include - #include - #include - #include -diff --git a/test/zdtm/static/aio01.c b/test/zdtm/static/aio01.c -index f84fd35..4ad29a7 100644 ---- a/test/zdtm/static/aio01.c -+++ b/test/zdtm/static/aio01.c -@@ -1,6 +1,5 @@ --#include -+#include - #include --#include - #include - #include - #include -@@ -13,6 +12,77 @@ - const char *test_doc = "Check head and tail restore correct"; - const char *test_author = "Kirill Tkhai "; - -+/* copied from linux/fs.h */ -+typedef int __bitwise __kernel_rwf_t; -+ -+/* copied from linux/aio_abi.h */ -+#ifndef COMPEL_SYSCALL_TYPES_H__ -+typedef __kernel_ulong_t aio_context_t; -+#endif -+ -+enum { -+ IOCB_CMD_PREAD = 0, -+ IOCB_CMD_PWRITE = 1, -+ IOCB_CMD_FSYNC = 2, -+ IOCB_CMD_FDSYNC = 3, -+ /* These two are experimental. -+ * IOCB_CMD_PREADX = 4, -+ * IOCB_CMD_POLL = 5, -+ */ -+ IOCB_CMD_NOOP = 6, -+ IOCB_CMD_PREADV = 7, -+ IOCB_CMD_PWRITEV = 8, -+}; -+/* read() from /dev/aio returns these structures. */ -+struct io_event { -+ __u64 data; /* the data field from the iocb */ -+ __u64 obj; /* what iocb this event came from */ -+ __s64 res; /* result code for this event */ -+ __s64 res2; /* secondary result */ -+}; -+ -+/* -+ * we always use a 64bit off_t when communicating -+ * with userland. its up to libraries to do the -+ * proper padding and aio_error abstraction -+ */ -+ -+struct iocb { -+ /* these are internal to the kernel/libc. */ -+ __u64 aio_data; /* data to be returned in event's data */ -+ -+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN) -+ __u32 aio_key; /* the kernel sets aio_key to the req # */ -+ __kernel_rwf_t aio_rw_flags; /* RWF_* flags */ -+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN) -+ __kernel_rwf_t aio_rw_flags; /* RWF_* flags */ -+ __u32 aio_key; /* the kernel sets aio_key to the req # */ -+#else -+#error edit for your odd byteorder. -+#endif -+ -+ /* common fields */ -+ __u16 aio_lio_opcode; /* see IOCB_CMD_ above */ -+ __s16 aio_reqprio; -+ __u32 aio_fildes; -+ -+ __u64 aio_buf; -+ __u64 aio_nbytes; -+ __s64 aio_offset; -+ -+ /* extra parameters */ -+ __u64 aio_reserved2; /* TODO: use this for a (struct sigevent *) */ -+ -+ /* flags for the "struct iocb" */ -+ __u32 aio_flags; -+ -+ /* -+ * if the IOCB_FLAG_RESFD flag of "aio_flags" is set, this is an -+ * eventfd to signal AIO readiness to -+ */ -+ __u32 aio_resfd; -+}; /* 64 bytes */ -+ - struct aio_ring { - unsigned id; /* kernel internal index number */ - unsigned nr; /* number of io_events */ diff --git a/SOURCES/1e84cb90b63bce841376140a7a80107e5ec1e1a8.patch b/SOURCES/1e84cb90b63bce841376140a7a80107e5ec1e1a8.patch new file mode 100644 index 0000000..3b2fbd8 --- /dev/null +++ b/SOURCES/1e84cb90b63bce841376140a7a80107e5ec1e1a8.patch @@ -0,0 +1,67 @@ +From 1e84cb90b63bce841376140a7a80107e5ec1e1a8 Mon Sep 17 00:00:00 2001 +From: Adrian Reber +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 +Signed-off-by: Andrei Vagin +--- + 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; + } diff --git a/SOURCES/27034e7c64b00a1f2467afb5ebb1d5b9b1a06ce1.patch b/SOURCES/27034e7c64b00a1f2467afb5ebb1d5b9b1a06ce1.patch deleted file mode 100644 index 269236a..0000000 --- a/SOURCES/27034e7c64b00a1f2467afb5ebb1d5b9b1a06ce1.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 27034e7c64b00a1f2467afb5ebb1d5b9b1a06ce1 Mon Sep 17 00:00:00 2001 -From: Pavel Tikhomirov -Date: Wed, 11 Jul 2018 13:43:33 +0300 -Subject: [PATCH] mount: fix regression where open_mountpoint failed on - readonly fs - -If we fail to create temporary directory for doing a clean mount we can -make mount clean reusing the code which enters new mountns to umount -overmounts. As when last process exits mntns all mounts are implicitly -cleaned from children, see in kernel source - sys_exit->do_exit -->exit_task_namespaces->switch_task_namespaces->free_nsproxy -->put_mnt_ns->umount_tree->drop_collected_mounts->umount_tree: - - /* Hide the mounts from mnt_mounts */ - list_for_each_entry(p, &tmp_list, mnt_list) { - list_del_init(&p->mnt_child); - } - -Fixes commit b6cfb1ce2948 ("mount: make open_mountpoint handle overmouts -properly") - -https://github.com/checkpoint-restore/criu/issues/520 -Signed-off-by: Pavel Tikhomirov -Acked-by: Adrian Reber -Signed-off-by: Andrei Vagin ---- - criu/mount.c | 28 ++++++++++++++++++++-------- - 1 file changed, 20 insertions(+), 8 deletions(-) - -diff --git a/criu/mount.c b/criu/mount.c -index b56164e953..9cc8f6e940 100644 ---- a/criu/mount.c -+++ b/criu/mount.c -@@ -1325,10 +1325,18 @@ int ns_open_mountpoint(void *arg) - if (umount_overmounts(mi)) - goto err; - -- /* Save fd which we opened for parent due to CLONE_FILES flag */ -- *fd = get_clean_fd(mi); -- if (*fd < 0) -+ /* -+ * Save fd which we opened for parent due to CLONE_FILES flag -+ * -+ * Mount can still have children in it, but we don't need to clean it -+ * explicitly as when last process exits mntns all mounts in it are -+ * cleaned from their children, and we are exactly the last process. -+ */ -+ *fd = open(mi->mountpoint, O_DIRECTORY|O_RDONLY); -+ if (*fd < 0) { -+ pr_perror("Unable to open %s", mi->mountpoint); - goto err; -+ } - - return 0; - err: -@@ -1367,18 +1375,22 @@ int open_mountpoint(struct mount_info *pm) - - if (!mnt_is_overmounted(pm)) { - pr_info("\tmount has children %s\n", pm->mountpoint); -- - fd = get_clean_fd(pm); -- if (fd < 0) -- goto err; -- } else { -+ } -+ -+ /* -+ * Mount is overmounted or probably we can't create a temporary -+ * direcotry for a cleaned mount -+ */ -+ if (fd < 0) { - int pid, status; - struct clone_arg ca = { - .mi = pm, - .fd = &fd - }; - -- pr_info("\tmount is overmounted %s\n", pm->mountpoint); -+ pr_info("\tmount is overmounted or has children %s\n", -+ pm->mountpoint); - - /* - * We are overmounted - not accessible in a regular way. We diff --git a/SOURCES/685.patch b/SOURCES/685.patch new file mode 100644 index 0000000..30e1728 --- /dev/null +++ b/SOURCES/685.patch @@ -0,0 +1,834 @@ +From 3313343ba7803bff077af5d87df2260cdcd2d678 Mon Sep 17 00:00:00 2001 +From: Adrian Reber +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 + #include + #include ++#include + #include + + #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 +@@ -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 +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 +--- + 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#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 "; ++ ++/* 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 diff --git a/SOURCES/80d90c5c59e9477d8a0c9eb727a0fc1bec2b01ea.patch b/SOURCES/80d90c5c59e9477d8a0c9eb727a0fc1bec2b01ea.patch new file mode 100644 index 0000000..09446a6 --- /dev/null +++ b/SOURCES/80d90c5c59e9477d8a0c9eb727a0fc1bec2b01ea.patch @@ -0,0 +1,44 @@ +From 80d90c5c59e9477d8a0c9eb727a0fc1bec2b01ea Mon Sep 17 00:00:00 2001 +From: Andrei Vagin +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) diff --git a/SOURCES/b9e9e3903c78ba5d243b4176e82bf4b82342cb6a.patch b/SOURCES/b9e9e3903c78ba5d243b4176e82bf4b82342cb6a.patch new file mode 100644 index 0000000..ec0cf00 --- /dev/null +++ b/SOURCES/b9e9e3903c78ba5d243b4176e82bf4b82342cb6a.patch @@ -0,0 +1,40 @@ +From b9e9e3903c78ba5d243b4176e82bf4b82342cb6a Mon Sep 17 00:00:00 2001 +From: Adrian Reber +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 +--- + 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; + } + diff --git a/SOURCES/c321cc07607cfe4215fc90e426ae4491fca4c49c.patch b/SOURCES/c321cc07607cfe4215fc90e426ae4491fca4c49c.patch deleted file mode 100644 index 7ac5679..0000000 --- a/SOURCES/c321cc07607cfe4215fc90e426ae4491fca4c49c.patch +++ /dev/null @@ -1,58 +0,0 @@ -From c321cc07607cfe4215fc90e426ae4491fca4c49c Mon Sep 17 00:00:00 2001 -From: Adrian Reber -Date: Thu, 22 Nov 2018 13:44:03 +0000 -Subject: [PATCH] Fix kerndat_link_nsid() on systems with more than 10 - interfaces - -On a system with more than 10 network interfaces the link_nsid check -fails: - -$ criu check --feature link_nsid -Warn (criu/cr-check.c:1237): NSID isn't supported - -The function kerndat_link_nsid() uses: - - nde.ifindex = 10; - -This fails as there is already an interface with ifindex 10. - -This patch moves the creation of the socket into the second network -namespace and the feature check succeeds. - -Suggested-by: Jiri Benc -Signed-off-by: Adrian Reber -Signed-off-by: Andrei Vagin ---- - criu/net.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/criu/net.c b/criu/net.c -index ec66d1e6c3..c1a6e3094f 100644 ---- a/criu/net.c -+++ b/criu/net.c -@@ -3148,12 +3148,6 @@ int kerndat_link_nsid() - }; - int nsfd, sk, ret; - -- sk = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); -- if (sk < 0) { -- pr_perror("Unable to create a netlink socket"); -- exit(1); -- } -- - if (unshare(CLONE_NEWNET)) { - pr_perror("Unable create a network namespace"); - exit(1); -@@ -3168,6 +3162,12 @@ int kerndat_link_nsid() - exit(1); - } - -+ sk = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); -+ if (sk < 0) { -+ pr_perror("Unable to create a netlink socket"); -+ exit(1); -+ } -+ - nde.type = ND_TYPE__VETH; - nde.name = "veth"; - nde.ifindex = 10; diff --git a/SOURCES/f44f8ef6e4d594bd74c041e25261bf275e52621b.patch b/SOURCES/f44f8ef6e4d594bd74c041e25261bf275e52621b.patch deleted file mode 100644 index 55aaae4..0000000 --- a/SOURCES/f44f8ef6e4d594bd74c041e25261bf275e52621b.patch +++ /dev/null @@ -1,33 +0,0 @@ -From f44f8ef6e4d594bd74c041e25261bf275e52621b Mon Sep 17 00:00:00 2001 -From: Adrian Reber -Date: Thu, 29 Nov 2018 09:24:01 +0000 -Subject: [PATCH] Do not lock network if running in the host network namespace - -Related: https://github.com/checkpoint-restore/criu/issues/577 - -Restoring a runc container which is running in the host's network -namespace locked the network (iptables-restore) without unlocking it. - -This disables network logging if running in the host's network -namespace. - -Suggested-by: Andrei Vagin -Signed-off-by: Adrian Reber -Signed-off-by: Andrei Vagin ---- - criu/cr-restore.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/criu/cr-restore.c b/criu/cr-restore.c -index 6086d65238..d8fe352a63 100644 ---- a/criu/cr-restore.c -+++ b/criu/cr-restore.c -@@ -2135,7 +2135,7 @@ static int restore_root_task(struct pstree_item *init) - goto out_kill; - } - -- if (opts.empty_ns & CLONE_NEWNET) { -+ if (root_ns_mask & opts.empty_ns & CLONE_NEWNET) { - /* - * Local TCP connections were locked by network_lock_internal() - * on dump and normally should have been C/R-ed by respectively diff --git a/SPECS/criu.spec b/SPECS/criu.spec index ad4940f..44e484e 100644 --- a/SPECS/criu.spec +++ b/SPECS/criu.spec @@ -1,7 +1,9 @@ %if 0%{?fedora} >= 27 || 0%{?rhel} > 7 %global py_prefix python3 +%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 @@ -9,23 +11,19 @@ %undefine _annotated_build Name: criu -Version: 3.10 -Release: 7%{?dist} +Version: 3.12 +Release: 9%{?dist} Provides: crtools = %{version}-%{release} Obsoletes: crtools <= 1.0-2 Summary: Tool for Checkpoint/Restore in User-space -Group: System Environment/Base License: GPLv2 URL: http://criu.org/ Source0: http://download.openvz.org/criu/criu-%{version}.tar.bz2 -# https://patchwork.criu.org/patch/8849/mbox/ -Patch1: 1-2-Fix-building-with-4.18.patch -# Fixes errors with read-only runc -Patch2: https://github.com/checkpoint-restore/criu/commit/27034e7c64b00a1f2467afb5ebb1d5b9b1a06ce1.patch -# Do not lock network if running in the host network namespace -Patch3: https://github.com/checkpoint-restore/criu/commit/f44f8ef6e4d594bd74c041e25261bf275e52621b.patch -# Fix 'criu check --feature link_nsid' with more than 10 interfaces -Patch4: https://github.com/checkpoint-restore/criu/commit/c321cc07607cfe4215fc90e426ae4491fca4c49c.patch + +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 @@ -47,8 +45,12 @@ BuildRequires: protobuf-devel protobuf-c-devel %{py_prefix}-devel libnl3-devel l %if 0%{?fedora} || 0%{?rhel} > 7 BuildRequires: asciidoc xmlto BuildRequires: perl-interpreter +BuildRequires: libselinux-devel # Checkpointing containers with a tmpfs requires tar Recommends: tar +%if 0%{?fedora} +BuildRequires: libbsd-devel +%endif %endif # user-space and kernel changes are only available for x86_64, arm, @@ -61,20 +63,25 @@ criu is the user-space part of Checkpoint/Restore in User-space (CRIU), a project to implement checkpoint/restore functionality for Linux in user-space. -%if 0%{?fedora} || 0%{?rhel} > 7 +%if 0%{?fedora} %package devel Summary: Header files and libraries for %{name} -Group: Development/Libraries Requires: %{name} = %{version}-%{release} %description devel This package contains header files and libraries for %{name}. + +%package libs +Summary: Libraries for %{name} +Requires: %{name} = %{version}-%{release} + +%description libs +This package contains the libraries for %{name} %endif %package -n %{py_prefix}-%{name} %{?python_provide:%python_provide %{py_prefix}-%{name}} Summary: Python bindings for %{name} -Group: Development/Languages %if 0%{?rhel} && 0%{?rhel} <= 7 Requires: protobuf-python Requires: %{name} = %{version}-%{release} %{py_prefix}-ipaddr @@ -97,10 +104,10 @@ their content in human-readable form. %prep %setup -q +%patch0 -p1 %patch1 -p1 %patch2 -p1 %patch3 -p1 -%patch4 -p1 %if 0%{?rhel} && 0%{?rhel} <= 7 %patch100 -p1 @@ -109,7 +116,7 @@ their content in human-readable form. %build # %{?_smp_mflags} does not work # -fstack-protector breaks build -CFLAGS+=`echo %{optflags} | sed -e 's,-fstack-protector\S*,,g'` make V=1 WERROR=0 PREFIX=%{_prefix} RUNDIR=/run/criu PYTHON=%{py_prefix} +CFLAGS+=`echo %{optflags} | sed -e 's,-fstack-protector\S*,,g'` make V=1 WERROR=0 PREFIX=%{_prefix} RUNDIR=/run/criu PYTHON=%{py_binary} %if 0%{?fedora} || 0%{?rhel} > 7 make docs V=1 %endif @@ -117,7 +124,7 @@ make docs V=1 %install make install-criu DESTDIR=$RPM_BUILD_ROOT PREFIX=%{_prefix} LIBDIR=%{_libdir} -make install-lib DESTDIR=$RPM_BUILD_ROOT PREFIX=%{_prefix} LIBDIR=%{_libdir} PYTHON=%{py_prefix} +make install-lib DESTDIR=$RPM_BUILD_ROOT PREFIX=%{_prefix} LIBDIR=%{_libdir} PYTHON=%{py_binary} %if 0%{?fedora} || 0%{?rhel} > 7 # only install documentation on Fedora as it requires asciidoc, # which is not available on RHEL7 @@ -131,32 +138,32 @@ mkdir -p %{buildroot}%{_tmpfilesdir} install -m 0644 %{SOURCE3} %{buildroot}%{_tmpfilesdir}/%{name}.conf install -d -m 0755 %{buildroot}/run/%{name}/ -%if 0%{?rhel} && 0%{?rhel} <= 7 -# remove devel package +%if 0%{?rhel} +# remove devel and libs packages 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} %endif -%ldconfig_scriptlets - %files %{_sbindir}/%{name} %doc %{_mandir}/man8/criu.8* -%if 0%{?fedora} || 0%{?rhel} > 7 -%{_libdir}/*.so.* +%if 0%{?fedora} %{_libexecdir}/%{name} %endif %dir /run/%{name} %{_tmpfilesdir}/%{name}.conf %doc README.md COPYING -%if 0%{?fedora} || 0%{?rhel} > 7 +%if 0%{?fedora} %files devel %{_includedir}/criu %{_libdir}/*.so %{_libdir}/pkgconfig/*.pc + +%files libs +%{_libdir}/*.so.* %endif %files -n %{py_prefix}-%{name} @@ -174,6 +181,32 @@ rm -rf $RPM_BUILD_ROOT%{_libexecdir}/%{name} %changelog +* Mon May 13 2019 Adrian Reber - 3.12-9 +- Added additional fixup patches for the socket labelling + +* Sat May 04 2019 Adrian Reber - 3.12-8 +- Patch for socket labelling has changed upstream + +* Mon Apr 29 2019 Adrian Reber - 3.12-4 +- Applied patch to correctly restore socket()s + +* Sat Apr 27 2019 Adrian Reber - 3.12-3 +- Correctly exclude libs and devel for RHEL + +* Thu Apr 25 2019 Adrian Reber - 3.12-2 +- Updated to official 3.12 + +* Tue Apr 23 2019 Adrian Reber - 3.12-0.1 +- Updated to 3.12 (pre-release) +- Create libs subpackage +- Build against SELinux (Fedora and RHEL8) +- Build against libbsd (Fedora) + +* Thu Feb 14 2019 Adrian Reber - 3.11-2 +- Updated to 3.11 +- Removed upstreamed patches +- Added patch for gcc-9 + * Tue Dec 11 2018 Adrian Reber - 3.10-7 - Fix 'criu check --feature link_nsid' with more than 10 interfaces (#1652442)