diff --git a/compel/arch/aarch64/src/lib/include/uapi/asm/breakpoints.h b/compel/arch/aarch64/src/lib/include/uapi/asm/breakpoints.h deleted file mode 100644 index 8a61b268f..000000000 --- a/compel/arch/aarch64/src/lib/include/uapi/asm/breakpoints.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef __COMPEL_BREAKPOINTS_H__ -#define __COMPEL_BREAKPOINTS_H__ -#define ARCH_SI_TRAP TRAP_BRKPT - -#include -#include - -struct hwbp_cap { - char arch; - char bp_count; -}; - -/* copied from `linux/arch/arm64/include/asm/hw_breakpoint.h` */ -/* Lengths */ -#define ARM_BREAKPOINT_LEN_1 0x1 -#define ARM_BREAKPOINT_LEN_2 0x3 -#define ARM_BREAKPOINT_LEN_3 0x7 -#define ARM_BREAKPOINT_LEN_4 0xf -#define ARM_BREAKPOINT_LEN_5 0x1f -#define ARM_BREAKPOINT_LEN_6 0x3f -#define ARM_BREAKPOINT_LEN_7 0x7f -#define ARM_BREAKPOINT_LEN_8 0xff - -/* Privilege Levels */ -#define AARCH64_BREAKPOINT_EL1 1 -#define AARCH64_BREAKPOINT_EL0 2 - -/* Breakpoint */ -#define ARM_BREAKPOINT_EXECUTE 0 - -/* Watchpoints */ -#define ARM_BREAKPOINT_LOAD 1 -#define ARM_BREAKPOINT_STORE 2 -#define AARCH64_ESR_ACCESS_MASK (1 << 6) - -#define DISABLE_HBP 0 -#define ENABLE_HBP 1 - -int ptrace_set_breakpoint(pid_t pid, void *addr); -int ptrace_flush_breakpoints(pid_t pid); - -#endif diff --git a/compel/arch/aarch64/src/lib/infect.c b/compel/arch/aarch64/src/lib/infect.c index 42f593c79..c7bcb2a44 100644 --- a/compel/arch/aarch64/src/lib/infect.c +++ b/compel/arch/aarch64/src/lib/infect.c @@ -12,7 +12,6 @@ #include "errno.h" #include "infect.h" #include "infect-priv.h" -#include "asm/breakpoints.h" #include "asm/gcs-types.h" #include @@ -255,114 +254,6 @@ unsigned long compel_task_size(void) return task_size; } -static struct hwbp_cap *ptrace_get_hwbp_cap(pid_t pid) -{ - static struct hwbp_cap info; - static int available = -1; - - if (available == -1) { - unsigned int val; - struct iovec iovec = { - .iov_base = &val, - .iov_len = sizeof(val), - }; - - if (ptrace(PTRACE_GETREGSET, pid, NT_ARM_HW_BREAK, &iovec) < 0) - available = 0; - else { - info.arch = (char)((val >> 8) & 0xff); - info.bp_count = (char)(val & 0xff); - - available = (info.arch != 0); - } - } - - return available == 1 ? &info : NULL; -} - -int ptrace_set_breakpoint(pid_t pid, void *addr) -{ - k_rtsigset_t block; - struct hwbp_cap *info = ptrace_get_hwbp_cap(pid); - struct user_hwdebug_state regs = {}; - unsigned int ctrl = 0; - struct iovec iovec; - - if (info == NULL || info->bp_count == 0) - return 0; - - /* - * The struct is copied from `arch/arm64/include/asm/hw_breakpoint.h` in - * linux kernel: - * struct arch_hw_breakpoint_ctrl { - * __u32 __reserved : 19, - * len : 8, - * type : 2, - * privilege : 2, - * enabled : 1; - * }; - * - * The part of `struct arch_hw_breakpoint_ctrl` bits meaning is defined - * in <>, - * D13.3.2 DBGBCR_EL1, Debug Breakpoint Control Registers. - */ - ctrl = ARM_BREAKPOINT_LEN_4; - ctrl = (ctrl << 2) | ARM_BREAKPOINT_EXECUTE; - ctrl = (ctrl << 2) | AARCH64_BREAKPOINT_EL0; - ctrl = (ctrl << 1) | ENABLE_HBP; - regs.dbg_regs[0].addr = (__u64)addr; - regs.dbg_regs[0].ctrl = ctrl; - iovec.iov_base = ®s; - iovec.iov_len = (offsetof(struct user_hwdebug_state, dbg_regs) + sizeof(regs.dbg_regs[0])); - - if (ptrace(PTRACE_SETREGSET, pid, NT_ARM_HW_BREAK, &iovec)) - return -1; - - /* - * FIXME(issues/1429): SIGTRAP can't be blocked, otherwise its handler - * will be reset to the default one. - */ - ksigfillset(&block); - ksigdelset(&block, SIGTRAP); - if (ptrace(PTRACE_SETSIGMASK, pid, sizeof(k_rtsigset_t), &block)) { - pr_perror("Can't block signals for %d", pid); - return -1; - } - - if (ptrace(PTRACE_CONT, pid, NULL, NULL) != 0) { - pr_perror("Unable to restart the stopped tracee process %d", pid); - return -1; - } - - return 1; -} - -int ptrace_flush_breakpoints(pid_t pid) -{ - struct hwbp_cap *info = ptrace_get_hwbp_cap(pid); - struct user_hwdebug_state regs = {}; - unsigned int ctrl = 0; - struct iovec iovec; - - if (info == NULL || info->bp_count == 0) - return 0; - - ctrl = ARM_BREAKPOINT_LEN_4; - ctrl = (ctrl << 2) | ARM_BREAKPOINT_EXECUTE; - ctrl = (ctrl << 2) | AARCH64_BREAKPOINT_EL0; - ctrl = (ctrl << 1) | DISABLE_HBP; - regs.dbg_regs[0].addr = 0ul; - regs.dbg_regs[0].ctrl = ctrl; - - iovec.iov_base = ®s; - iovec.iov_len = (offsetof(struct user_hwdebug_state, dbg_regs) + sizeof(regs.dbg_regs[0])); - - if (ptrace(PTRACE_SETREGSET, pid, NT_ARM_HW_BREAK, &iovec)) - return -1; - - return 0; -} - int inject_gcs_cap_token(struct parasite_ctl *ctl, pid_t pid, struct cr_user_gcs *gcs) { struct iovec gcs_iov = { .iov_base = gcs, .iov_len = sizeof(*gcs) }; diff --git a/compel/arch/arm/src/lib/include/uapi/asm/breakpoints.h b/compel/arch/arm/src/lib/include/uapi/asm/breakpoints.h deleted file mode 100644 index 5f090490d..000000000 --- a/compel/arch/arm/src/lib/include/uapi/asm/breakpoints.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __COMPEL_BREAKPOINTS_H__ -#define __COMPEL_BREAKPOINTS_H__ -#define ARCH_SI_TRAP TRAP_BRKPT - -static inline int ptrace_set_breakpoint(pid_t pid, void *addr) -{ - return 0; -} - -static inline int ptrace_flush_breakpoints(pid_t pid) -{ - return 0; -} - -#endif diff --git a/compel/arch/arm/src/lib/include/uapi/asm/infect-types.h b/compel/arch/arm/src/lib/include/uapi/asm/infect-types.h index 8d328252e..5fd94ca7b 100644 --- a/compel/arch/arm/src/lib/include/uapi/asm/infect-types.h +++ b/compel/arch/arm/src/lib/include/uapi/asm/infect-types.h @@ -2,6 +2,7 @@ #define UAPI_COMPEL_ASM_TYPES_H__ #include +#include #include #define SIGMAX 64 diff --git a/compel/arch/loongarch64/src/lib/include/uapi/asm/breakpoints.h b/compel/arch/loongarch64/src/lib/include/uapi/asm/breakpoints.h deleted file mode 100644 index 21eb1309f..000000000 --- a/compel/arch/loongarch64/src/lib/include/uapi/asm/breakpoints.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __COMPEL_BREAKPOINTS_H__ -#define __COMPEL_BREAKPOINTS_H__ -#define ARCH_SI_TRAP TRAP_BRKPT -extern int ptrace_set_breakpoint(pid_t pid, void *addr); -extern int ptrace_flush_breakpoints(pid_t pid); -#endif diff --git a/compel/arch/loongarch64/src/lib/include/uapi/asm/infect-types.h b/compel/arch/loongarch64/src/lib/include/uapi/asm/infect-types.h index 0b047a5b0..9abb92207 100644 --- a/compel/arch/loongarch64/src/lib/include/uapi/asm/infect-types.h +++ b/compel/arch/loongarch64/src/lib/include/uapi/asm/infect-types.h @@ -2,9 +2,11 @@ #define UAPI_COMPEL_ASM_TYPES_H__ #include +#include #define SIGMAX 64 #define SIGMAX_OLD 31 +#define ARCH_SI_TRAP TRAP_BRKPT /* * From the Linux kernel header arch/loongarch/include/uapi/asm/ptrace.h diff --git a/compel/arch/loongarch64/src/lib/infect.c b/compel/arch/loongarch64/src/lib/infect.c index 190c39227..75a7a409a 100644 --- a/compel/arch/loongarch64/src/lib/infect.c +++ b/compel/arch/loongarch64/src/lib/infect.c @@ -174,19 +174,6 @@ int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s) return err ? err : ret; } -/* - * TODO: add feature - */ -int ptrace_set_breakpoint(pid_t pid, void *addr) -{ - return 0; -} - -int ptrace_flush_breakpoints(pid_t pid) -{ - return 0; -} - /* * Refer to Linux kernel arch/loongarch/include/asm/processor.h */ diff --git a/compel/arch/mips/src/lib/include/uapi/asm/breakpoints.h b/compel/arch/mips/src/lib/include/uapi/asm/breakpoints.h deleted file mode 100644 index 21eb1309f..000000000 --- a/compel/arch/mips/src/lib/include/uapi/asm/breakpoints.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __COMPEL_BREAKPOINTS_H__ -#define __COMPEL_BREAKPOINTS_H__ -#define ARCH_SI_TRAP TRAP_BRKPT -extern int ptrace_set_breakpoint(pid_t pid, void *addr); -extern int ptrace_flush_breakpoints(pid_t pid); -#endif diff --git a/compel/arch/mips/src/lib/include/uapi/asm/infect-types.h b/compel/arch/mips/src/lib/include/uapi/asm/infect-types.h index 481566a12..57a1b6b48 100644 --- a/compel/arch/mips/src/lib/include/uapi/asm/infect-types.h +++ b/compel/arch/mips/src/lib/include/uapi/asm/infect-types.h @@ -8,6 +8,7 @@ #include #define SIGMAX 64 #define SIGMAX_OLD 31 +#define ARCH_SI_TRAP TRAP_BRKPT /* * Copied from the Linux kernel header arch/mips/include/asm/ptrace.h diff --git a/compel/arch/mips/src/lib/infect.c b/compel/arch/mips/src/lib/infect.c index a1d4865cc..e0bbc384f 100644 --- a/compel/arch/mips/src/lib/infect.c +++ b/compel/arch/mips/src/lib/infect.c @@ -226,16 +226,6 @@ int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s) return err ? err : ret; } -int ptrace_set_breakpoint(pid_t pid, void *addr) -{ - return 0; -} - -int ptrace_flush_breakpoints(pid_t pid) -{ - return 0; -} - /*refer to kernel linux-3.10/arch/mips/include/asm/processor.h*/ #define TASK_SIZE32 0x7fff8000UL #define TASK_SIZE64 0x10000000000UL diff --git a/compel/arch/ppc64/src/lib/include/uapi/asm/breakpoints.h b/compel/arch/ppc64/src/lib/include/uapi/asm/breakpoints.h deleted file mode 100644 index 5f090490d..000000000 --- a/compel/arch/ppc64/src/lib/include/uapi/asm/breakpoints.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __COMPEL_BREAKPOINTS_H__ -#define __COMPEL_BREAKPOINTS_H__ -#define ARCH_SI_TRAP TRAP_BRKPT - -static inline int ptrace_set_breakpoint(pid_t pid, void *addr) -{ - return 0; -} - -static inline int ptrace_flush_breakpoints(pid_t pid) -{ - return 0; -} - -#endif diff --git a/compel/arch/riscv64/src/lib/include/uapi/asm/breakpoints.h b/compel/arch/riscv64/src/lib/include/uapi/asm/breakpoints.h deleted file mode 100644 index f2ba799cb..000000000 --- a/compel/arch/riscv64/src/lib/include/uapi/asm/breakpoints.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __COMPEL_BREAKPOINTS_H__ -#define __COMPEL_BREAKPOINTS_H__ -#define ARCH_SI_TRAP TRAP_BRKPT - -static inline int ptrace_set_breakpoint(pid_t pid, void *addr) -{ - return 0; -} - -static inline int ptrace_flush_breakpoints(pid_t pid) -{ - return 0; -} - -#endif \ No newline at end of file diff --git a/compel/arch/s390/src/lib/include/uapi/asm/breakpoints.h b/compel/arch/s390/src/lib/include/uapi/asm/breakpoints.h deleted file mode 100644 index 5f090490d..000000000 --- a/compel/arch/s390/src/lib/include/uapi/asm/breakpoints.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __COMPEL_BREAKPOINTS_H__ -#define __COMPEL_BREAKPOINTS_H__ -#define ARCH_SI_TRAP TRAP_BRKPT - -static inline int ptrace_set_breakpoint(pid_t pid, void *addr) -{ - return 0; -} - -static inline int ptrace_flush_breakpoints(pid_t pid) -{ - return 0; -} - -#endif diff --git a/compel/arch/s390/src/lib/include/uapi/asm/infect-types.h b/compel/arch/s390/src/lib/include/uapi/asm/infect-types.h index 87283bc6b..e15b495b2 100644 --- a/compel/arch/s390/src/lib/include/uapi/asm/infect-types.h +++ b/compel/arch/s390/src/lib/include/uapi/asm/infect-types.h @@ -9,6 +9,7 @@ #define SIGMAX 64 #define SIGMAX_OLD 31 +#define ARCH_SI_TRAP TRAP_BRKPT /* * Definitions from /usr/include/asm/ptrace.h: diff --git a/compel/arch/x86/src/lib/include/uapi/asm/breakpoints.h b/compel/arch/x86/src/lib/include/uapi/asm/breakpoints.h deleted file mode 100644 index 980f25d06..000000000 --- a/compel/arch/x86/src/lib/include/uapi/asm/breakpoints.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __COMPEL_BREAKPOINTS_H__ -#define __COMPEL_BREAKPOINTS_H__ -#define ARCH_SI_TRAP SI_KERNEL -extern int ptrace_set_breakpoint(pid_t pid, void *addr); -extern int ptrace_flush_breakpoints(pid_t pid); -#endif diff --git a/compel/arch/x86/src/lib/include/uapi/asm/infect-types.h b/compel/arch/x86/src/lib/include/uapi/asm/infect-types.h index b998c488c..711ca48fc 100644 --- a/compel/arch/x86/src/lib/include/uapi/asm/infect-types.h +++ b/compel/arch/x86/src/lib/include/uapi/asm/infect-types.h @@ -8,6 +8,7 @@ #define SIGMAX 64 #define SIGMAX_OLD 31 +#define ARCH_SI_TRAP SI_KERNEL #define ARCH_HAS_PTRACE_GET_THREAD_AREA diff --git a/compel/arch/x86/src/lib/infect.c b/compel/arch/x86/src/lib/infect.c index 6d5602ffe..dca24cc19 100644 --- a/compel/arch/x86/src/lib/infect.c +++ b/compel/arch/x86/src/lib/infect.c @@ -633,70 +633,6 @@ int arch_fetch_sas(struct parasite_ctl *ctl, struct rt_sigframe *s) return err ? err : ret; } -/* Copied from the gdb header gdb/nat/x86-dregs.h */ - -/* Debug registers' indices. */ -#define DR_FIRSTADDR 0 -#define DR_LASTADDR 3 -#define DR_NADDR 4 /* The number of debug address registers. */ -#define DR_STATUS 6 /* Index of debug status register (DR6). */ -#define DR_CONTROL 7 /* Index of debug control register (DR7). */ - -#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit. */ -#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit. */ -#define DR_ENABLE_SIZE 2 /* Two enable bits per debug register. */ - -/* Locally enable the break/watchpoint in the I'th debug register. */ -#define X86_DR_LOCAL_ENABLE(i) (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i))) - -int ptrace_set_breakpoint(pid_t pid, void *addr) -{ - k_rtsigset_t block; - int ret; - - /* Set a breakpoint */ - if (ptrace(PTRACE_POKEUSER, pid, offsetof(struct user, u_debugreg[DR_FIRSTADDR]), addr)) { - pr_perror("Unable to setup a breakpoint into %d", pid); - return -1; - } - - /* Enable the breakpoint */ - if (ptrace(PTRACE_POKEUSER, pid, offsetof(struct user, u_debugreg[DR_CONTROL]), - X86_DR_LOCAL_ENABLE(DR_FIRSTADDR))) { - pr_perror("Unable to enable the breakpoint for %d", pid); - return -1; - } - - /* - * FIXME(issues/1429): SIGTRAP can't be blocked, otherwise its handler - * will be reset to the default one. - */ - ksigfillset(&block); - ksigdelset(&block, SIGTRAP); - if (ptrace(PTRACE_SETSIGMASK, pid, sizeof(k_rtsigset_t), &block)) { - pr_perror("Can't block signals for %d", pid); - return -1; - } - ret = ptrace(PTRACE_CONT, pid, NULL, NULL); - if (ret) { - pr_perror("Unable to restart the stopped tracee process %d", pid); - return -1; - } - - return 1; -} - -int ptrace_flush_breakpoints(pid_t pid) -{ - /* Disable the breakpoint */ - if (ptrace(PTRACE_POKEUSER, pid, offsetof(struct user, u_debugreg[DR_CONTROL]), 0)) { - pr_perror("Unable to disable the breakpoint for %d", pid); - return -1; - } - - return 0; -} - int ptrace_get_regs(pid_t pid, user_regs_struct_t *regs) { struct iovec iov; diff --git a/compel/include/infect-priv.h b/compel/include/infect-priv.h index 8e78a7f6c..79bb2580e 100644 --- a/compel/include/infect-priv.h +++ b/compel/include/infect-priv.h @@ -19,7 +19,6 @@ struct parasite_ctl { int rpid; /* Real pid of the victim */ void *remote_map; void *local_map; - void *sigreturn_addr; /* A place for the breakpoint */ unsigned long map_length; struct infect_ctx ictx; diff --git a/compel/include/rpc-pie-priv.h b/compel/include/rpc-pie-priv.h index 5a6b337b2..8afce2389 100644 --- a/compel/include/rpc-pie-priv.h +++ b/compel/include/rpc-pie-priv.h @@ -41,7 +41,6 @@ struct parasite_init_args { int32_t h_addr_len; struct sockaddr_un h_addr; int32_t log_level; - uint64_t sigreturn_addr; uint64_t sigframe; /* pointer to sigframe */ futex_t daemon_connected; #ifdef ARCH_HAS_LONG_PAGES diff --git a/compel/include/uapi/infect.h b/compel/include/uapi/infect.h index 35d99a715..94d7d2c5e 100644 --- a/compel/include/uapi/infect.h +++ b/compel/include/uapi/infect.h @@ -95,8 +95,6 @@ enum trace_flags { extern int __must_check compel_stop_on_syscall(int tasks, int sys_nr, int sys_nr_compat); extern int compel_stop_tasks_on_syscall(int tasks, pid_t *pids, const int sys_nr, const int sys_nr_compat); -extern int __must_check compel_stop_pie(pid_t pid, void *addr, bool no_bp); - extern int __must_check compel_unmap(struct parasite_ctl *ctl, unsigned long addr); extern int compel_mode_native(struct parasite_ctl *ctl); @@ -139,8 +137,6 @@ extern struct infect_ctx *compel_infect_ctx(struct parasite_ctl *); #define INFECT_NO_MEMFD (1UL << 0) /* Make parasite connect() fail */ #define INFECT_FAIL_CONNECT (1UL << 1) -/* No breakpoints in pie tracking */ -#define INFECT_NO_BREAKPOINTS (1UL << 2) /* Can run parasite inside compat tasks */ #define INFECT_COMPATIBLE (1UL << 3) /* Workaround for ptrace bug on Skylake CPUs with kernels older than v4.14 */ diff --git a/compel/include/uapi/ptrace.h b/compel/include/uapi/ptrace.h index 558124fbd..585f18967 100644 --- a/compel/include/uapi/ptrace.h +++ b/compel/include/uapi/ptrace.h @@ -11,8 +11,6 @@ #include #include -#include - /* * Some constants for ptrace that might be missing from the * standard library includes due to being (relatively) new. diff --git a/compel/plugins/std/infect.c b/compel/plugins/std/infect.c index 034201320..e7b46301e 100644 --- a/compel/plugins/std/infect.c +++ b/compel/plugins/std/infect.c @@ -153,7 +153,6 @@ static noinline __used unsigned long parasite_init_daemon(void *data) struct parasite_init_args *args = data; int ret; - args->sigreturn_addr = (uint64_t)(uintptr_t)fini_sigreturn; sigframe = (void *)(uintptr_t)args->sigframe; #ifdef ARCH_HAS_LONG_PAGES __page_size = args->page_size; diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c index 1b6ca2676..1d7bbb479 100644 --- a/compel/src/lib/infect.c +++ b/compel/src/lib/infect.c @@ -725,7 +725,6 @@ static int parasite_init_daemon(struct parasite_ctl *ctl) goto err; } - ctl->sigreturn_addr = (void *)(uintptr_t)args->sigreturn_addr; ctl->daemonized = true; pr_info("Parasite %d has been switched to daemon mode\n", pid); return 0; @@ -1435,9 +1434,10 @@ static int parasite_fini_seized(struct parasite_ctl *ctl) return -1; /* Go to sigreturn as closer as we can */ - ret = compel_stop_pie(pid, ctl->sigreturn_addr, ctl->ictx.flags & INFECT_NO_BREAKPOINTS); - if (ret < 0) - return ret; + if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL)) { + pr_perror("Unable to restart the %d process", pid); + return -1; + } if (compel_stop_on_syscall(1, __NR(rt_sigreturn, 0), __NR(rt_sigreturn, 1))) return -1; @@ -1588,38 +1588,6 @@ err: return ret; } -int compel_stop_pie(pid_t pid, void *addr, bool no_bp) -{ - int ret; - - if (no_bp) { - pr_debug("Force no-breakpoints restore of %d\n", pid); - ret = 0; - } else - ret = ptrace_set_breakpoint(pid, addr); - if (ret < 0) - return ret; - - if (ret > 0) { - /* - * PIE will stop on a breakpoint, next - * stop after that will be syscall enter. - */ - return 0; - } - - /* - * No breakpoints available -- start tracing it - * in a per-syscall manner. - */ - ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL); - if (ret) { - pr_perror("Unable to restart the %d process", pid); - return -1; - } - return 0; -} - static bool task_is_trapped(int status, pid_t pid) { if (WIFSTOPPED(status) && (WSTOPSIG(status) & ~PTRACE_SYSCALL_TRAP) == SIGTRAP) @@ -1675,22 +1643,19 @@ int compel_stop_on_syscall(int tasks, const int sys_nr, const int sys_nr_compat) pr_debug("%d was trapped\n", pid); - if ((WSTOPSIG(status) & PTRACE_SYSCALL_TRAP) == 0) { - /* - * On some platforms such as ARM64, it is impossible to - * pass through a breakpoint, so let's clear it right - * after it has been triggered. - */ - if (ptrace_flush_breakpoints(pid)) { - pr_err("Unable to clear breakpoints\n"); - return -1; - } - goto goon; + if (!(WSTOPSIG(status) & PTRACE_SYSCALL_TRAP)) { + pr_err("Task %d is in unexpected state: %x\n", pid, status); + return -1; } if (trace == TRACE_EXIT) { trace = TRACE_ENTER; pr_debug("`- Expecting exit\n"); - goto goon; + ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL); + if (ret) { + pr_perror("ptrace"); + return -1; + } + continue; } if (trace == TRACE_ENTER) trace = TRACE_EXIT; @@ -1721,12 +1686,17 @@ int compel_stop_on_syscall(int tasks, const int sys_nr, const int sys_nr_compat) if (!task_is_trapped(status, pid)) return -1; + if (!(WSTOPSIG(status) & PTRACE_SYSCALL_TRAP)) { + pr_err("Task %d is in unexpected state: %x\n", pid, status); + return -1; + } + pr_debug("%d was stopped\n", pid); tasks--; continue; } - goon: ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL); + if (ret) { pr_perror("ptrace"); return -1; @@ -1785,18 +1755,11 @@ int compel_stop_tasks_on_syscall(int nr_tasks, pid_t *pids, const int sys_nr, co pr_debug("%d was trapped\n", pid); - if ((WSTOPSIG(status) & PTRACE_SYSCALL_TRAP) == 0) { - /* - * On some platforms such as ARM64, it is impossible to - * pass through a breakpoint, so let's clear it right - * after it has been triggered. - */ - if (ptrace_flush_breakpoints(pid)) { - pr_err("Unable to clear breakpoints\n"); - goto err; - } - goto goon; + if (!(WSTOPSIG(status) & PTRACE_SYSCALL_TRAP)) { + pr_err("Task %d is in unexpected state: %x\n", pid, status); + goto err; } + if (done[i] == SYS_TRAP_ENTER) { done[i] = SYS_TRAP_EXIT; continue; @@ -1810,7 +1773,7 @@ int compel_stop_tasks_on_syscall(int nr_tasks, pid_t *pids, const int sys_nr, co if (is_required_syscall(®s, pid, sys_nr, sys_nr_compat)) done[i] = SYS_TRAP_ENTER; - goon: + /* Let this task run while updating the others. */ ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL); if (ret) { diff --git a/criu/arch/x86/include/asm/restorer.h b/criu/arch/x86/include/asm/restorer.h index 3a673958d..57736dcf2 100644 --- a/criu/arch/x86/include/asm/restorer.h +++ b/criu/arch/x86/include/asm/restorer.h @@ -199,9 +199,6 @@ static inline void _setup_sas(struct rt_sigframe *sigframe, ThreadSasEntry *sas) int restore_gpregs(struct rt_sigframe *f, UserX86RegsEntry *r); int restore_nonsigframe_gpregs(UserX86RegsEntry *r); -int ptrace_set_breakpoint(pid_t pid, void *addr); -int ptrace_flush_breakpoints(pid_t pid); - extern int arch_map_vdso(unsigned long map_at, bool compatible); #endif diff --git a/criu/cr-check.c b/criu/cr-check.c index 6c9c01756..d7aa43076 100644 --- a/criu/cr-check.c +++ b/criu/cr-check.c @@ -1589,16 +1589,6 @@ static int check_overlayfs_maps(void) return status == 0 ? 0 : -1; } -static int check_breakpoints(void) -{ - if (!kdat.has_breakpoints) { - pr_warn("Hardware breakpoints don't seem to work\n"); - return -1; - } - - return 0; -} - static int check_pagemap_scan_guard_pages(void) { kerndat_warn_about_madv_guards(); @@ -1746,7 +1736,6 @@ int cr_check(void) /* * Category 4 - optional. */ - check_breakpoints(); pr_msg("%s\n", ret ? CHECK_MAYBE : CHECK_GOOD); return ret; @@ -1869,7 +1858,6 @@ static struct feature_list feature_list[] = { { "pagemap_scan", check_pagemap_scan }, { "timer_cr_ids", check_timer_cr_ids }, { "overlayfs_maps", check_overlayfs_maps }, - { "breakpoints", check_breakpoints }, { "pagemap_scan_guard_pages", check_pagemap_scan_guard_pages }, { "binfmt_misc_sandboxing", check_binfmt_misc_sandboxing }, { NULL, NULL }, diff --git a/criu/cr-restore.c b/criu/cr-restore.c index b4f32dac0..957478ce2 100644 --- a/criu/cr-restore.c +++ b/criu/cr-restore.c @@ -1834,7 +1834,6 @@ static int restore_rseq_cs(void) static int catch_tasks(pid_t *pids, int nr_tasks) { struct pstree_item *item; - bool nobp = fault_injected(FI_NO_BREAKPOINTS) || !kdat.has_breakpoints; int npids = 0; for_each_pstree_item(item) { @@ -1859,7 +1858,7 @@ static int catch_tasks(pid_t *pids, int nr_tasks) } } for_each_pstree_item(item) { - int status, i, ret; + int status, i; if (!task_alive(item)) continue; @@ -1872,9 +1871,10 @@ static int catch_tasks(pid_t *pids, int nr_tasks) return -1; } - ret = compel_stop_pie(pid, rsti(item)->breakpoint, nobp); - if (ret < 0) + if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL)) { + pr_perror("Unable to resume the %d process", pid); return -1; + } } } @@ -3334,7 +3334,6 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns goto err; } - task_args->breakpoint = &rsti(current)->breakpoint; task_args->fault_strategy = fi_strategy; sigemptyset(&blockmask); diff --git a/criu/include/fault-injection.h b/criu/include/fault-injection.h index e987c18ce..3557954a2 100644 --- a/criu/include/fault-injection.h +++ b/criu/include/fault-injection.h @@ -14,7 +14,6 @@ enum faults { FI_VDSO_TRAMPOLINES = 127, FI_CHECK_OPEN_HANDLE = 128, FI_NO_MEMFD = 129, - FI_NO_BREAKPOINTS = 130, FI_PARTIAL_PAGES = 131, FI_HUGE_ANON_SHMEM_ID = 132, FI_CANNOT_MAP_VDSO = 133, diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h index 7ede28e2e..27bdfe557 100644 --- a/criu/include/kerndat.h +++ b/criu/include/kerndat.h @@ -90,7 +90,6 @@ struct kerndat_s { bool has_shstk; bool has_close_range; bool has_timer_cr_ids; - bool has_breakpoints; bool has_madv_guard; bool has_pagemap_scan_guard_pages; bool has_binfmt_misc_sandboxing; diff --git a/criu/include/restorer.h b/criu/include/restorer.h index 14c0a3768..78da19182 100644 --- a/criu/include/restorer.h +++ b/criu/include/restorer.h @@ -229,7 +229,6 @@ struct task_restore_args { unsigned long vdso_rt_size; struct vdso_maps vdso_maps_rt; /* runtime vdso symbols */ unsigned long vdso_rt_parked_at; /* safe place to keep vdso */ - void **breakpoint; enum faults fault_strategy; #ifdef ARCH_HAS_LONG_PAGES diff --git a/criu/include/rst_info.h b/criu/include/rst_info.h index deb297e5f..c9b0c3fb4 100644 --- a/criu/include/rst_info.h +++ b/criu/include/rst_info.h @@ -85,8 +85,6 @@ struct rst_info { futex_t shstk_enable; futex_t shstk_unlock; - void *breakpoint; - struct rst_arch_info arch_info; }; diff --git a/criu/kerndat.c b/criu/kerndat.c index 7cb05047d..1e4863190 100644 --- a/criu/kerndat.c +++ b/criu/kerndat.c @@ -1736,83 +1736,6 @@ static int kerndat_has_timer_cr_ids(void) return 0; } -static void breakpoint_func(void) -{ - if (raise(SIGSTOP)) - pr_perror("Unable to kill itself with SIGSTOP"); - exit(1); -} - -/* - * kerndat_breakpoints checks that hardware breakpoints work as they should. - * In some cases, they might not work in virtual machines if the hypervisor - * doesn't virtualize them. For example, they don't work in AMD SEV virtual - * machines if the Debug Virtualization extension isn't supported or isn't - * enabled in SEV_FEATURES. - */ -static int kerndat_breakpoints(void) -{ - int status, ret, exit_code = -1; - pid_t pid; - - pid = fork(); - if (pid == -1) { - pr_perror("fork"); - return -1; - } - if (pid == 0) { - if (ptrace(PTRACE_TRACEME, 0, 0, 0)) { - pr_perror("ptrace(PTRACE_TRACEME)"); - exit(1); - } - raise(SIGSTOP); - breakpoint_func(); - exit(1); - } - if (waitpid(pid, &status, 0) == -1) { - pr_perror("waitpid for initial stop"); - goto err; - } - if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) { - pr_err("Child didn't stop as expected: status=%x\n", status); - goto err; - } - ret = ptrace_set_breakpoint(pid, &breakpoint_func); - if (ret < 0) { - pr_err("Failed to set breakpoint\n"); - goto err; - } - if (ret == 0) { - pr_debug("Hardware breakpoints appear to be disabled\n"); - goto out; - } - if (waitpid(pid, &status, 0) == -1) { - pr_perror("waitpid for breakpoint trigger"); - goto err; - } - if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGTRAP) { - pr_warn("Hardware breakpoints don't seem to work (status=%x)\n", status); - goto out; - } - kdat.has_breakpoints = true; -out: - exit_code = 0; -err: - if (kill(pid, SIGKILL)) { - pr_perror("Failed to kill the child process"); - exit_code = -1; - } - if (waitpid(pid, &status, 0) == -1) { - pr_perror("Failed to wait for the child process"); - exit_code = -1; - } - if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGKILL) { - pr_err("The child exited with unexpected code: %x\n", status); - exit_code = -1; - } - return exit_code; -} - static int kerndat_has_madv_guard(void) { void *map; @@ -2199,10 +2122,6 @@ int kerndat_init(void) pr_err("kerndat_has_timer_cr_ids has failed when initializing kerndat.\n"); ret = -1; } - if (!ret && kerndat_breakpoints()) { - pr_err("kerndat_breakpoints has failed when initializing kerndat.\n"); - ret = -1; - } if (!ret && kerndat_has_madv_guard()) { pr_err("kerndat_has_madv_guard has failed when initializing kerndat.\n"); ret = -1; diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c index e19847b37..c2d9ad976 100644 --- a/criu/parasite-syscall.c +++ b/criu/parasite-syscall.c @@ -421,8 +421,6 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, ictx->flags |= INFECT_NO_MEMFD; if (fault_injected(FI_PARASITE_CONNECT)) ictx->flags |= INFECT_FAIL_CONNECT; - if (fault_injected(FI_NO_BREAKPOINTS) || !kdat.has_breakpoints) - ictx->flags |= INFECT_NO_BREAKPOINTS; if (kdat.compat_cr) ictx->flags |= INFECT_COMPATIBLE; if (kdat.x86_has_ptrace_fpu_xsave_bug) diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c index b02be4a78..772664f5e 100644 --- a/criu/pie/restorer.c +++ b/criu/pie/restorer.c @@ -1747,7 +1747,6 @@ __visible long __export_restore_task(struct task_restore_args *args) n_helpers = args->helpers_n; zombies = args->zombies; n_zombies = args->zombies_n; - *args->breakpoint = rst_sigreturn; #ifdef ARCH_HAS_LONG_PAGES __page_size = args->page_size; #endif diff --git a/test/jenkins/criu-fault.sh b/test/jenkins/criu-fault.sh index 6ee7ce33a..05aa1940a 100755 --- a/test/jenkins/criu-fault.sh +++ b/test/jenkins/criu-fault.sh @@ -15,7 +15,6 @@ if [ $NOBTRFS -eq 1 ] ; then fi ./test/zdtm.py run -t zdtm/static/env00 --fault 129 -f uns || fail -./test/zdtm.py run -t zdtm/transition/fork --fault 130 -f h || fail ./test/zdtm.py run -t zdtm/static/vdso01 --fault 127 || fail ./test/zdtm.py run -t zdtm/static/vdso-proxy --fault 127 --iters 3 || fail