Commit e9700c4f authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Andrei Vagin

infect: Introduce and use parasite_blob_desc

The _desc is to describe where libcompel should task
parasite code from. For now the parasite is taken as
piece of memory, but more ways to load the code will
come soon.
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 901ccfb8
...@@ -32,6 +32,8 @@ struct parasite_ctl { ...@@ -32,6 +32,8 @@ struct parasite_ctl {
void *addr_args; /* address for arguments */ void *addr_args; /* address for arguments */
unsigned long args_size; unsigned long args_size;
int tsock; /* transport socket for transferring fds */ int tsock; /* transport socket for transferring fds */
struct parasite_blob_desc pblob;
}; };
#define MEMFD_FNAME "CRIUMFD" #define MEMFD_FNAME "CRIUMFD"
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "asm/infect-types.h" #include "asm/infect-types.h"
#include <compel/ksigset.h> #include <compel/ksigset.h>
#include <compel/compel.h>
#define PARASITE_START_AREA_MIN (4096) #define PARASITE_START_AREA_MIN (4096)
...@@ -120,6 +121,19 @@ extern struct infect_ctx *compel_infect_ctx(struct parasite_ctl *); ...@@ -120,6 +121,19 @@ extern struct infect_ctx *compel_infect_ctx(struct parasite_ctl *);
#define INFECT_NO_BREAKPOINTS 0x4 /* no breakpoints in pie tracking */ #define INFECT_NO_BREAKPOINTS 0x4 /* no breakpoints in pie tracking */
#define INFECT_HAS_COMPAT_SIGRETURN 0x8 #define INFECT_HAS_COMPAT_SIGRETURN 0x8
struct parasite_blob_desc {
const void *mem;
size_t bsize; /* size of the blob */
size_t size; /* size of the blob with relocs */
unsigned long parasite_ip_off;
unsigned long addr_cmd_off;
unsigned long addr_arg_off;
compel_reloc_t *relocs;
unsigned int nr_relocs;
};
extern struct parasite_blob_desc *compel_parasite_blob_desc(struct parasite_ctl *);
typedef int (*save_regs_t)(void *, user_regs_struct_t *, user_fpregs_struct_t *); typedef int (*save_regs_t)(void *, user_regs_struct_t *, user_fpregs_struct_t *);
extern int compel_get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t, void *); extern int compel_get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t, void *);
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <linux/seccomp.h> #include <linux/seccomp.h>
#include "pie-relocs.h" #include "pie-relocs.h"
#include "parasite-blob.h"
#include "criu-log.h" #include "criu-log.h"
#include "common/bug.h" #include "common/bug.h"
#include "common/xmalloc.h" #include "common/xmalloc.h"
...@@ -743,27 +742,6 @@ int compel_map_exchange(struct parasite_ctl *ctl, unsigned long size) ...@@ -743,27 +742,6 @@ int compel_map_exchange(struct parasite_ctl *ctl, unsigned long size)
return ret; return ret;
} }
/* the parasite prefix is added by gen_offsets.sh */
#define __pblob_offset(ptype, symbol) \
parasite_ ## ptype ## _blob_offset__ ## symbol
#define parasite_sym(pblob, ptype, symbol) \
((void *)(pblob) + __pblob_offset(ptype, symbol))
#define init_parasite_ctl(ctl, blob_type) \
do { \
memcpy(ctl->local_map, parasite_##blob_type##_blob, \
sizeof(parasite_##blob_type##_blob)); \
ELF_RELOCS_APPLY(parasite_##blob_type, \
ctl->local_map, ctl->remote_map); \
/* Setup the rest of a control block */ \
ctl->parasite_ip = (unsigned long)parasite_sym(ctl->remote_map, \
blob_type, __export_parasite_head_start); \
ctl->addr_cmd = parasite_sym(ctl->local_map, blob_type, \
__export_parasite_cmd); \
ctl->addr_args = parasite_sym(ctl->local_map, blob_type, \
__export_parasite_args); \
} while (0)
int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size) int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size)
{ {
int ret; int ret;
...@@ -782,12 +760,7 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l ...@@ -782,12 +760,7 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
* without using ptrace at all. * without using ptrace at all.
*/ */
if (compel_mode_native(ctl)) parasite_size = ctl->pblob.size;
parasite_size = pie_size(parasite_native);
#ifdef CONFIG_COMPAT
else
parasite_size = pie_size(parasite_compat);
#endif
ctl->args_size = round_up(args_size, PAGE_SIZE); ctl->args_size = round_up(args_size, PAGE_SIZE);
parasite_size += ctl->args_size; parasite_size += ctl->args_size;
...@@ -803,12 +776,14 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l ...@@ -803,12 +776,14 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
pr_info("Putting parasite blob into %p->%p\n", ctl->local_map, ctl->remote_map); pr_info("Putting parasite blob into %p->%p\n", ctl->local_map, ctl->remote_map);
if (compel_mode_native(ctl)) ctl->parasite_ip = (unsigned long)(ctl->remote_map + ctl->pblob.parasite_ip_off);
init_parasite_ctl(ctl, native); ctl->addr_cmd = ctl->local_map + ctl->pblob.addr_cmd_off;
#ifdef CONFIG_COMPAT ctl->addr_args = ctl->local_map + ctl->pblob.addr_arg_off;
else
init_parasite_ctl(ctl, compat); memcpy(ctl->local_map, ctl->pblob.mem, ctl->pblob.size);
#endif if (ctl->pblob.nr_relocs)
elf_relocs_apply(ctl->local_map, ctl->remote_map, ctl->pblob.bsize,
ctl->pblob.relocs, ctl->pblob.nr_relocs);
p = parasite_size; p = parasite_size;
...@@ -1252,3 +1227,8 @@ struct infect_ctx *compel_infect_ctx(struct parasite_ctl *ctl) ...@@ -1252,3 +1227,8 @@ struct infect_ctx *compel_infect_ctx(struct parasite_ctl *ctl)
{ {
return &ctl->ictx; return &ctl->ictx;
} }
struct parasite_blob_desc *compel_parasite_blob_desc(struct parasite_ctl *ctl)
{
return &ctl->pblob;
}
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "common/compiler.h"
#include "types.h" #include "types.h"
#include "protobuf.h" #include "protobuf.h"
#include "images/sa.pb-c.h" #include "images/sa.pb-c.h"
...@@ -43,6 +44,7 @@ ...@@ -43,6 +44,7 @@
#include "infect.h" #include "infect.h"
#include "infect-rpc.h" #include "infect-rpc.h"
#include "parasite-blob.h"
unsigned long get_exec_start(struct vm_area_list *vmas) unsigned long get_exec_start(struct vm_area_list *vmas)
{ {
...@@ -522,11 +524,37 @@ static int make_sigframe(void *arg, struct rt_sigframe *sf, struct rt_sigframe * ...@@ -522,11 +524,37 @@ static int make_sigframe(void *arg, struct rt_sigframe *sf, struct rt_sigframe *
return construct_sigframe(sf, rtsf, bs, (CoreEntry *)arg); return construct_sigframe(sf, rtsf, bs, (CoreEntry *)arg);
} }
/* the parasite prefix is added by gen_offsets.sh */
#define pblob_offset(ptype, symbol) \
parasite_ ## ptype ## _blob_offset__ ## symbol
#ifdef CONFIG_PIEGEN
#define init_blob_relocs(bdesc, blob_type) \
do { \
bdesc->relocs = parasite_##blob_type##_relocs; \
bdesc->nr_relocs = ARRAY_SIZE(parasite_##blob_type##_relocs); \
} while (0)
#else
#define init_blob_relocs(bdesc, blob_type)
#endif
#define init_blob_desc(bdesc, blob_type) do { \
pbd->size = pie_size(parasite_##blob_type); \
bdesc->mem = parasite_##blob_type##_blob; \
bdesc->bsize = sizeof(parasite_##blob_type##_blob); \
/* Setup the rest of a control block */ \
bdesc->parasite_ip_off = pblob_offset(blob_type, __export_parasite_head_start); \
bdesc->addr_cmd_off = pblob_offset(blob_type, __export_parasite_cmd); \
bdesc->addr_arg_off = pblob_offset(blob_type, __export_parasite_args); \
init_blob_relocs(bdesc, blob_type); \
} while (0)
struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
struct vm_area_list *vma_area_list) struct vm_area_list *vma_area_list)
{ {
struct parasite_ctl *ctl; struct parasite_ctl *ctl;
struct infect_ctx *ictx; struct infect_ctx *ictx;
struct parasite_blob_desc *pbd;
unsigned long p; unsigned long p;
BUG_ON(item->threads[0].real != pid); BUG_ON(item->threads[0].real != pid);
...@@ -564,6 +592,14 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, ...@@ -564,6 +592,14 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
ictx->log_fd = log_get_fd(); ictx->log_fd = log_get_fd();
pbd = compel_parasite_blob_desc(ctl);
if (compel_mode_native(ctl))
init_blob_desc(pbd, native);
#ifdef CONFIG_COMPAT
else
init_blob_desc(pbd, compat);
#endif
parasite_ensure_args_size(dump_pages_args_size(vma_area_list)); parasite_ensure_args_size(dump_pages_args_size(vma_area_list));
parasite_ensure_args_size(aio_rings_args_size(vma_area_list)); parasite_ensure_args_size(aio_rings_args_size(vma_area_list));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment