From 55209831c2d4bdc2fe57e82b8ea878e1da0d20d1 Mon Sep 17 00:00:00 2001 From: Guocai He Date: Fri, 21 Mar 2025 11:54:32 +0800 Subject: criu: Adjust to glibc __rseq_size semantic change On criu version 3.17: When use "criu restore -d -D checkpoint" to restore, the error is: 1272: Error (criu/cr-restore.c:1498): 1295 killed by signal 11: Segmentation fault The root casue is that the glibc updated and criu should adjust to glibc __rseq_size semantic change. Signed-off-by: Guocai He Signed-off-by: Bruce Ashfield --- recipes-containers/criu/criu_git.bb | 2 +- ...just-to-glibc-__rseq_size-semantic-change.patch | 100 +++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 recipes-containers/criu/files/0004-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch diff --git a/recipes-containers/criu/criu_git.bb b/recipes-containers/criu/criu_git.bb index 46401f9a..cff2d9d6 100644 --- a/recipes-containers/criu/criu_git.bb +++ b/recipes-containers/criu/criu_git.bb @@ -20,8 +20,8 @@ SRC_URI = "git://github.com/checkpoint-restore/criu.git;branch=master;protocol=h file://0001-criu-Skip-documentation-install.patch \ file://0002-criu-Change-libraries-install-directory.patch \ file://0003-lib-Makefile-overwrite-install-lib-to-allow-multiarc.patch \ + file://0004-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch \ " - COMPATIBLE_HOST = "(x86_64|arm|aarch64).*-linux" DEPENDS += "libnl libcap protobuf-c-native protobuf-c util-linux-native libbsd libnet" diff --git a/recipes-containers/criu/files/0004-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch b/recipes-containers/criu/files/0004-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch new file mode 100644 index 00000000..b6f642f8 --- /dev/null +++ b/recipes-containers/criu/files/0004-criu-Adjust-to-glibc-__rseq_size-semantic-change.patch @@ -0,0 +1,100 @@ +From 9f2eb6b9c4642fdc8aba2712d21cbe75545e4ab4 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Wed, 10 Jul 2024 18:34:50 +0200 +Subject: [PATCH] criu: 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. + +Upstream-Status: Backport [https://github.com/checkpoint-restore/criu/commit/ +089345f77a34d1bc7ef146d650636afcd3cdda21] + +Signed-off-by: Florian Weimer +Signed-off-by: Guocai He +--- + criu/cr-restore.c | 8 ++++++++ + test/zdtm/static/rseq00.c | 7 +++++-- + test/zdtm/transition/rseq01.c | 5 ++++- + 3 files changed, 17 insertions(+), 3 deletions(-) + +diff --git a/criu/cr-restore.c b/criu/cr-restore.c +index 9853c0585..df2010a4d 100644 +--- a/criu/cr-restore.c ++++ b/criu/cr-restore.c +@@ -3087,7 +3087,15 @@ static void prep_libc_rseq_info(struct rst_rseq_param *rseq) + } + + 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 +diff --git a/test/zdtm/static/rseq00.c b/test/zdtm/static/rseq00.c +index 471ad6a43..23b2d74ab 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) +@@ -140,4 +143,4 @@ int main(int argc, char *argv[]) + return 0; + } + +-#endif /* #if defined(__x86_64__) */ +\ No newline at end of file ++#endif /* #if defined(__x86_64__) */ +diff --git a/test/zdtm/transition/rseq01.c b/test/zdtm/transition/rseq01.c +index b6d470785..de4355845 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) +-- +2.34.1 -- cgit v1.2.3-54-g00ecf