mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 02:14:37 +00:00
cr-check: Add ptrace rseq conf dump feature
Add "get_rseq_conf" feature corresponding to the ptrace(PTRACE_GET_RSEQ_CONFIGURATION) support. Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
This commit is contained in:
parent
ca54dfcac9
commit
bd9ee32554
4 changed files with 65 additions and 0 deletions
|
|
@ -65,6 +65,18 @@ typedef struct {
|
|||
uint64_t flags; /* Output: filter's flags */
|
||||
} seccomp_metadata_t;
|
||||
|
||||
#ifndef PTRACE_GET_RSEQ_CONFIGURATION
|
||||
#define PTRACE_GET_RSEQ_CONFIGURATION 0x420f
|
||||
|
||||
struct __ptrace_rseq_configuration {
|
||||
uint64_t rseq_abi_pointer;
|
||||
uint32_t rseq_abi_size;
|
||||
uint32_t signature;
|
||||
uint32_t flags;
|
||||
uint32_t pad;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef PTRACE_EVENT_STOP
|
||||
#if PTRACE_EVENT_STOP == 7 /* Bad value from Linux 3.1-3.3, fixed in 3.4 */
|
||||
#undef PTRACE_EVENT_STOP
|
||||
|
|
|
|||
|
|
@ -798,6 +798,15 @@ static int check_ptrace_dump_seccomp_filters(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int check_ptrace_get_rseq_conf(void)
|
||||
{
|
||||
if (!kdat.has_ptrace_get_rseq_conf) {
|
||||
pr_warn("ptrace(PTRACE_GET_RSEQ_CONFIGURATION) isn't supported. C/R of processes which are using rseq() won't work.\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_mem_dirty_track(void)
|
||||
{
|
||||
if (!kdat.has_dirty_track) {
|
||||
|
|
@ -1475,6 +1484,7 @@ int cr_check(void)
|
|||
ret |= check_memfd_hugetlb();
|
||||
ret |= check_move_mount_set_group();
|
||||
ret |= check_openat2();
|
||||
ret |= check_ptrace_get_rseq_conf();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1591,6 +1601,7 @@ static struct feature_list feature_list[] = {
|
|||
{ "memfd_hugetlb", check_memfd_hugetlb },
|
||||
{ "move_mount_set_group", check_move_mount_set_group },
|
||||
{ "openat2", check_openat2 },
|
||||
{ "get_rseq_conf", check_ptrace_get_rseq_conf },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ struct kerndat_s {
|
|||
bool has_move_mount_set_group;
|
||||
bool has_openat2;
|
||||
bool has_rseq;
|
||||
bool has_ptrace_get_rseq_conf;
|
||||
};
|
||||
|
||||
extern struct kerndat_s kdat;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
#include <sys/syscall.h>
|
||||
|
|
@ -37,6 +39,7 @@
|
|||
#include "sockets.h"
|
||||
#include "net.h"
|
||||
#include "tun.h"
|
||||
#include <compel/ptrace.h>
|
||||
#include <compel/plugins/std/syscall-codes.h>
|
||||
#include "netfilter.h"
|
||||
#include "fsnotify.h"
|
||||
|
|
@ -919,6 +922,40 @@ static int kerndat_has_rseq(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int kerndat_has_ptrace_get_rseq_conf(void)
|
||||
{
|
||||
pid_t pid;
|
||||
int len;
|
||||
struct __ptrace_rseq_configuration rseq;
|
||||
|
||||
pid = fork_and_ptrace_attach(NULL);
|
||||
if (pid < 0)
|
||||
return -1;
|
||||
|
||||
len = ptrace(PTRACE_GET_RSEQ_CONFIGURATION, pid, sizeof(rseq), &rseq);
|
||||
if (len != sizeof(rseq)) {
|
||||
kdat.has_ptrace_get_rseq_conf = false;
|
||||
pr_info("ptrace(PTRACE_GET_RSEQ_CONFIGURATION) is not supported\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* flags is always zero from the kernel side, if it will be changed
|
||||
* we need to pay attention to that and, possibly, make changes on the CRIU side.
|
||||
*/
|
||||
if (rseq.flags != 0) {
|
||||
kdat.has_ptrace_get_rseq_conf = false;
|
||||
pr_err("ptrace(PTRACE_GET_RSEQ_CONFIGURATION): rseq.flags != 0\n");
|
||||
} else {
|
||||
kdat.has_ptrace_get_rseq_conf = true;
|
||||
}
|
||||
|
||||
out:
|
||||
kill(pid, SIGKILL);
|
||||
waitpid(pid, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kerndat_sockopt_buf_lock(void)
|
||||
{
|
||||
int exit_code = -1;
|
||||
|
|
@ -1624,6 +1661,10 @@ int kerndat_init(void)
|
|||
pr_err("kerndat_has_rseq failed when initializing kerndat.\n");
|
||||
ret = -1;
|
||||
}
|
||||
if (!ret && kerndat_has_ptrace_get_rseq_conf()) {
|
||||
pr_err("kerndat_has_ptrace_get_rseq_conf failed when initializing kerndat.\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
kerndat_lsm();
|
||||
kerndat_mmap_min_addr();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue