mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-23 18:19:39 +00:00
Why should we have self-unmapping code in parasite?
It looks like, we can drop this code using simple sys_unmap()
injection (like that I did for `criu exec` action and for cases where we
failed to insert parasite by some reason, but still need to unmap remotes).
It's an RFC, so just a suggestion - maybe I miss something you have in
mind - please, describe that/those things.
My motivation is:
- less code, defined commands for PIE, one BUG() less, one jump to PIE less
- I'm making one 64-bit parasite on x86 instead of two 32 and 64 bit.
It works (branch 32-one-parasite) with long-jump in the beginning to
64-bit code from 32-bit task.
On parasite curing it sig-returns from 64-bit parasite to 32-bit task,
this point we're trapping in CRIU. After that we command parasite to
unmap itself, so it long-jumps again to parasite 64-bit code, unmaps,
we caught task after sys_unmap and the task is with 64-bit CS.
We can't set 32-bit registers after this - kernel checks that
registers set is the same on PTRACE_SETREGSET:
> > static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
> > struct iovec *kiov)
...
> > if (!regset || (kiov->iov_len % regset->size) != 0)
> > return -EINVAL;
So, to return again to 32-bit task I need sigreturn() again or add
long-jump with 32-bit CS.
I've disable that for 32-bit testing with (in compel_cure_remote):
- if (ctl->addr_cmd) {
+ if (ctl->addr_cmd && user_regs_native(&ctl->orig.regs)) {
And it works. It also works for native tasks, so why should we keep it?
travis-ci: success for compel: kill self-unmap in parasite
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Pavel Emelyanov <xemul@virtuozzo.com>
Cc: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
Acked-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
47 lines
1,011 B
C
47 lines
1,011 B
C
#ifndef __COMPEL_RPC_H__
|
|
#define __COMPEL_RPC_H__
|
|
struct ctl_msg {
|
|
uint32_t cmd; /* command itself */
|
|
uint32_t ack; /* ack on command */
|
|
int32_t err; /* error code on reply */
|
|
};
|
|
|
|
#define ctl_msg_cmd(_cmd) \
|
|
(struct ctl_msg){.cmd = _cmd, }
|
|
|
|
#define ctl_msg_ack(_cmd, _err) \
|
|
(struct ctl_msg){.cmd = _cmd, .ack = _cmd, .err = _err, }
|
|
|
|
/*
|
|
* NOTE: each command's args should be arch-independed sized.
|
|
* If you want to use one of the standard types, declare
|
|
* alternative type for compatible tasks in parasite-compat.h
|
|
*/
|
|
enum {
|
|
PARASITE_CMD_IDLE = 0,
|
|
PARASITE_CMD_ACK,
|
|
|
|
PARASITE_CMD_INIT_DAEMON,
|
|
|
|
/*
|
|
* This must be greater than INITs.
|
|
*/
|
|
PARASITE_CMD_FINI,
|
|
|
|
__PARASITE_END_CMDS,
|
|
};
|
|
|
|
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;
|
|
};
|
|
|
|
struct parasite_unmap_args {
|
|
uint64_t parasite_start;
|
|
uint64_t parasite_len;
|
|
};
|
|
#endif
|