[CRIU] [PATCH 03/11] vdso: Don't drop original VVAR VMA on dump

Dmitry Safonov dsafonov at virtuozzo.com
Mon Jul 17 15:39:54 MSK 2017


I think, it's better if we still restore the original vvar
as some code may expect vma to be there or may dereference
pointer there.
E.g., if we checkpointed task while it was on vdso page,
it'll dereference pointer to vvar. Better keep it in vmas.

So, the original code deleted it becase it was proxy_vvar_marked,
which I think is misnaming problem.
Having two vvar addresses named rt_ and orig_ describes what to
do with them on dump.

Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
 criu/include/parasite.h |  5 +++--
 criu/pie/parasite.c     | 14 +++++++------
 criu/vdso.c             | 56 +++++++++++++++++++++++++------------------------
 3 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/criu/include/parasite.h b/criu/include/parasite.h
index 115891f3b65c..9de0d2e9ac79 100644
--- a/criu/include/parasite.h
+++ b/criu/include/parasite.h
@@ -49,8 +49,9 @@ struct parasite_vma_entry
 struct parasite_vdso_vma_entry {
 	unsigned long	start;
 	unsigned long	len;
-	unsigned long	proxy_vdso_addr;
-	unsigned long	proxy_vvar_addr;
+	unsigned long	orig_vdso_addr;
+	unsigned long	orig_vvar_addr;
+	unsigned long	rt_vvar_addr;
 	int		is_marked;
 	bool		try_fill_symtable;
 	bool		is_vdso;
diff --git a/criu/pie/parasite.c b/criu/pie/parasite.c
index eeae848ebbf4..f3fa2e39af5f 100644
--- a/criu/pie/parasite.c
+++ b/criu/pie/parasite.c
@@ -554,13 +554,15 @@ static int parasite_check_vdso_mark(struct parasite_vdso_vma_entry *args)
 			pr_err("vdso: Mark version mismatch!\n");
 			return -EINVAL;
 		}
