[CRIU] [PATCH 2/8] compel: Get syscall injection point in compel

Cyrill Gorcunov gorcunov at openvz.org
Mon Nov 21 10:26:14 PST 2016


From: Pavel Emelyanov <xemul at virtuozzo.com>

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.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 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 aee125d28f2f..98f1c80ca8bf 100644
--- a/compel/src/lib/infect.c
+++ b/compel/src/lib/infect.c
@@ -926,6 +926,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;
@@ -937,8 +972,16 @@ struct parasite_ctl *compel_prepare(int pid)
 
 	ictx = &ctl->ictx;
 	ictx->task_size = 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)
-- 
2.7.4



More information about the CRIU mailing list