From c7544894fe8de4f00c396c6fe4ce5c0542689bb5 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Fri, 1 Jan 2021 01:21:44 +0300 Subject: [PATCH] dump/ppc64,arm,mips: sanitize the ERESTART_RESTARTBLOCK -> EINTR transition 1. The -ERESTART_RESTARTBLOCK case in get_task_regs() depends on kernel internals too much, and for no reason. We shouldn't rely on fact that a) we are going to do sigreturn() and b) restore_sigcontext() always sets restart_block->fn = do_no_restart_syscall which returns -EINTR. Just change this code to enforce -EINTR after restore, this is what we actually want until we teach criu to handle ERESTART_RESTARTBLOCK. 2. Add pr_warn() to make the potential bug-reports more understandable, a sane application should handle -EINTR correctly but this is not always the case. Fixes: #1325 Report-by: Mr Travis Inspired-by: dd71cca58ada ("dump/x86: sanitize the ERESTART_RESTARTBLOCK -> EINTR transition") Signed-off-by: Andrei Vagin --- compel/arch/arm/src/lib/infect.c | 6 ++++-- compel/arch/mips/src/lib/infect.c | 7 ++++--- compel/arch/ppc64/src/lib/infect.c | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/compel/arch/arm/src/lib/infect.c b/compel/arch/arm/src/lib/infect.c index 0053bef58..75b985b74 100644 --- a/compel/arch/arm/src/lib/infect.c +++ b/compel/arch/arm/src/lib/infect.c @@ -4,6 +4,8 @@ #include #include #include +#include + #include "common/page.h" #include "uapi/compel/asm/infect-types.h" #include "log.h" @@ -91,8 +93,8 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, regs->ARM_pc -= 4; break; case -ERESTART_RESTARTBLOCK: - regs->ARM_r0 = __NR_restart_syscall; - regs->ARM_pc -= 4; + pr_warn("Will restore %d with interrupted system call\n", pid); + regs->ARM_r0 = -EINTR; break; } } diff --git a/compel/arch/mips/src/lib/infect.c b/compel/arch/mips/src/lib/infect.c index 521528f76..35e947cc0 100755 --- a/compel/arch/mips/src/lib/infect.c +++ b/compel/arch/mips/src/lib/infect.c @@ -2,6 +2,8 @@ #include #include #include +#include + #include #include #include "errno.h" @@ -142,9 +144,8 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, regs->cp0_epc -= 4; break; case ERESTART_RESTARTBLOCK: - regs->regs[2] = __NR_restart_syscall; - regs->regs[7] = regs->regs[26]; - regs->cp0_epc -= 4; + pr_warn("Will restore %d with interrupted system call\n", pid); + regs->regs[2] = -EINTR; break; } regs->regs[0] = 0; diff --git a/compel/arch/ppc64/src/lib/infect.c b/compel/arch/ppc64/src/lib/infect.c index 637acd46d..b2c725f62 100644 --- a/compel/arch/ppc64/src/lib/infect.c +++ b/compel/arch/ppc64/src/lib/infect.c @@ -330,8 +330,8 @@ static int __get_task_regs(pid_t pid, user_regs_struct_t *regs, regs->nip -= 4; break; case ERESTART_RESTARTBLOCK: - regs->gpr[0] = __NR_restart_syscall; - regs->nip -= 4; + pr_warn("Will restore %d with interrupted system call\n", pid); + regs->gpr[3] = EINTR; break; } }