From 3bef22791deec6280244b43b028044ad7015c5d1 Mon Sep 17 00:00:00 2001
From: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
Date: Fri, 24 Dec 2021 18:57:54 +0300
Subject: [PATCH 09/10] fixup: attempt to disable rseq at the thread start
Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
---
criu/clone-noasan.c | 49 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/criu/clone-noasan.c b/criu/clone-noasan.c
index d657ea2e8..bcda7865b 100644
--- a/criu/clone-noasan.c
+++ b/criu/clone-noasan.c
@@ -2,6 +2,10 @@
#include <sched.h>
#include <unistd.h>
+#if defined(__x86_64__) && (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 34)
+#include <sys/rseq.h>
+#endif
+
#include <compel/plugins/std/syscall-codes.h>
#include "sched.h"
@@ -34,16 +38,55 @@
* ... wait for process to finish ...
* unlock_last_pid
*/
+
+#if defined(__x86_64__) && defined(RSEQ_SIG)
+static inline void *
+thread_pointer (void)
+{
+ void *result;
+ asm ("mov %%fs:0, %0" : "=r" (result));
+ return result;
+}
+
+static inline void
+unregister_rseq_asdf (void)
+{
+ /* unregister rseq */
+ syscall(__NR_rseq, (void *)((char *) thread_pointer () + __rseq_offset), __rseq_size, 1, RSEQ_SIG);
+}
+#else
+static inline void
+unregister_rseq_asdf (void)
+{
+}
+#endif
+
+struct call_fn_args {
+ int (*fn)(void *);
+ void *arg;
+};
+
+int call_fn(void *arg)
+{
+ struct call_fn_args *a = arg;
+ unregister_rseq_asdf();
+ return a->fn(a->arg);
+}
+
int clone_noasan(int (*fn)(void *), int flags, void *arg)
{
void *stack_ptr = (void *)round_down((unsigned long)&stack_ptr - 1024, 16);
+ struct call_fn_args a = {
+ .fn = fn,
+ .arg = arg,
+ };
BUG_ON((flags & CLONE_VM) && !(flags & CLONE_VFORK));
/*
* Reserve some bytes for clone() internal needs
* and use as stack the address above this area.
*/
- return clone(fn, stack_ptr, flags, arg);
+ return clone(call_fn, stack_ptr, flags, (void*)&a);
}
int clone3_with_pid_noasan(int (*fn)(void *), void *arg, int flags, int exit_signal, pid_t pid)
@@ -78,7 +121,9 @@ int clone3_with_pid_noasan(int (*fn)(void *), void *arg, int flags, int exit_sig
c_args.set_tid = ptr_to_u64(&pid);
c_args.set_tid_size = 1;
pid = syscall(__NR_clone3, &c_args, sizeof(c_args));
- if (pid == 0)
+ if (pid == 0) {
+ unregister_rseq_asdf();
exit(fn(arg));
+ }
return pid;
}
--
2.34.1