Commit f52ea57d authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

pie/restorer: add vdso_fill_symtable_compat for 32-bit vdso

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@openvz.org>
Signed-off-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 2457ce6f
...@@ -83,7 +83,7 @@ extern int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, uns ...@@ -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); int vdso_map_compat(unsigned long map_at);
extern int vdso_proxify(char *who, 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, 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 */ #else /* CONFIG_VDSO */
#define vdso_do_park(sym_rt, park_at, park_size) (0) #define vdso_do_park(sym_rt, park_at, park_size) (0)
......
...@@ -88,6 +88,10 @@ static inline unsigned long vvar_vma_size(struct vdso_symtable *t) ...@@ -88,6 +88,10 @@ static inline unsigned long vvar_vma_size(struct vdso_symtable *t)
return t->vvar_end - t->vvar_start; 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); extern int vdso_fill_symtable(uintptr_t mem, size_t size, struct vdso_symtable *t);
#endif /* __CR_UTIL_VDSO_H__ */ #endif /* __CR_UTIL_VDSO_H__ */
...@@ -9,6 +9,9 @@ ifeq ($(ARCH),x86) ...@@ -9,6 +9,9 @@ ifeq ($(ARCH),x86)
target += compat target += compat
CFLAGS_native += -DCONFIG_X86_64 CFLAGS_native += -DCONFIG_X86_64
CFLAGS_compat += -fno-pic -m32 -DCONFIG_X86_32 CFLAGS_compat += -fno-pic -m32 -DCONFIG_X86_32
native-lib-y += util-vdso-elf32.o
CFLAGS_util-vdso-elf32.o += -DCONFIG_X86_32
endif endif
OBJS += log-simple.o util-fd.o util.o string.o OBJS += log-simple.o util-fd.o util.o string.o
......
...@@ -81,16 +81,32 @@ int vdso_map_compat(unsigned long map_at) ...@@ -81,16 +81,32 @@ int vdso_map_compat(unsigned long map_at)
ret = sys_arch_prctl(ARCH_MAP_VDSO_32, map_at); ret = sys_arch_prctl(ARCH_MAP_VDSO_32, map_at);
return 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)
{
if (compat_vdso)
return vdso_fill_symtable_compat(mem, size, t);
else
return vdso_fill_symtable(mem, size, t);
}
#else #else
int vdso_map_compat(unsigned long map_at) int vdso_map_compat(unsigned long map_at)
{ {
return 0; 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 #endif
int vdso_proxify(char *who, struct vdso_symtable *sym_rt, int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
unsigned long vdso_rt_parked_at, size_t index, 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; VmaEntry *vma_vdso = NULL, *vma_vvar = NULL;
struct vdso_symtable s = VDSO_SYMTABLE_INIT; struct vdso_symtable s = VDSO_SYMTABLE_INIT;
...@@ -125,8 +141,8 @@ int vdso_proxify(char *who, struct vdso_symtable *sym_rt, ...@@ -125,8 +141,8 @@ int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
/* /*
* Find symbols in vDSO zone read from image. * Find symbols in vDSO zone read from image.
*/ */
if (vdso_fill_symtable((uintptr_t)vma_vdso->start, if (__vdso_fill_symtable((uintptr_t)vma_vdso->start,
vma_entry_len(vma_vdso), &s)) vma_entry_len(vma_vdso), &s, compat_vdso))
return -1; return -1;
/* /*
......
...@@ -1169,7 +1169,8 @@ long __export_restore_task(struct task_restore_args *args) ...@@ -1169,7 +1169,8 @@ long __export_restore_task(struct task_restore_args *args)
vma_entry_is(&args->vmas[i], VMA_AREA_VVAR)) { vma_entry_is(&args->vmas[i], VMA_AREA_VVAR)) {
if (vdso_proxify("dumpee", &args->vdso_sym_rt, if (vdso_proxify("dumpee", &args->vdso_sym_rt,
args->vdso_rt_parked_at, args->vdso_rt_parked_at,
i, args->vmas, args->vmas_n)) i, args->vmas, args->vmas_n,
args->compatible_mode))
goto core_restore_end; goto core_restore_end;
break; break;
} }
......
util-vdso.c
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment