From 45fdee04fb57db2ee32cc57c332dbcfe1024924e Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Mon, 17 Dec 2012 22:53:23 +0300 Subject: [PATCH] parasite: Split infecting routine into parts The fist part prepares ctl to controll the seized task. The 2nd one mmaps shareb buffer for data exchange. Signed-off-by: Pavel Emelyanov --- include/parasite-syscall.h | 2 ++ parasite-syscall.c | 57 ++++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h index 4ef6ed926..c578792d8 100644 --- a/include/parasite-syscall.h +++ b/include/parasite-syscall.h @@ -52,6 +52,8 @@ extern int parasite_cure_seized(struct parasite_ctl *ctl, struct pstree_item *it extern struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, struct list_head *vma_area_list); +extern struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct list_head *vma_area_list); +extern int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size); extern struct parasite_tty_args *parasite_dump_tty(struct parasite_ctl *ctl, int fd); diff --git a/parasite-syscall.c b/parasite-syscall.c index 7375afd90..6c1492b02 100644 --- a/parasite-syscall.c +++ b/parasite-syscall.c @@ -776,11 +776,10 @@ int parasite_cure_seized(struct parasite_ctl *ctl, struct pstree_item *item) return ret; } -struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, struct list_head *vma_area_list) +struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct list_head *vma_area_list) { struct parasite_ctl *ctl = NULL; struct vma_area *vma_area; - int ret, fd; /* * Control block early setup. @@ -822,26 +821,31 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, goto err; } - /* - * Inject a parasite engine. Ie allocate memory inside alien - * space and copy engine code there. Then re-map the engine - * locally, so we will get an easy way to access engine memory - * without using ptrace at all. - */ + return ctl; + +err: + xfree(ctl); + return NULL; +} + +int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size) +{ + int fd; + ctl->remote_map = mmap_seized(ctl, NULL, (size_t)parasite_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_SHARED, -1, 0); if (!ctl->remote_map) { - pr_err("Can't allocate memory for parasite blob (pid: %d)\n", pid); - goto err_restore; + pr_err("Can't allocate memory for parasite blob (pid: %d)\n", ctl->pid); + return -1; } ctl->map_length = round_up(parasite_size, PAGE_SIZE); - fd = open_proc_rw(pid, "map_files/%p-%p", + fd = open_proc_rw(ctl->pid, "map_files/%p-%p", ctl->remote_map, ctl->remote_map + ctl->map_length); if (fd < 0) - goto err_restore; + return -1; ctl->local_map = mmap(NULL, parasite_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FILE, fd, 0); @@ -850,9 +854,32 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, if (ctl->local_map == MAP_FAILED) { ctl->local_map = NULL; pr_perror("Can't map remote parasite map"); - goto err_restore; + return -1; } + return 0; +} + +struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, struct list_head *vma_area_list) +{ + int ret; + struct parasite_ctl *ctl; + + ctl = parasite_prep_ctl(pid, vma_area_list); + if (!ctl) + return NULL; + + /* + * Inject a parasite engine. Ie allocate memory inside alien + * space and copy engine code there. Then re-map the engine + * locally, so we will get an easy way to access engine memory + * without using ptrace at all. + */ + + ret = parasite_map_exchange(ctl, parasite_size); + if (ret) + goto err_restore; + pr_info("Putting parasite blob into %p->%p\n", ctl->local_map, ctl->remote_map); memcpy(ctl->local_map, parasite_blob, sizeof(parasite_blob)); @@ -884,10 +911,6 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, err_restore: parasite_cure_seized(ctl, item); return NULL; - -err: - xfree(ctl); - return NULL; } #else /* CONFIG_X86_64 */