[CRIU] [PATCHv3 20/30] pie/restorer: add vdso_fill_symtable_compat for 32-bit vdso

Dmitry Safonov dsafonov at virtuozzo.com
Tue Jun 28 12:24:13 PDT 2016


While restorering compatible application on x86-64, we need
to parse 32-bit vDSO. By that reason I need _three_ compiled
object versions for util-vdso:
- for native parasite it's util-vdso.o
- for compatible parasite it's compat/util-vdso.o
- for restorer it's util-vdso.o and util-vdso-elf32.o

Note, that I can't link compat/util-vdso.o to restorer, as it's
i386 ELF which ld can't link to x86_64 ELF file.

TODO: maybe I'll need to refactor and introduce generic
CONFIG_COMPAT instead of those defined(CONFIG_X86_32).

Fixes:
  pie: 27504: vdso: Mapping compatible vDSO at 0x25000
  pie: 27504: Remap 0x7f3de3efa000->0x8048000 len 0x1000
  ...
  pie: 27504: vdso: Parsing at 0xf7776000 0xf7778000
  pie: 27504: Error (pie/util-vdso.c:87): vdso: Elf header magic mismatch
  pie: 27504: Error (pie/restorer.c:1540): Restorer fail 27504
  (00.029188) Error (cr-restore.c:988): 27504 exited, status=1
  (00.033072) Error (cr-restore.c:1870): Restoring FAILED.

Cc: Cyrill Gorcunov <gorcunov at openvz.org>
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
 criu/include/parasite-vdso.h |  2 +-
 criu/include/util-vdso.h     |  4 ++++
 criu/pie/Makefile.library    |  3 +++
 criu/pie/parasite-vdso.c     | 22 +++++++++++++++++++---
 criu/pie/restorer.c          |  3 ++-
 criu/pie/util-vdso-elf32.c   |  1 +
 6 files changed, 30 insertions(+), 5 deletions(-)
 create mode 120000 criu/pie/util-vdso-elf32.c

diff --git a/criu/include/parasite-vdso.h b/criu/include/parasite-vdso.h
index d50319048264..4f25f57d3573 100644
--- a/criu/include/parasite-vdso.h
+++ b/criu/include/parasite-vdso.h
@@ -83,7 +83,7 @@ extern int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, uns
 int vdso_map_compat(unsigned long map_at);
 extern int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
 			unsigned long vdso_rt_parked_at, size_t index,
-			VmaEntry *vmas, size_t nr_vmas);
+			VmaEntry *vmas, size_t nr_vmas, bool compat_vdso);
 
 #else /* CONFIG_VDSO */
 #define vdso_do_park(sym_rt, park_at, park_size)		(0)
diff --git a/criu/include/util-vdso.h b/criu/include/util-vdso.h
index 43f7549c822e..63bc70d79f3e 100644
--- a/criu/include/util-vdso.h
+++ b/criu/include/util-vdso.h
@@ -88,6 +88,10 @@ static inline unsigned long vvar_vma_size(struct vdso_symtable *t)
 	return t->vvar_end - t->vvar_start;
 }
 
+#if defined(CONFIG_X86_32)
+# define vdso_fill_symtable vdso_fill_symtable_compat
+#endif
+
 extern int vdso_fill_symtable(uintptr_t mem, size_t size, struct vdso_symtable *t);
 
 #endif /* __CR_UTIL_VDSO_H__ */
diff --git a/criu/pie/Makefile.library b/criu/pie/Makefile.library
index ecd862385222..288594a64959 100644
--- a/criu/pie/Makefile.library
+++ b/criu/pie/Makefile.library
@@ -9,6 +9,9 @@ ifeq ($(ARCH),x86)
         target		+= compat
         CFLAGS_native	+= -DCONFIG_X86_64
         CFLAGS_compat	+= -fno-pic -m32 -DCONFIG_X86_32
+
+        native-lib-y	+= util-vdso-elf32.o
+        CFLAGS_util-vdso-elf32.o	+= -DCONFIG_X86_32
 endif
 
 OBJS			+= log-simple.o util-fd.o util.o
diff --git a/criu/pie/parasite-vdso.c b/criu/pie/parasite-vdso.c
index b5d12f1e1ca7..9310b0426a3a 100644
--- a/criu/pie/parasite-vdso.c
+++ b/criu/pie/parasite-vdso.c
@@ -81,16 +81,32 @@ int vdso_map_compat(unsigned long map_at)
 	ret = sys_arch_prctl(ARCH_MAP_VDSO_32, map_at);
 	return ret;
 }
+
+extern int vdso_fill_symtable_compat(uintptr_t mem, size_t size,
+		struct vdso_symtable *t);
+int __vdso_fill_symtable(uintptr_t mem, size_t size,
+		struct vdso_symtable *t, bool compat_vdso)
+{
+	if (compat_vdso)
+		return vdso_fill_symtable_compat(mem, size, t);
+	else
+		return vdso_fill_symtable(mem, size, t);
+}
 #else
 int vdso_map_compat(unsigned long map_at)
 {
 	return 0;
 }
+int __vdso_fill_symtable(uintptr_t mem, size_t size,
+		struct vdso_symtable *t, bool __always_unused compat_vdso)
+{
+	return vdso_fill_symtable(mem, size, t);
+}
 #endif
 
 int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
 		 unsigned long vdso_rt_parked_at, size_t index,
-		 VmaEntry *vmas, size_t nr_vmas)
+		 VmaEntry *vmas, size_t nr_vmas, bool compat_vdso)
 {
 	VmaEntry *vma_vdso = NULL, *vma_vvar = NULL;
 	struct vdso_symtable s = VDSO_SYMTABLE_INIT;
@@ -125,8 +141,8 @@ int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
 	/*
 	 * Find symbols in vDSO zone read from image.
 	 */
-	if (vdso_fill_symtable((uintptr_t)vma_vdso->start,
-				vma_entry_len(vma_vdso), &s))
+	if (__vdso_fill_symtable((uintptr_t)vma_vdso->start,
+			vma_entry_len(vma_vdso), &s, compat_vdso))
 		return -1;
 
 	/*
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index b40bc346e279..96a44c8f56d0 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -1216,7 +1216,8 @@ long __export_restore_task(struct task_restore_args *args)
 		    vma_entry_is(&args->vmas[i], VMA_AREA_VVAR)) {
 			if (vdso_proxify("dumpee", &args->vdso_sym_rt,
 					 args->vdso_rt_parked_at,
-					 i, args->vmas, args->vmas_n))
+					 i, args->vmas, args->vmas_n,
+					 args->compatible_mode))
 				goto core_restore_end;
 			break;
 		}
diff --git a/criu/pie/util-vdso-elf32.c b/criu/pie/util-vdso-elf32.c
new file mode 120000
index 000000000000..97928c05535d
--- /dev/null
+++ b/criu/pie/util-vdso-elf32.c
@@ -0,0 +1 @@
+util-vdso.c
\ No newline at end of file
-- 
2.9.0



More information about the CRIU mailing list