From b0dfd996ed5e2e6dca965edbce983b58f4c5cdfb Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Mon, 21 Nov 2016 21:26:14 +0300 Subject: [PATCH] compel: Get syscall injection point in compel The ictx->syscall_ip is the address of any x-able VMA. CRIU knows this as it parses the smaps file (heavily). For others compel just parses /proc/pid/maps file. travis-ci: success for compel: Contrinue improving library Signed-off-by: Pavel Emelyanov Signed-off-by: Andrei Vagin --- compel/src/lib/infect.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c index f924e8683..d699e2006 100644 --- a/compel/src/lib/infect.c +++ b/compel/src/lib/infect.c @@ -924,6 +924,41 @@ err: return NULL; } +/* + * Find first executable VMA that would fit the initial + * syscall injection. + */ +static unsigned long find_executable_area(int pid) +{ + char aux[128]; + FILE *f; + unsigned long ret = (unsigned long)MAP_FAILED; + + sprintf(aux, "/proc/%d/maps", pid); + f = fopen(aux, "r"); + if (!f) + goto out; + + while (fgets(aux, sizeof(aux), f)) { + unsigned long start, end; + char *f; + + start = strtoul(aux, &f, 16); + end = strtoul(f + 1, &f, 16); + + /* f now points at " rwx" (yes, with space) part */ + if (f[3] == 'x') { + BUG_ON(end - start < PARASITE_START_AREA_MIN); + ret = start; + break; + } + } + + fclose(f); +out: + return ret; +} + struct parasite_ctl *compel_prepare(int pid) { struct parasite_ctl *ctl; @@ -935,8 +970,16 @@ struct parasite_ctl *compel_prepare(int pid) ictx = &ctl->ictx; ictx->task_size = compel_task_size(); + ictx->syscall_ip = find_executable_area(pid); + if (ictx->syscall_ip == (unsigned long)MAP_FAILED) + goto err; + out: return ctl; + +err: + free(ctl); + goto out; } static bool task_in_parasite(struct parasite_ctl *ctl, user_regs_struct_t *regs)