Commit dcb1cbfb authored by Cyrill Gorcunov's avatar Cyrill Gorcunov

Rework parasite code

 - make control block to keep all information
   needed to run injected syscall and parasite
   blobs

 - add ptrace_swap_area helper

 - handle both parasite engine calls and injected
   syscalls by single __parasite_execute function

 - drop jerr() usage

 - bring back handling of inflight signals from
   original program inside parasite code
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent 47ee1213
...@@ -1225,7 +1225,7 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset) ...@@ -1225,7 +1225,7 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
goto err; goto err;
} }
ret = parasite_cure_seized(parasite_ctl, &vma_area_list); ret = parasite_cure_seized(parasite_ctl);
if (ret) { if (ret) {
pr_err("Can't cure (pid: %d) from parasite\n", pid); pr_err("Can't cure (pid: %d) from parasite\n", pid);
goto err; goto err;
......
...@@ -17,22 +17,27 @@ struct parasite_ctl { ...@@ -17,22 +17,27 @@ struct parasite_ctl {
void * remote_map; void * remote_map;
void * local_map; void * local_map;
unsigned long map_length; unsigned long map_length;
unsigned long parasite_ip; /* service routine start ip */ unsigned long parasite_ip; /* service routine start ip */
user_regs_struct_t regs_orig; /* original registers */
unsigned long syscall_ip; /* entry point of infection */
u8 code_orig[BUILTIN_SYSCALL_SIZE];
unsigned long status;
void * addr_cmd; /* addr for command */ void * addr_cmd; /* addr for command */
void * addr_args; /* address for arguments */ void * addr_args; /* address for arguments */
}; };
extern int can_run_syscall(unsigned long ip, unsigned long start, unsigned long end);
extern int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_area_list,
struct cr_fdset *cr_fdset);
extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset); extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset);
extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset); extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset);
struct parasite_dump_misc; struct parasite_dump_misc;
extern int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_misc *); extern int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_misc *misc);
extern int parasite_dump_pages_seized(struct parasite_ctl *ctl,
extern struct parasite_ctl *parasite_infect_seized(pid_t pid, int pid_dir, struct list_head *vma_area_list); struct list_head *vma_area_list,
extern int parasite_cure_seized(struct parasite_ctl *ctl, struct list_head *vma_area_list); struct cr_fdset *cr_fdset);
extern int parasite_cure_seized(struct parasite_ctl *ctl);
extern struct parasite_ctl *parasite_infect_seized(pid_t pid, int pid_dir,
struct list_head *vma_area_list);
#endif /* PARASITE_SYSCALL_H_ */ #endif /* PARASITE_SYSCALL_H_ */
...@@ -37,6 +37,7 @@ extern int seize_task(pid_t pid); ...@@ -37,6 +37,7 @@ extern int seize_task(pid_t pid);
extern int unseize_task(pid_t pid, enum cr_task_state st); extern int unseize_task(pid_t pid, enum cr_task_state st);
extern int ptrace_peek_area(pid_t pid, void *dst, void *addr, long bytes); extern int ptrace_peek_area(pid_t pid, void *dst, void *addr, long bytes);
extern int ptrace_poke_area(pid_t pid, void *src, void *addr, long bytes); extern int ptrace_poke_area(pid_t pid, void *src, void *addr, long bytes);
extern int ptrace_swap_area(pid_t pid, void *dst, void *src, long bytes);
extern int ptrace_show_area(pid_t pid, void *addr, long bytes); extern int ptrace_show_area(pid_t pid, void *addr, long bytes);
extern int ptrace_show_area_r(pid_t pid, void *addr, long bytes); extern int ptrace_show_area_r(pid_t pid, void *addr, long bytes);
......
This diff is collapsed.
...@@ -175,3 +175,21 @@ err: ...@@ -175,3 +175,21 @@ err:
return -2; return -2;
} }
/* don't swap big space, it might overflow the stack */
int ptrace_swap_area(pid_t pid, void *dst, void *src, long bytes)
{
void *t = alloca(bytes);
if (ptrace_peek_area(pid, t, dst, bytes))
return -1;
if (ptrace_poke_area(pid, src, dst, bytes)) {
if (ptrace_poke_area(pid, t, dst, bytes))
return -2;
return -1;
}
memcpy(src, t, bytes);
return 0;
}
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