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 <xemul@virtuozzo.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
Pavel Emelyanov 2016-11-21 21:26:14 +03:00 committed by Andrei Vagin
parent c0836c2052
commit b0dfd996ed

View file

@ -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)