-		args->is_marked = 1;
-		args->proxy_vdso_addr = m->orig_vdso_addr;
-		args->proxy_vvar_addr = m->orig_vvar_addr;
+		args->is_marked		= 1;
+		args->orig_vdso_addr	= m->orig_vdso_addr;
+		args->orig_vvar_addr	= m->orig_vvar_addr;
+		args->rt_vvar_addr	= m->rt_vvar_addr;
 	} else {
-		args->is_marked = 0;
-		args->proxy_vdso_addr = VDSO_BAD_ADDR;
-		args->proxy_vvar_addr = VVAR_BAD_ADDR;
+		args->is_marked		= 0;
+		args->orig_vdso_addr	= VDSO_BAD_ADDR;
+		args->orig_vvar_addr	= VVAR_BAD_ADDR;
+		args->rt_vvar_addr	= VVAR_BAD_ADDR;
 
 		if (args->try_fill_symtable) {
 			struct vdso_symtable t;
diff --git a/criu/vdso.c b/criu/vdso.c
index caed5efd8941..ffe97b95e28f 100644
--- a/criu/vdso.c
+++ b/criu/vdso.c
@@ -118,10 +118,11 @@ static bool not_vvar_or_vdso(struct vma_area *vma)
 int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 			struct vm_area_list *vma_area_list)
 {
-	unsigned long proxy_vdso_addr = VDSO_BAD_ADDR;
-	unsigned long proxy_vvar_addr = VVAR_BAD_ADDR;
-	struct vma_area *proxy_vdso_marked = NULL;
-	struct vma_area *proxy_vvar_marked = NULL;
+	unsigned long orig_vdso_addr = VDSO_BAD_ADDR;
+	unsigned long orig_vvar_addr = VVAR_BAD_ADDR;
+	unsigned long rt_vvar_addr = VVAR_BAD_ADDR;
+	struct vma_area *rt_vdso_marked = NULL;
+	struct vma_area *rt_vvar_marked = NULL;
 	struct parasite_vdso_vma_entry *args;
 	int fd = -1, exit_code = -1;
 	enum vdso_check_t vcheck;
@@ -152,10 +153,10 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 		BUILD_BUG_ON(!(VDSO_PROT & VVAR_PROT));
 
 		if ((vma->e->prot & VVAR_PROT) == VVAR_PROT) {
-			if (proxy_vvar_addr != VVAR_BAD_ADDR &&
-			    proxy_vvar_addr == vma->e->start) {
-				BUG_ON(proxy_vvar_marked);
-				proxy_vvar_marked = vma;
+			if (rt_vvar_addr != VVAR_BAD_ADDR &&
+			    rt_vvar_addr == vma->e->start) {
+				BUG_ON(rt_vvar_marked);
+				rt_vvar_marked = vma;
 				continue;
 			}
 		}
@@ -188,13 +189,14 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 		 * area status.
 		 */
 		if (unlikely(args->is_marked)) {
-			if (proxy_vdso_marked) {
+			if (rt_vdso_marked) {
 				pr_err("Ow! Second vdso mark detected!\n");
 				goto err;
 			}
-			proxy_vdso_marked = vma;
-			proxy_vdso_addr = args->proxy_vdso_addr;
-			proxy_vvar_addr = args->proxy_vvar_addr;
+			rt_vdso_marked	= vma;
+			orig_vdso_addr	= args->orig_vdso_addr;
+			orig_vvar_addr	= args->orig_vvar_addr;
+			rt_vvar_addr	= args->rt_vvar_addr;
 			continue;
 		}
 
@@ -225,38 +227,38 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
 	 * There is marked vdso, it means such vdso is autogenerated
 	 * and must be dropped from vma list.
 	 */
-	if (proxy_vdso_marked) {
-		pr_debug("vdso: Found marked at %lx (proxy vDSO at %lx VVAR at %lx)\n",
-			 (long)proxy_vdso_marked->e->start,
-			 (long)proxy_vdso_addr, (long)proxy_vvar_addr);
+	if (rt_vdso_marked) {
+		pr_debug("vdso: Found marked at %lx (orig vDSO at %lx VVAR at %lx)\n",
+			 (long)rt_vdso_marked->e->start,
+			 (long)orig_vdso_addr, (long)orig_vvar_addr);
 
 		/*
 		 * Don't forget to restore the proxy vdso/vvar status, since
 		 * it's unknown to the kernel.
 		 */
 		list_for_each_entry(vma, &vma_area_list->h, list) {
-			if (vma->e->start == proxy_vdso_addr) {
+			if (vma->e->start == orig_vdso_addr) {
 				vma->e->status |= VMA_AREA_REGULAR | VMA_AREA_VDSO;
-				pr_debug("vdso: Restore proxy vDSO status at %lx\n",
+				pr_debug("vdso: Restore orig vDSO status at %lx\n",
 					 (long)vma->e->start);
-			} else if (vma->e->start == proxy_vvar_addr) {
+			} else if (vma->e->start == orig_vvar_addr) {
 				vma->e->status |= VMA_AREA_REGULAR | VMA_AREA_VVAR;
-				pr_debug("vdso: Restore proxy VVAR status at %lx\n",
+				pr_debug("vdso: Restore orig VVAR status at %lx\n",
 					 (long)vma->e->start);
 			}
 		}
 
 		pr_debug("vdso: Droppping marked vdso at %lx\n",
-			 (long)proxy_vdso_marked->e->start);
-		list_del(&proxy_vdso_marked->list);
-		xfree(proxy_vdso_marked);
+			 (long)rt_vdso_marked->e->start);
+		list_del(&rt_vdso_marked->list);
+		xfree(rt_vdso_marked);
 		vma_area_list->nr--;
 
-		if (proxy_vvar_marked) {
+		if (rt_vvar_marked) {
 			pr_debug("vdso: Droppping marked vvar at %lx\n",
-				 (long)proxy_vvar_marked->e->start);
-			list_del(&proxy_vvar_marked->list);
-			xfree(proxy_vvar_marked);
+				 (long)rt_vvar_marked->e->start);
+			list_del(&rt_vvar_marked->list);
+			xfree(rt_vvar_marked);
 			vma_area_list->nr--;
 		}
 	}
-- 
2.13.1



More information about the CRIU mailing list