[CRIU] [PATCH 37/78] infect: Move mmap_seized() and syscall_seized() into arch/infect.c
Cyrill Gorcunov
gorcunov at openvz.org
Mon Nov 7 08:36:22 PST 2016
From: Pavel Emelyanov <xemul at virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
criu/arch/aarch64/crtools.c | 60 ---------------
criu/arch/aarch64/include/asm/parasite-syscall.h | 4 -
criu/arch/aarch64/infect.c | 59 +++++++++++++++
criu/arch/arm/crtools.c | 60 ---------------
criu/arch/arm/include/asm/parasite-syscall.h | 4 -
criu/arch/arm/infect.c | 60 +++++++++++++++
criu/arch/ppc64/crtools.c | 54 --------------
criu/arch/ppc64/include/asm/parasite-syscall.h | 4 -
criu/arch/ppc64/infect.c | 54 ++++++++++++++
criu/arch/x86/crtools.c | 89 -----------------------
criu/arch/x86/include/asm/parasite-syscall.h | 4 -
criu/arch/x86/infect.c | 93 ++++++++++++++++++++++++
criu/cr-exec.c | 2 +-
criu/include/infect-priv.h | 9 +++
criu/include/parasite-syscall.h | 5 --
criu/infect.c | 14 ++--
16 files changed, 283 insertions(+), 292 deletions(-)
diff --git a/criu/arch/aarch64/crtools.c b/criu/arch/aarch64/crtools.c
index b3e5e55fcee7..e7e7be9c3403 100644
--- a/criu/arch/aarch64/crtools.c
+++ b/criu/arch/aarch64/crtools.c
@@ -20,23 +20,6 @@
#include "infect.h"
#include "infect-priv.h"
-/*
- * Injected syscall instruction
- */
-const char code_syscall[] = {
- 0x01, 0x00, 0x00, 0xd4, /* SVC #0 */
- 0x00, 0x00, 0x20, 0xd4 /* BRK #0 */
-};
-
-static const int
-code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
-
-static inline void __always_unused __check_code_syscall(void)
-{
- BUILD_BUG_ON(code_syscall_aligned != BUILTIN_SYSCALL_SIZE);
- BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
-}
-
void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
{
regs->pc = new_ip;
@@ -52,33 +35,6 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
return true;
}
-int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
- unsigned long arg1,
- unsigned long arg2,
- unsigned long arg3,
- unsigned long arg4,
- unsigned long arg5,
- unsigned long arg6)
-{
- user_regs_struct_t regs = ctl->orig.regs;
- int err;
-
- regs.regs[8] = (unsigned long)nr;
- regs.regs[0] = arg1;
- regs.regs[1] = arg2;
- regs.regs[2] = arg3;
- regs.regs[3] = arg4;
- regs.regs[4] = arg5;
- regs.regs[5] = arg6;
- regs.regs[6] = 0;
- regs.regs[7] = 0;
-
- err = compel_execute_syscall(ctl, ®s, code_syscall);
-
- *ret = regs.regs[0];
- return err;
-}
-
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))(src)->e
int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd)
@@ -179,22 +135,6 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
return 0;
}
-void *mmap_seized(
- struct parasite_ctl *ctl,
- void *addr, size_t length, int prot,
- int flags, int fd, off_t offset)
-{
- unsigned long map;
- int err;
-
- err = syscall_seized(ctl, __NR_mmap, &map,
- (unsigned long)addr, length, prot, flags, fd, offset);
- if (err < 0 || (long)map < 0)
- map = 0;
-
- return (void *)map;
-}
-
int restore_gpregs(struct rt_sigframe *f, UserRegsEntry *r)
{
#define CPREG1(d) f->uc.uc_mcontext.d = r->d
diff --git a/criu/arch/aarch64/include/asm/parasite-syscall.h b/criu/arch/aarch64/include/asm/parasite-syscall.h
index 7a5591ad5c7c..e420ccbdc625 100644
--- a/criu/arch/aarch64/include/asm/parasite-syscall.h
+++ b/criu/arch/aarch64/include/asm/parasite-syscall.h
@@ -9,8 +9,4 @@ struct parasite_ctl;
void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
-void *mmap_seized(struct parasite_ctl *ctl,
- void *addr, size_t length, int prot,
- int flags, int fd, off_t offset);
-
#endif
diff --git a/criu/arch/aarch64/infect.c b/criu/arch/aarch64/infect.c
index 92b3c73b1e48..2411cd6e8392 100644
--- a/criu/arch/aarch64/infect.c
+++ b/criu/arch/aarch64/infect.c
@@ -12,6 +12,23 @@
#include "infect.h"
#include "infect-priv.h"
+/*
+ * Injected syscall instruction
+ */
+const char code_syscall[] = {
+ 0x01, 0x00, 0x00, 0xd4, /* SVC #0 */
+ 0x00, 0x00, 0x20, 0xd4 /* BRK #0 */
+};
+
+static const int
+code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
+
+static inline void __always_unused __check_code_syscall(void)
+{
+ BUILD_BUG_ON(code_syscall_aligned != BUILTIN_SYSCALL_SIZE);
+ BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
+}
+
int compel_get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t save, void *arg)
{
struct iovec iov;
@@ -39,3 +56,45 @@ err:
return ret;
}
+int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
+ unsigned long arg1,
+ unsigned long arg2,
+ unsigned long arg3,
+ unsigned long arg4,
+ unsigned long arg5,
+ unsigned long arg6)
+{
+ user_regs_struct_t regs = ctl->orig.regs;
+ int err;
+
+ regs.regs[8] = (unsigned long)nr;
+ regs.regs[0] = arg1;
+ regs.regs[1] = arg2;
+ regs.regs[2] = arg3;
+ regs.regs[3] = arg4;
+ regs.regs[4] = arg5;
+ regs.regs[5] = arg6;
+ regs.regs[6] = 0;
+ regs.regs[7] = 0;
+
+ err = compel_execute_syscall(ctl, ®s, code_syscall);
+
+ *ret = regs.regs[0];
+ return err;
+}
+
+void *mmap_re(struct parasite_ctl *ctl,
+ void *addr, size_t length, int prot,
+ int flags, int fd, off_t offset)
+{
+ unsigned long map;
+ int err;
+
+ err = compel_syscall(ctl, __NR_mmap, &map,
+ (unsigned long)addr, length, prot, flags, fd, offset);
+ if (err < 0 || (long)map < 0)
+ map = 0;
+
+ return (void *)map;
+}
+
diff --git a/criu/arch/arm/crtools.c b/criu/arch/arm/crtools.c
index fb267fe85072..78fa02a99082 100644
--- a/criu/arch/arm/crtools.c
+++ b/criu/arch/arm/crtools.c
@@ -21,23 +21,6 @@
#include "infect.h"
#include "infect-priv.h"
-/*
- * Injected syscall instruction
- */
-const char code_syscall[] = {
- 0x00, 0x00, 0x00, 0xef, /* SVC #0 */
- 0xf0, 0x01, 0xf0, 0xe7 /* UDF #32 */
-};
-
-static const int
-code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
-
-static inline __always_unused void __check_code_syscall(void)
-{
- BUILD_BUG_ON(code_syscall_aligned != BUILTIN_SYSCALL_SIZE);
- BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
-}
-
void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
{
regs->ARM_pc = new_ip;
@@ -56,31 +39,6 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
return true;
}
-int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
- unsigned long arg1,
- unsigned long arg2,
- unsigned long arg3,
- unsigned long arg4,
- unsigned long arg5,
- unsigned long arg6)
-{
- user_regs_struct_t regs = ctl->orig.regs;
- int err;
-
- regs.ARM_r7 = (unsigned long)nr;
- regs.ARM_r0 = arg1;
- regs.ARM_r1 = arg2;
- regs.ARM_r2 = arg3;
- regs.ARM_r3 = arg4;
- regs.ARM_r4 = arg5;
- regs.ARM_r5 = arg6;
-
- err = compel_execute_syscall(ctl, ®s, code_syscall);
-
- *ret = regs.ARM_r0;
- return err;
-}
-
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))((src)->ARM_##e)
int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
@@ -172,24 +130,6 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
return 0;
}
-void *mmap_seized(struct parasite_ctl *ctl,
- void *addr, size_t length, int prot,
- int flags, int fd, off_t offset)
-{
- unsigned long map;
- int err;
-
- if (offset & ~PAGE_MASK)
- return 0;
-
- err = syscall_seized(ctl, __NR_mmap2, &map,
- (unsigned long)addr, length, prot, flags, fd, offset >> 12);
- if (err < 0 || map > kdat.task_size)
- map = 0;
-
- return (void *)map;
-}
-
int restore_gpregs(struct rt_sigframe *f, UserArmRegsEntry *r)
{
#define CPREG1(d) f->sig.uc.uc_mcontext.arm_##d = r->d
diff --git a/criu/arch/arm/include/asm/parasite-syscall.h b/criu/arch/arm/include/asm/parasite-syscall.h
index 7a5591ad5c7c..e420ccbdc625 100644
--- a/criu/arch/arm/include/asm/parasite-syscall.h
+++ b/criu/arch/arm/include/asm/parasite-syscall.h
@@ -9,8 +9,4 @@ struct parasite_ctl;
void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
-void *mmap_seized(struct parasite_ctl *ctl,
- void *addr, size_t length, int prot,
- int flags, int fd, off_t offset);
-
#endif
diff --git a/criu/arch/arm/infect.c b/criu/arch/arm/infect.c
index d524d513026f..ec84c20aabb5 100644
--- a/criu/arch/arm/infect.c
+++ b/criu/arch/arm/infect.c
@@ -10,6 +10,23 @@
#include "infect.h"
#include "infect-priv.h"
+/*
+ * Injected syscall instruction
+ */
+const char code_syscall[] = {
+ 0x00, 0x00, 0x00, 0xef, /* SVC #0 */
+ 0xf0, 0x01, 0xf0, 0xe7 /* UDF #32 */
+};
+
+static const int
+code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
+
+static inline __always_unused void __check_code_syscall(void)
+{
+ BUILD_BUG_ON(code_syscall_aligned != BUILTIN_SYSCALL_SIZE);
+ BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
+}
+
#define PTRACE_GETVFPREGS 27
int compel_get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t save, void *arg)
{
@@ -45,3 +62,46 @@ err:
return ret;
}
+int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
+ unsigned long arg1,
+ unsigned long arg2,
+ unsigned long arg3,
+ unsigned long arg4,
+ unsigned long arg5,
+ unsigned long arg6)
+{
+ user_regs_struct_t regs = ctl->orig.regs;
+ int err;
+
+ regs.ARM_r7 = (unsigned long)nr;
+ regs.ARM_r0 = arg1;
+ regs.ARM_r1 = arg2;
+ regs.ARM_r2 = arg3;
+ regs.ARM_r3 = arg4;
+ regs.ARM_r4 = arg5;
+ regs.ARM_r5 = arg6;
+
+ err = compel_execute_syscall(ctl, ®s, code_syscall);
+
+ *ret = regs.ARM_r0;
+ return err;
+}
+
+void *remote_mmap(struct parasite_ctl *ctl,
+ void *addr, size_t length, int prot,
+ int flags, int fd, off_t offset)
+{
+ unsigned long map;
+ int err;
+
+ if (offset & ~PAGE_MASK)
+ return 0;
+
+ err = compel_syscall(ctl, __NR_mmap2, &map,
+ (unsigned long)addr, length, prot, flags, fd, offset >> 12);
+ if (err < 0 || map > kdat.task_size)
+ map = 0;
+
+ return (void *)map;
+}
+
diff --git a/criu/arch/ppc64/crtools.c b/criu/arch/ppc64/crtools.c
index fbcdf51497ec..33c1ec416056 100644
--- a/criu/arch/ppc64/crtools.c
+++ b/criu/arch/ppc64/crtools.c
@@ -25,20 +25,6 @@
#include "images/core.pb-c.h"
#include "images/creds.pb-c.h"
-/*
- * Injected syscall instruction
- */
-const u32 code_syscall[] = {
- 0x44000002, /* sc */
- 0x0fe00000 /* twi 31,0,0 */
-};
-
-static inline void __always_unused __check_code_syscall(void)
-{
- BUILD_BUG_ON(sizeof(code_syscall) != BUILTIN_SYSCALL_SIZE);
- BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
-}
-
void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
{
/*
@@ -60,31 +46,6 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
return true;
}
-int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
- unsigned long arg1,
- unsigned long arg2,
- unsigned long arg3,
- unsigned long arg4,
- unsigned long arg5,
- unsigned long arg6)
-{
- user_regs_struct_t regs = ctl->orig.regs;
- int err;
-
- regs.gpr[0] = (unsigned long)nr;
- regs.gpr[3] = arg1;
- regs.gpr[4] = arg2;
- regs.gpr[5] = arg3;
- regs.gpr[6] = arg4;
- regs.gpr[7] = arg5;
- regs.gpr[8] = arg6;
-
- err = compel_execute_syscall(ctl, ®s, (char*)code_syscall);
-
- *ret = regs.gpr[3];
- return err;
-}
-
static UserPpc64FpstateEntry *copy_fp_regs(uint64_t *fpregs)
{
UserPpc64FpstateEntry *fpe;
@@ -565,18 +526,3 @@ int restore_gpregs(struct rt_sigframe *f, UserPpc64RegsEntry *r)
return 0;
}
-
-void *mmap_seized(struct parasite_ctl *ctl,
- void *addr, size_t length, int prot,
- int flags, int fd, off_t offset)
-{
- unsigned long map = 0;
- int err;
-
- err = syscall_seized(ctl, __NR_mmap, &map,
- (unsigned long)addr, length, prot, flags, fd, offset);
- if (err < 0 || (long)map < 0)
- map = 0;
-
- return (void *)map;
-}
diff --git a/criu/arch/ppc64/include/asm/parasite-syscall.h b/criu/arch/ppc64/include/asm/parasite-syscall.h
index 7a5591ad5c7c..e420ccbdc625 100644
--- a/criu/arch/ppc64/include/asm/parasite-syscall.h
+++ b/criu/arch/ppc64/include/asm/parasite-syscall.h
@@ -9,8 +9,4 @@ struct parasite_ctl;
void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
-void *mmap_seized(struct parasite_ctl *ctl,
- void *addr, size_t length, int prot,
- int flags, int fd, off_t offset);
-
#endif
diff --git a/criu/arch/ppc64/infect.c b/criu/arch/ppc64/infect.c
index 6c9692f7c717..c76bef5e758b 100644
--- a/criu/arch/ppc64/infect.c
+++ b/criu/arch/ppc64/infect.c
@@ -19,6 +19,20 @@
#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */
#endif
+/*
+ * Injected syscall instruction
+ */
+const u32 code_syscall[] = {
+ 0x44000002, /* sc */
+ 0x0fe00000 /* twi 31,0,0 */
+};
+
+static inline void __check_code_syscall(void)
+{
+ BUILD_BUG_ON(sizeof(code_syscall) != BUILTIN_SYSCALL_SIZE);
+ BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
+}
+
/* This is the layout of the POWER7 VSX registers and the way they
* overlap with the existing FPR and VMX registers.
*
@@ -241,3 +255,43 @@ int compel_get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t save, v
return save(arg, ®s, &fpregs);
}
+
+int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
+ unsigned long arg1,
+ unsigned long arg2,
+ unsigned long arg3,
+ unsigned long arg4,
+ unsigned long arg5,
+ unsigned long arg6)
+{
+ user_regs_struct_t regs = ctl->orig.regs;
+ int err;
+
+ regs.gpr[0] = (unsigned long)nr;
+ regs.gpr[3] = arg1;
+ regs.gpr[4] = arg2;
+ regs.gpr[5] = arg3;
+ regs.gpr[6] = arg4;
+ regs.gpr[7] = arg5;
+ regs.gpr[8] = arg6;
+
+ err = compel_execute_syscall(ctl, ®s, (char*)code_syscall);
+
+ *ret = regs.gpr[3];
+ return err;
+}
+
+void *remote_mmap(struct parasite_ctl *ctl,
+ void *addr, size_t length, int prot,
+ int flags, int fd, off_t offset)
+{
+ unsigned long map = 0;
+ int err;
+
+ err = compel_syscall(ctl, __NR_mmap, &map,
+ (unsigned long)addr, length, prot, flags, fd, offset);
+ if (err < 0 || (long)map < 0)
+ map = 0;
+
+ return (void *)map;
+}
diff --git a/criu/arch/x86/crtools.c b/criu/arch/x86/crtools.c
index 363a52e07c88..de3cd02f8a60 100644
--- a/criu/arch/x86/crtools.c
+++ b/criu/arch/x86/crtools.c
@@ -32,31 +32,6 @@
#include "images/creds.pb-c.h"
/*
- * Injected syscall instruction
- */
-const char code_syscall[] = {
- 0x0f, 0x05, /* syscall */
- 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc /* int 3, ... */
-};
-
-const char code_int_80[] = {
- 0xcd, 0x80, /* int $0x80 */
- 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc /* int 3, ... */
-};
-
-static const int
-code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
-static const int
-code_int_80_aligned = round_up(sizeof(code_syscall), sizeof(long));
-
-static inline __always_unused void __check_code_syscall(void)
-{
- BUILD_BUG_ON(code_int_80_aligned != BUILTIN_SYSCALL_SIZE);
- BUILD_BUG_ON(code_syscall_aligned != BUILTIN_SYSCALL_SIZE);
- BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
-}
-
-/*
* regs must be inited when calling this function from original context
*/
void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
@@ -146,47 +121,6 @@ bool arch_can_dump_task(struct parasite_ctl *ctl)
return true;
}
-int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
- unsigned long arg1,
- unsigned long arg2,
- unsigned long arg3,
- unsigned long arg4,
- unsigned long arg5,
- unsigned long arg6)
-{
- user_regs_struct_t regs = ctl->orig.regs;
- int err;
-
- if (user_regs_native(®s)) {
- user_regs_struct64 *r = ®s.native;
-
- r->ax = (uint64_t)nr;
- r->di = arg1;
- r->si = arg2;
- r->dx = arg3;
- r->r10 = arg4;
- r->r8 = arg5;
- r->r9 = arg6;
-
- err = compel_execute_syscall(ctl, ®s, code_syscall);
- } else {
- user_regs_struct32 *r = ®s.compat;
-
- r->ax = (uint32_t)nr;
- r->bx = arg1;
- r->cx = arg2;
- r->dx = arg3;
- r->si = arg4;
- r->di = arg5;
- r->bp = arg6;
-
- err = compel_execute_syscall(ctl, ®s, code_int_80);
- }
-
- *ret = get_user_reg(®s, ax);
- return err;
-}
-
int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpregs)
{
CoreEntry *core = x;
@@ -548,29 +482,6 @@ int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
return 0;
}
-void *mmap_seized(struct parasite_ctl *ctl,
- void *addr, size_t length, int prot,
- int flags, int fd, off_t offset)
-{
- unsigned long map;
- int err;
- bool compat_task = !user_regs_native(&ctl->orig.regs);
-
- err = syscall_seized(ctl, __NR(mmap, compat_task), &map,
- (unsigned long)addr, length, prot, flags, fd, offset);
- if (err < 0)
- return NULL;
-
- if (IS_ERR_VALUE(map)) {
- if (map == -EACCES && (prot & PROT_WRITE) && (prot & PROT_EXEC))
- pr_warn("mmap(PROT_WRITE | PROT_EXEC) failed for %d, "
- "check selinux execmem policy\n", ctl->rpid);
- return NULL;
- }
-
- return (void *)map;
-}
-
#ifdef CONFIG_X86_64
#define CPREG32(d) f->compat.uc.uc_mcontext.d = r->d
#else
diff --git a/criu/arch/x86/include/asm/parasite-syscall.h b/criu/arch/x86/include/asm/parasite-syscall.h
index cbc0442dd722..18c746f6fc59 100644
--- a/criu/arch/x86/include/asm/parasite-syscall.h
+++ b/criu/arch/x86/include/asm/parasite-syscall.h
@@ -20,8 +20,4 @@ struct parasite_ctl;
void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
-void *mmap_seized(struct parasite_ctl *ctl,
- void *addr, size_t length, int prot,
- int flags, int fd, off_t offset);
-
#endif
diff --git a/criu/arch/x86/infect.c b/criu/arch/x86/infect.c
index 7c7537cb26d3..ad3ce267958d 100644
--- a/criu/arch/x86/infect.c
+++ b/criu/arch/x86/infect.c
@@ -2,6 +2,10 @@
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/auxv.h>
+#include <sys/mman.h>
+#include "asm/parasite-syscall.h"
+#include "uapi/std/syscall-codes.h"
+#include "err.h"
#include "asm/fpu.h"
#include "asm/types.h"
#include "errno.h"
@@ -10,6 +14,31 @@
#include "infect.h"
#include "infect-priv.h"
+/*
+ * Injected syscall instruction
+ */
+const char code_syscall[] = {
+ 0x0f, 0x05, /* syscall */
+ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc /* int 3, ... */
+};
+
+const char code_int_80[] = {
+ 0xcd, 0x80, /* int $0x80 */
+ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc /* int 3, ... */
+};
+
+static const int
+code_syscall_aligned = round_up(sizeof(code_syscall), sizeof(long));
+static const int
+code_int_80_aligned = round_up(sizeof(code_syscall), sizeof(long));
+
+static inline __always_unused void __check_code_syscall(void)
+{
+ BUILD_BUG_ON(code_int_80_aligned != BUILTIN_SYSCALL_SIZE);
+ BUILD_BUG_ON(code_syscall_aligned != BUILTIN_SYSCALL_SIZE);
+ BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
+}
+
#define get_signed_user_reg(pregs, name) \
((user_regs_native(pregs)) ? (int64_t)((pregs)->native.name) : \
(int32_t)((pregs)->compat.name))
@@ -76,3 +105,67 @@ out:
err:
return ret;
}
+
+int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
+ unsigned long arg1,
+ unsigned long arg2,
+ unsigned long arg3,
+ unsigned long arg4,
+ unsigned long arg5,
+ unsigned long arg6)
+{
+ user_regs_struct_t regs = ctl->orig.regs;
+ int err;
+
+ if (user_regs_native(®s)) {
+ user_regs_struct64 *r = ®s.native;
+
+ r->ax = (uint64_t)nr;
+ r->di = arg1;
+ r->si = arg2;
+ r->dx = arg3;
+ r->r10 = arg4;
+ r->r8 = arg5;
+ r->r9 = arg6;
+
+ err = compel_execute_syscall(ctl, ®s, code_syscall);
+ } else {
+ user_regs_struct32 *r = ®s.compat;
+
+ r->ax = (uint32_t)nr;
+ r->bx = arg1;
+ r->cx = arg2;
+ r->dx = arg3;
+ r->si = arg4;
+ r->di = arg5;
+ r->bp = arg6;
+
+ err = compel_execute_syscall(ctl, ®s, code_int_80);
+ }
+
+ *ret = get_user_reg(®s, ax);
+ return err;
+}
+
+void *remote_mmap(struct parasite_ctl *ctl,
+ void *addr, size_t length, int prot,
+ int flags, int fd, off_t offset)
+{
+ unsigned long map;
+ int err;
+ bool compat_task = !user_regs_native(&ctl->orig.regs);
+
+ err = compel_syscall(ctl, __NR(mmap, compat_task), &map,
+ (unsigned long)addr, length, prot, flags, fd, offset);
+ if (err < 0)
+ return NULL;
+
+ if (IS_ERR_VALUE(map)) {
+ if (map == -EACCES && (prot & PROT_WRITE) && (prot & PROT_EXEC))
+ pr_warn("mmap(PROT_WRITE | PROT_EXEC) failed for %d, "
+ "check selinux execmem policy\n", ctl->rpid);
+ return NULL;
+ }
+
+ return (void *)map;
+}
diff --git a/criu/cr-exec.c b/criu/cr-exec.c
index 098bf96d7ced..e7b3f058f1a4 100644
--- a/criu/cr-exec.c
+++ b/criu/cr-exec.c
@@ -96,7 +96,7 @@ static int execute_syscall(struct parasite_ctl *ctl,
pr_info("Calling %d with %lu %lu %lu %lu %lu %lu\n", scd->nr,
args[0], args[1], args[2], args[3], args[4], args[5]);
- err = syscall_seized(ctl, scd->nr, &ret,
+ err = compel_syscall(ctl, scd->nr, &ret,
args[0], args[1], args[2], args[3], args[4], args[5]);
if (err)
return err;
diff --git a/criu/include/infect-priv.h b/criu/include/infect-priv.h
index b33a635161d0..3ddd1175f754 100644
--- a/criu/include/infect-priv.h
+++ b/criu/include/infect-priv.h
@@ -40,4 +40,13 @@ int parasite_wait_ack(int sockfd, unsigned int cmd, struct ctl_msg *m);
/* XXX -- remove with cr-exec.c */
extern int compel_map_exchange(struct parasite_ctl *ctl, unsigned long size);
+extern int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
+ unsigned long arg1, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4,
+ unsigned long arg5, unsigned long arg6);
+
+
+extern void *remote_mmap(struct parasite_ctl *ctl,
+ void *addr, size_t length, int prot,
+ int flags, int fd, off_t offset);
#endif
diff --git a/criu/include/parasite-syscall.h b/criu/include/parasite-syscall.h
index 2efec72d4a03..5c4ca6de5a9b 100644
--- a/criu/include/parasite-syscall.h
+++ b/criu/include/parasite-syscall.h
@@ -64,11 +64,6 @@ extern struct parasite_tty_args *parasite_dump_tty(struct parasite_ctl *ctl, int
extern int parasite_init_threads_seized(struct parasite_ctl *ctl, struct pstree_item *item);
extern int parasite_fini_threads_seized(struct parasite_ctl *ctl);
-extern int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
- unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4,
- unsigned long arg5, unsigned long arg6);
-
extern bool arch_can_dump_task(struct parasite_ctl *ctl);
#endif /* __CR_PARASITE_SYSCALL_H__ */
diff --git a/criu/infect.c b/criu/infect.c
index 5090413b1b6e..14fcc74767f9 100644
--- a/criu/infect.c
+++ b/criu/infect.c
@@ -603,7 +603,7 @@ static int parasite_mmap_exchange(struct parasite_ctl *ctl, unsigned long size)
{
int fd;
- ctl->remote_map = mmap_seized(ctl, NULL, size,
+ ctl->remote_map = remote_mmap(ctl, NULL, size,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANONYMOUS | MAP_SHARED, -1, 0);
if (!ctl->remote_map) {
@@ -650,13 +650,13 @@ static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size)
return -1;
}
- ret = syscall_seized(ctl, __NR(memfd_create, compat_task), &sret,
+ ret = compel_syscall(ctl, __NR(memfd_create, compat_task), &sret,
(unsigned long)where, 0, 0, 0, 0, 0);
if (ptrace_poke_area(pid, orig_code, where, sizeof(orig_code))) {
fd = (int)(long)sret;
if (fd >= 0)
- syscall_seized(ctl, __NR(close, compat_task), &sret,
+ compel_syscall(ctl, __NR(close, compat_task), &sret,
fd, 0, 0, 0, 0, 0);
pr_err("Can't restore memfd args (pid: %d)\n", pid);
return -1;
@@ -681,7 +681,7 @@ static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size)
goto err_cure;
}
- ctl->remote_map = mmap_seized(ctl, NULL, size,
+ ctl->remote_map = remote_mmap(ctl, NULL, size,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FILE | MAP_SHARED, fd, 0);
if (!ctl->remote_map) {
@@ -697,7 +697,7 @@ static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size)
goto err_curef;
}
- syscall_seized(ctl, __NR(close, compat_task), &sret, fd, 0, 0, 0, 0, 0);
+ compel_syscall(ctl, __NR(close, compat_task), &sret, fd, 0, 0, 0, 0, 0);
close(lfd);
pr_info("Set up parasite blob using memfd\n");
@@ -706,7 +706,7 @@ static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size)
err_curef:
close(lfd);
err_cure:
- syscall_seized(ctl, __NR(close, compat_task), &sret, fd, 0, 0, 0, 0, 0);
+ compel_syscall(ctl, __NR(close, compat_task), &sret, fd, 0, 0, 0, 0, 0);
return -1;
}
@@ -964,7 +964,7 @@ int compel_cure_remote(struct parasite_ctl *ctl)
} else {
unsigned long ret;
- syscall_seized(ctl, __NR(munmap, !compel_mode_native(ctl)), &ret,
+ compel_syscall(ctl, __NR(munmap, !compel_mode_native(ctl)), &ret,
(unsigned long)ctl->remote_map, ctl->map_length,
0, 0, 0, 0);
if (ret) {
--
2.7.4
More information about the CRIU
mailing list