[CRIU] [PATCH 2/2] parasite: Pass @MEMFD_FNAME as predefined memfd name

Cyrill Gorcunov gorcunov at openvz.org
Fri Sep 25 15:01:48 PDT 2015


We put name of the MFD file right after the syscall
binary blob. For this sake, when we lookup for suitable
IP to run seized syscall we pass @MEMFD_FNAME_SZ as
an argument.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 parasite-syscall.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/parasite-syscall.c b/parasite-syscall.c
index eb2bfe0d4153..fa696ebd1876 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -39,6 +39,9 @@
 #include "asm/restorer.h"
 #include "pie/pie-relocs.h"
 
+#define MEMFD_FNAME	"CRIUMFD"
+#define MEMFD_FNAME_SZ	sizeof(MEMFD_FNAME)
+
 static int can_run_syscall(unsigned long ip, unsigned long start,
 			   unsigned long end, unsigned long pad)
 {
@@ -1103,7 +1106,9 @@ struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_
 		return ctl;
 
 	/* Search a place for injecting syscall */
-	vma_area = get_vma_by_ip(&vma_area_list->h, REG_IP(ctl->orig.regs), 0);
+	vma_area = get_vma_by_ip(&vma_area_list->h,
+				 REG_IP(ctl->orig.regs),
+				 MEMFD_FNAME_SZ);
 	if (!vma_area) {
 		pr_err("No suitable VMA found to run parasite "
 		       "bootstrap code (pid: %d)\n", pid);
@@ -1155,11 +1160,27 @@ static int parasite_mmap_exchange(struct parasite_ctl *ctl, unsigned long size)
 static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size,
 		struct proc_pid_stat *pps)
 {
+	void *where = (void *)ctl->syscall_ip + BUILTIN_SYSCALL_SIZE;
+	u8 orig_code[MEMFD_FNAME_SZ] = MEMFD_FNAME;
+	pid_t pid = ctl->pid.real;
 	unsigned long sret;
 	int ret, fd, lfd;
 
+	BUILD_BUG_ON(sizeof(orig_code) < sizeof(long));
+
+	if (ptrace_swap_area(pid, where, (void *)orig_code, sizeof(orig_code))) {
+		pr_err("Can't inject memfd args (pid: %d)\n", pid);
+		return -1;
+	}
+
 	ret = syscall_seized(ctl, __NR_memfd_create, &sret,
-			pps->arg_start, 0, 0, 0, 0, 0);
+			     (unsigned long)where, 0, 0, 0, 0, 0);
+
+	if (ptrace_poke_area(pid, orig_code, where, sizeof(orig_code))) {
+		pr_err("Can't restore memfd args (pid: %d)\n", pid);
+		return -1;
+	}
+
 	if (ret < 0)
 		return ret;
 
-- 
2.4.3



More information about the CRIU mailing list