[PATCHv3,21/30] restorer: refill symtable for rt-vdso

Submitted by Dmitry Safonov on June 28, 2016, 7:24 p.m.

Details

Message ID 20160628192423.14943-22-dsafonov@virtuozzo.com
State Rejected
Series "x86 Compatible C/R, part 2"
Headers show

Commit Message

Dmitry Safonov June 28, 2016, 7:24 p.m.
Otherwise, we still have parsed x86_64 vdso symtable.
After this:
  pie: 17917: vdso: Mapping compatible vDSO at 0x25000
  pie: 17917: vdso: Parsing at 0x25000 0x29000
  pie: 17917: Error (pie/util-vdso-elf32.c:87): vdso: Elf header magic m>
  pie: 17917: ismatch
  pie: 17917: vdso: Parsing at 0x26000 0x29000
  pie: 17917: Error (pie/util-vdso-elf32.c:87): vdso: Elf header magic m>
  pie: 17917: ismatch
  pie: 17917: vdso: Parsing at 0x27000 0x29000
  pie: 17917: vdso: PT_LOAD p_vaddr: 0x0
  pie: 17917: vdso: DT_HASH: 0xb4
  pie: 17917: vdso: DT_STRTAB: 0x1c0
  pie: 17917: vdso: DT_SYMTAB: 0x130
  pie: 17917: vdso: DT_STRSZ: 0x95
  pie: 17917: vdso: DT_SYMENT: 0x10
  pie: 17917: vdso: nbucket 0x3 nchain 0x9 bucket 0x270bc chain 0x270c8

Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
---
 criu/include/parasite-vdso.h |  5 +++--
 criu/pie/parasite-vdso.c     | 30 ++++++++++++++++++++++++++----
 criu/pie/restorer.c          |  3 ++-
 3 files changed, 31 insertions(+), 7 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/parasite-vdso.h b/criu/include/parasite-vdso.h
index 4f25f57d3573..025396319e41 100644
--- a/criu/include/parasite-vdso.h
+++ b/criu/include/parasite-vdso.h
@@ -80,14 +80,15 @@  static inline bool is_vdso_mark(void *addr)
 }
 
 extern int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned long park_size);
-int vdso_map_compat(unsigned long map_at);
+extern int vdso_map_compat(unsigned long map_at, unsigned long park_size,
+		struct vdso_symtable *sym_rt);
 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, bool compat_vdso);
 
 #else /* CONFIG_VDSO */
 #define vdso_do_park(sym_rt, park_at, park_size)		(0)
-#define vdso_map_compat(map_at)					(0)
+#define vdso_map_compat(map_at, park_size, sym_rt)		(0)
 
 #endif /* CONFIG_VDSO */
 
diff --git a/criu/pie/parasite-vdso.c b/criu/pie/parasite-vdso.c
index 9310b0426a3a..f838f826d24c 100644
--- a/criu/pie/parasite-vdso.c
+++ b/criu/pie/parasite-vdso.c
@@ -11,6 +11,7 @@ 
 
 #include "asm/string.h"
 #include "asm/types.h"
+#include "asm/page.h"
 
 #include "syscall.h"
 #include "image.h"
@@ -72,18 +73,37 @@  int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned l
 #ifndef ARCH_MAP_VDSO_32
 # define ARCH_MAP_VDSO_32	0x2002
 #endif
-int vdso_map_compat(unsigned long map_at)
+extern int vdso_fill_symtable_compat(uintptr_t mem, size_t size,
+		struct vdso_symtable *t);
+
+int vdso_map_compat(unsigned long map_at, unsigned long park_size,
+		struct vdso_symtable *sym_rt)
 {
+	unsigned long search_vdso;
 	int ret;
 
 	pr_debug("Mapping compatible vDSO at %lx\n", map_at);
 
 	ret = sys_arch_prctl(ARCH_MAP_VDSO_32, map_at);
+	if (ret)
+		return ret;
+
+	/*
+	 * We could map VVAR firstly, or VDSO.
+	 * Try to find VDSO pages in this couple of parking pages.
+	 */
+	for (search_vdso = map_at; search_vdso < map_at + park_size;
+			search_vdso += PAGE_SIZE)
+	{
+		ret = vdso_fill_symtable_compat(search_vdso,
+			map_at + park_size - search_vdso, sym_rt);
+		if (!ret)
+			return 0;
+	}
+	pr_err("Failed to parse a arch_prctl-mapped vDSO %d\n", ret);
 	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)
 {
@@ -93,7 +113,9 @@  int __vdso_fill_symtable(uintptr_t mem, size_t size,
 		return vdso_fill_symtable(mem, size, t);
 }
 #else
-int vdso_map_compat(unsigned long map_at)
+int vdso_map_compat(unsigned long __always_unused map_at,
+		unsigned long __always_unused park_size,
+		struct vdso_symtable __always_unused *sym_rt)
 {
 	return 0;
 }
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index 96a44c8f56d0..75903910f4f6 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -1139,7 +1139,8 @@  long __export_restore_task(struct task_restore_args *args)
 
 	if (args->compatible_mode) {
 		/* Map compatible vdso */
-		if (vdso_map_compat(args->vdso_rt_parked_at))
+		if (vdso_map_compat(args->vdso_rt_parked_at,
+				vdso_rt_size, &args->vdso_sym_rt))
 			goto core_restore_end;
 	}